Memory graph for AI agents that learns what to retrieve — and what to suppress.
Project description
OpenClawBrain
Your retrieval routes become the prompt — assembled by learned routing, not top-k similarity.
Repo version: v12.2.6 (see pyproject.toml; PyPI may lag)
Website: https://openclawbrain.ai
Setup: Setup Guide
Docs
- Operator guide: docs/operator-guide.md
- OpenClaw integration: docs/openclaw-integration.md
- Setup guide: docs/setup-guide.md
- GitHub repo: https://github.com/jonathangu/openclawbrain
- ClawHub skill: https://clawhub.ai/skills/openclawbrain
OpenClaw Integration (start here if you run OpenClaw)
OpenClawBrain is designed to be the memory layer for OpenClaw agents.
- Canonical operator runbook: docs/operator-guide.md
- Guide: docs/openclaw-integration.md
Quickstart (OpenClaw users):
pip install openclawbrain
openclawbrain init --workspace ~/.openclaw/workspace --output ~/.openclawbrain/main
openclawbrain serve --state ~/.openclawbrain/main/state.json
Production Deployment (socket):
Use LaunchAgent/systemd to keep the socket server running:
openclawbrain serve --state ~/.openclawbrain/main/state.json
macOS (~/Library/LaunchAgents/com.openclawbrain.daemon.plist):
<key>ProgramArguments</key>
<array>
<string>/usr/bin/env</string>
<string>openclawbrain</string>
<string>serve</string>
<string>--state</string>
<string>/Users/YOU/.openclawbrain/main/state.json</string>
</array>
Linux (/etc/systemd/system/openclawbrain-daemon.service):
[Service]
ExecStart=/usr/bin/env openclawbrain serve --state /home/YOUR_USER/.openclawbrain/main/state.json
python3 -m openclawbrain.socket_client --socket ~/.openclawbrain/main/daemon.sock --method health --params "{}"
OpenClawBrain learns from your agent feedback, so wrong answers get suppressed instead of resurfacing. It builds a memory graph over your workspace, remembers what worked, and routes future answers through learned paths.
-
Pure Python 3.10+ core (no vector DB). The package currently installs the OpenAI SDK by default; hash-embedder mode runs offline.
-
Built-in hash embeddings for offline/testing; OpenAI embeddings are recommended for production.
-
Builds a
state.jsonbrain from your workspace. -
Queries follow learned routes instead of only similarity matches.
-
Positive feedback (
+1) uses the default policy-gradient learnerapply_outcome_pg()(conserving probability mass across traversed nodes), while negative (-1) creates inhibitory edges. -
Over time, less noise appears and recurring mistakes are less likely.
-
OpenClawBrain integrates with your agent's file-based workspace through incremental sync, constitutional anchors, and optional/scheduled compaction.
-
See the context lifecycle for details.
Install
pip install openclawbrain
See also: Setup Guide for a complete local configuration walkthrough.
Why OpenClawBrain
- Static retrieval vs learned routing: OpenClawBrain continuously updates node-to-node edges so good routes strengthen and bad routes decay.
- No correction propagation vs inhibitory edges: incorrect context can be actively suppressed and forgotten less often than in similarity-only systems.
- Bulk context load vs targeted traversal: context windows stay focused (roughly 52KB → 3-13KB in typical sessions) by following likely retrieval routes.
- No structural maintenance vs prune/merge/compact: OpenClawBrain includes scheduled maintenance commands to keep the graph healthy and compact.
- No protection vs constitutional anchors: anchor critical nodes with authority so operational instructions do not drift.
5-minute quickstart (A→B learning story)
# 1. Build a brain from the sample workspace
openclawbrain init --workspace examples/sample_workspace --output /tmp/brain
Large texts are automatically rechunked to stay under embedding model limits (12K chars). No content is skipped or truncated.
# 2. Check state health
openclawbrain doctor --state /tmp/brain/state.json
# output
# PASS: python_version
# PASS: state_file_exists
# PASS: state_json_valid
# Summary: 8/9 checks passed
# 3. Query (text output includes node IDs)
openclawbrain query "how do I deploy" --state /tmp/brain/state.json --top 3 --json
# output (abbrev.)
# {"fired": ["deploy.md::0", "deploy.md::1", "deploy.md::2"], ...}
# 4. Teach it (good path)
openclawbrain learn --state /tmp/brain/state.json --outcome 1.0 --fired-ids "deploy.md::0,deploy.md::1"
# output
# {"edges_updated": 2, "max_weight_delta": 0.155}
#
# `learn` defaults to `apply_outcome_pg()` for full-policy updates.
# `apply_outcome()` remains available for simpler sparse updates.
# 5. Inject a correction
openclawbrain inject --state /tmp/brain/state.json \
--id "fix::1" --content "Never skip CI for hotfixes" --type CORRECTION
# 5b. Add new knowledge (no correction needed, just a new fact)
openclawbrain inject --state /tmp/brain/state.json \
--id "teaching::monitoring-tip" \
--content "Check Grafana dashboards before every deploy" \
--type TEACHING
# 6. Query again and see the route change
openclawbrain query "can I skip CI" --state /tmp/brain/state.json --top 3
# output
# fix::1
# ~~~~~~
# Never skip CI for hotfixes
# ...
# 7. Re-check health for a quick signal
openclawbrain health --state /tmp/brain/state.json
Correcting mistakes (the main workflow)
When your agent retrieves wrong context, teach OpenClawBrain in one command:
openclawbrain inject --state brain/state.json \
--id "correction::42" \
--content "Never show API keys in chat messages" \
--type CORRECTION
What happens:
- OpenClawBrain creates a new node with your correction text
- It connects that node to the most related workspace chunks
- It adds inhibitory edges — negative-weight links that suppress those chunks
- Next query touching that topic: the correction appears, the bad route is dampened
To add knowledge without suppressing anything, use --type TEACHING instead.
Structural corrections with split
Alongside inhibitory edges and periodic merge, maintenance now supports runtime splitting:
openclawbrain maintainrunsscaleafterdecay, thensplitbeforemerge.suggest_splits()finds bloated multi-topic nodes (including merged-byline nodes).split_node()rewires outgoing and incoming edges into focused child nodes, then removes the parent.- Inhibitory edges are always copied to every child, so suppressions are not lost.
openclawbrain maintainnow also includes optional homeostatic controls: decay half-life auto-adjusts to keep reflex-edge ratio in range, and synaptic scaling uses a soft per-node weight budget (5.0) with fourth-root scaling.Tier hysteresis: habitual band 0.15-0.6prevents threshold thrashing.
Self-learning (autonomous agent learning)
Agents can learn from their own observations — both mistakes and successes — without human feedback (self-correct available as CLI/API alias).
# Agent detected a failure — penalize the bad path and inject a correction
openclawbrain self-learn --state brain/state.json \
--content 'Always download model artifacts before terminating training instances' \
--fired-ids 'infra.md::3,cleanup.md::1' \
--outcome -1.0 --type CORRECTION
# Agent succeeded — reinforce the good path and record what worked
openclawbrain self-learn --state brain/state.json \
--content 'Download-then-terminate sequence works reliably for model training' \
--fired-ids 'infra.md::3,download.md::1' \
--outcome 1.0 --type TEACHING
# Agent learned something new (neutral — just adding knowledge)
openclawbrain self-learn --state brain/state.json \
--content 'GBM training takes ~40 min on g5.xlarge' \
--outcome 0 --type TEACHING
The full spectrum:
| Situation | outcome | type | Effect |
|---|---|---|---|
| Agent made a mistake | -1.0 | CORRECTION | Penalize fired path + inject with inhibitory edges |
| Agent learned a fact | 0.0 | TEACHING | Inject knowledge only, no weight changes |
| Agent succeeded | +1.0 | TEACHING | Reinforce fired path + inject positive knowledge |
Via socket (Python):
from openclawbrain.socket_client import OCBClient
with OCBClient('~/.openclawbrain/main/daemon.sock') as client:
# Agent detected its own mistake
client.self_learn(
content='Always download artifacts before terminating instances',
fired_ids=['infra.md::3', 'cleanup.md::1'],
outcome=-1.0,
node_type='CORRECTION',
)
# Agent observed a success — reinforce
client.self_learn(
content='Chunked download with checksum verification works reliably',
fired_ids=['download.md::0', 'validate.md::1'],
outcome=1.0,
node_type='TEACHING',
)
This enables autonomous learning loops: agents observe outcomes, detect failures and successes, and teach themselves — no human in the loop. self-correct is available as CLI/API alias.
Adding new knowledge (no rebuild needed)
When you learn something that isn't in any workspace file, inject it directly:
openclawbrain inject --state brain/state.json \
--id "teaching::codex-spark" \
--content "Use Codex CLI with gpt-5.3-codex-spark for coding tasks — free on Pro plan" \
--type TEACHING
TEACHING nodes connect to related workspace chunks just like CORRECTION nodes, but without inhibitory edges — they add knowledge instead of suppressing it.
Three injection types:
- CORRECTION — creates inhibitory edges that suppress related wrong paths
- TEACHING — adds knowledge with normal positive connections
- DIRECTIVE — same as TEACHING (use for standing instructions)
For agent frameworks that need to correlate corrections with earlier queries,
see examples/correction_flow/ for the fired-node logging pattern.
You can also reinforce good retrievals:
# After a query returns helpful context, strengthen those paths
openclawbrain learn --state brain/state.json --outcome 1.0 \
--fired-ids "deploy.md::0,deploy.md::1"
Or weaken bad ones:
openclawbrain learn --state brain/state.json --outcome -1.0 \
--fired-ids "monitoring.md::2"
What it looks like in practice
# Before learning
openclawbrain query "how do we handle incidents" --state /tmp/brain/state.json --top 3
# After one good learn on the best route
openclawbrain learn --state /tmp/brain/state.json --outcome 1.0 --fired-ids "incidents.md::0,deploy.md::1"
# After one negative learn on a bad route
openclawbrain learn --state /tmp/brain/state.json --outcome -1.0 --fired-ids "monitoring.md::2,incidents.md::0"
# Query again to observe new routing
openclawbrain query "incident runbook for deploy failures" --state /tmp/brain/state.json --top 4
How it compares
| Plain RAG | OpenClawBrain | |
|---|---|---|
| Retrieval | Similarity search | Learned graph traversal |
| Feedback | None | learn +1/-1 updates edge weights |
| Wrong answers | Can keep resurfacing | Inhibitory edges suppress them |
| Adding knowledge | Re-index/re-embed | inject --type TEACHING (no rebuild) |
| Over time | Same results for same query | Routes become habitual behavior |
| Dependencies | Vector DB or service | Zero dependencies |
How OpenClawBrain differs from related tools
| OpenClawBrain | Plain RAG | Reflexion | MemGPT | |
|---|---|---|---|---|
| What it learns | Retrieval routes | Nothing | Reasoning via self-reflection text | Memory read/write policies |
| Negative feedback | Inhibitory edges suppress bad paths | None | None (additive only) | None |
| New knowledge | inject node (no rebuild) |
Re-embed corpus | Add to reflection prompt | Update tier config |
| Integration | Standalone library, any agent | Vector DB required | Tied to agent loop | Tied to agent architecture |
| Cold start | Hash embeddings, no API key | Needs embedding service | Needs prior episodes | Needs configured tiers |
| State | Single state.json file |
External DB | Prompt history | Multi-tier storage |
Real embeddings + LLM routing (OpenAI)
Production deployments use:
- Embeddings:
text-embedding-3-small(1536-dim) - LLM routing/scoring:
gpt-5-mini - Offline/testing fallback:
hashembeddings (lower quality, no API key required).
from openai import OpenAI
from openclawbrain import split_workspace, VectorIndex
client = OpenAI()
def embed(text):
return client.embeddings.create(
model="text-embedding-3-small", input=[text]
).data[0].embedding
def llm(system, user):
return client.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "system", "content": system}, {"role": "user", "content": user}],
).choices[0].message.content
graph, texts = split_workspace("./workspace", llm_fn=llm)
index = VectorIndex()
for nid, content in texts.items():
index.upsert(nid, embed(content))
See examples/openai_embedder/ for a complete example.
CLI Reference
| Command | Description |
|---|---|
init |
Build a brain from workspace files |
query |
Traverse graph and return context |
learn |
Apply outcome feedback to fired edges |
self-learn |
Add outcome-aware lesson entries from agent observations |
self-correct |
Alias for self-learn |
merge |
Suggest and apply node merges |
anchor |
Set/list/remove constitutional authority on nodes |
connect |
Connect learning nodes to workspace neighborhoods |
maintain |
Run structural maintenance (health, decay, scale, split, merge, prune, connect) |
compact |
Compact old daily notes into graph nodes |
sync |
Incremental re-embed after file changes |
inject |
Add CORRECTION/TEACHING/DIRECTIVE nodes |
replay |
Replay session queries (defaults to full-learning; use --edges-only for cheap replay, --fast-learning/--extract-learning-events for LLM mining only, or --full-learning/--full-pipeline for the full pass) |
harvest |
Apply slow-learning pass from learning_events.jsonl to current graph |
async-route-pg |
Background teacher-shadow routing labels from recent query journal + PG edge updates |
health |
Show graph health metrics |
status |
openclawbrain status --state brain/state.json [--json] returns a one-command health overview: version, nodes, edges, tier distribution, daemon status, embedder, decay half-life |
serve |
openclawbrain serve --state brain/state.json [--socket-path path] [--foreground] starts the Unix socket service in the foreground |
journal |
Show event journal |
doctor |
Run diagnostic checks |
info |
Show brain info (nodes, edges, embedder) |
daemon |
Start persistent worker (JSON-RPC over stdio, state loaded once) |
State persistence
State writes are atomic (temp + fsync + rename) with .bak backup. Crash-safe.
Persistent Worker (openclawbrain daemon)
For production use, run OpenClawBrain as a long-lived daemon so the graph stays hot in memory and query paths avoid repeated startup+reload overhead.
Why this matters:
- First load initializes
state.jsononce, then keeps the process and index warm. - Saves about 100-800ms per call versus shelling out per query (production measure: ~504ms per warm query path on Mac Mini M4 Pro).
- Reduces memory churn and tail latency under steady traffic.
Start it with:
openclawbrain daemon --state ~/.openclawbrain/main/state.json
Protocol:
- Transport:
stdin/stdoutwith newline-delimited JSON (NDJSON). - Each request is a single JSON object with
id,method, andparams. - Each response is a single JSON object with the same
idand eitherresultorerror.
Example request/response:
echo '{"id":"req-1","method":"query","params":{"query":"how to deploy","top_k":4,"chat_id":"telegram:123"}}' | openclawbrain daemon --state ~/.openclawbrain/main/state.json
Enable deterministic query-conditioned habitual routing (no LLM calls on query path):
echo '{"id":"req-2","method":"query","params":{"query":"how to deploy","top_k":4,"route_mode":"edge+sim","route_top_k":5,"route_alpha_sim":0.5,"route_use_relevance":true}}' | openclawbrain daemon --state ~/.openclawbrain/main/state.json
{"id":"req-1","result":{"fired_nodes":["a"],"context":"...","seeds":[["a",0.96]],"embed_query_ms":1.1,"traverse_ms":2.4,"total_ms":3.5}}
Supported methods (all 10):
query: run route traversal and returnfired_nodes,context, timing, and seeds.learn: apply outcomes (+1/-1) with defaultapply_outcome_pg()updates and returnedges_updated.inject: add TEACHING/CORRECTION/DIRECTIVE nodes and connect them to related workspace chunks.correction: atomically apply negative feedback to last-fired nodes and inject a CORRECTION node.maintain: run maintenance ops and return health/merge summary fields.health: return current health metrics for the loaded graph.info: return state metadata and object counts.save: persist current in-memory state to disk immediately.reload: reloadstate.jsonwithout restarting.shutdown: persist pending writes and exit cleanly.query/learn/maintain/health/inforesponses includeembed_query_ms,traverse_ms, andtotal_mstiming fields where applicable.query/learn/inject/correctionare the only mutation-capable methods; the daemon is the single source of truth for those changes while state is hot in memory.
Current limitations:
- Per-chat mutation APIs remain scoped through request payloads (
chat_id) and adapter-layer bookkeeping. - Concurrent writers are serialized by the socket transport lock and one active request at a time.
Production timing (Mac Mini M4 Pro, OpenAI embeddings):
- MAIN (1,158 nodes): 397ms embed + 107ms traverse = 504ms total
- PELICAN (582 nodes): 634ms embed + 51ms traverse = 685ms total
- BOUNTIFUL (285 nodes): 404ms embed + 27ms traverse = 431ms total
See examples/ops/client_example.py for a Python client and docs/architecture.md for protocol details.
True Policy Gradient (apply_outcome_pg)
apply_outcome_pg implements a full REINFORCE policy-gradient update and is now the default learning rule used by daemon/CLI correction and learn paths.
- It updates all outgoing edges for each visited node on the fired trajectory, not only traversed edges.
- It uses the update:
Δw = (η(z-b)γ^ℓ)/τ · (𝟙[j=a] - π(j|i))where:η= learning ratez= outcome rewardb= baselineγ= discountℓ= trajectory depthτ= temperatureπ(j|i)= action probability from softmax (including STOP)𝟙[j=a]= 1 for the taken action, else 0
- Conservation property: for each source node
i, outgoing updates sum to zero, so total outgoing mass is preserved. - Use
apply_outcome_pgwhen you want smoother, probability-based updates across alternatives; useapply_outcomefor a simpler sparse update that only touches traversed edges.
from openclawbrain import apply_outcome_pg, LearningConfig
config = LearningConfig(learning_rate=0.1, temperature=1.0, baseline=0.0)
updates = apply_outcome_pg(graph, fired_nodes=["a", "b", "c"], outcome=1.0, config=config)
Full derivation: https://jonathangu.com/openclawbrain/gu2016/
Write policy summary
| Situation | Action |
|---|---|
| Durable fact | Edit file → sync re-embeds |
| Correction | Edit file + daemon correction method |
| Soft teaching | openclawbrain inject --type TEACHING |
| Wrong retrieval | daemon correction (graph-only, no rebuild) |
| New rule | Edit AGENTS.md or SOUL.md |
Production stats (current)
- MAIN: 1,160 nodes, 2,551 edges, 43 learnings
- PELICAN: 555 nodes, 2,211 edges, 181 learnings
- BOUNTIFUL: 289 nodes, 1,101 edges, 35 learnings
- CORMORANT: 1,672 nodes, ~7,100 edges, 22 learnings (first external user!)
Traversal defaults
| Setting | Default | Purpose |
|---|---|---|
beam_width |
8 |
Frontier size per hop (wider = reaches farther routes) |
max_hops |
30 |
Safety ceiling; damping controls convergence |
fire_threshold |
0.01 |
Minimum score required to fire a candidate node |
reflex_threshold |
0.6 |
Edges with weight >= 0.6 auto-follow (no route function) |
habitual_range |
0.15 - 0.6 |
Edges in this band run through route function |
inhibitory_threshold |
-0.01 |
Edges at or below suppress targets |
max_fired_nodes |
None |
Hard stop on fired node count |
max_context_chars |
None |
Hard stop on rendered traversal context |
edge_damping |
0.3 |
Per-reuse decay (weight × 0.3^k) |
from openclawbrain import traverse, TraversalConfig
result = traverse(
graph,
seeds,
config=TraversalConfig(max_context_chars=20000, max_fired_nodes=30),
)
query and query_brain.py honor these budgets and stop as soon as any termination condition is met.
External benchmarks
External retrieval benchmarks are optional and use separately downloaded datasets.
OpenClawBrain ships a quick-start workflow for MultiHop-RAG and HotPotQA in
benchmarks/external/README.md, but the datasets are not in the repository.
Quick run (from project root):
mkdir -p benchmarks/external
curl -L https://huggingface.co/datasets/yixuantt/MultiHopRAG/raw/main/MultiHopRAG.json -o benchmarks/external/multihop_rag.json
curl -L https://curtis.ml.cmu.edu/datasets/hotpot/hotpot_dev_distractor_v1.json -o benchmarks/external/hotpotqa_dev_distractor.json
python3 benchmarks/external/run_multihop_rag.py --limit 50
python3 benchmarks/external/run_hotpotqa.py --limit 50
Python API
from openclawbrain import (
split_workspace,
traverse,
apply_outcome_pg,
apply_outcome,
inject_node,
inject_correction,
inject_batch,
VectorIndex,
HashEmbedder,
TraversalConfig,
save_state,
load_state,
ManagedState,
measure_health,
suggest_splits,
split_node,
replay_queries,
score_retrieval,
)
State lifecycle
- Where it lives: a single
state.jsonfile (portable, version-controllable) - How big: ~180KB for 20 nodes (hash), ~60MB for 1,600 nodes (OpenAI embeddings)
- When to rebuild: after major workspace restructuring or embedder changes
- Embedder changes: OpenClawBrain stores the embedder name + dimension in state metadata and hard-fails on mismatch — no silent corruption
- Maintenance: use
openclawbrain maintain(decay+scale+split+merge+prune+connect) to rebalance structure as the graph evolves
Core thesis (recommended reading)
- Shadow routing + Ultimate Policy Gradient:
docs/core-thesis-ultimate-policy-gradient.md
Cost control
- Recommended: OpenAI
text-embedding-3-small(~$0.02/MB) +gpt-5-minifor optional offline teacher routing/scoring. Embeddings are generated at init and cached instate.json; normal query serving stays LLM-free. - Auto-detection:
openclawbrain inittries OpenAI by default (--embedder auto --llm auto). IfOPENAI_API_KEYis set, you get production-quality embeddings automatically. If not, it falls back to hash embeddings with no API calls. - Batch init:
openclawbrain initembeds all workspace files in one batch call. Subsequent queries reuse cached vectors. - Explicit control: use
--embedder openai/--embedder hashto force a specific embedder. Use--llm noneto skip LLM-assisted splitting.
Warm start from sessions
If you have prior conversation logs, replay them. By default, replay runs the
full learning pipeline (LLM transcript mining + edge replay + harvest):
openclawbrain replay --state /tmp/brain/state.json --sessions ./sessions/
OpenClaw media uploads are usually logged as user text stubs like
[media attached: ...]. Those stubs alone have little semantic value, so they
often do not improve memory quality by themselves. The useful text typically
arrives in later toolResult messages (OCR, image captions, audio transcript).
Recommended approach:
- Use dedicated media tools to emit transcript/OCR/caption text as
toolResult. - Let OpenClawBrain attach allowlisted
toolResulttext to media-stub user queries during replay and expose the same text to fast-learning windows.
Replay controls for this behavior:
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--include-tool-results \
--tool-result-allowlist image,openai-whisper,openai-whisper-api,openai-whisper-local,summarize \
--tool-result-max-chars 20000
--include-tool-results/--no-include-tool-results(default enabled)--tool-result-allowlist(comma-separated tool names)--tool-result-max-chars(max allowlisted tool text appended per user query)
This is equivalent to passing --full-learning (alias: --full-pipeline) explicitly. Decay is enabled
during replay by default and the harvest pass runs
(decay,scale,split,merge,prune,connect), so unrelated edges weaken while
active paths are reinforced.
For cheap edge-only replay (no LLM, no harvest):
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--edges-only
For transcript-backed fast-learning only (no harvest):
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--fast-learning \
--resume \
--workers 4 \
--checkpoint /tmp/brain/replay_checkpoint.json
--extract-learning-events is an alias for --fast-learning.
For cutover-friendly startup (inject quickly, then start daemon immediately):
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--fast-learning \
--stop-after-fast-learning \
--checkpoint /tmp/brain/replay_checkpoint.json
--workers controls fast-learning LLM extraction concurrency (this stage is often the slowest, because it is LLM-bound).
For durable long replays with periodic progress/checkpoint/state persistence:
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--edges-only \
--resume \
--checkpoint /tmp/brain/replay_checkpoint.json \
--checkpoint-every-seconds 60 \
--checkpoint-every 1 \
--persist-state-every-seconds 30 \
--progress-every 250
By default, replay also emits progress heartbeats every 30 seconds; use --quiet to suppress banners/progress.
When --json is set, progress is emitted as JSONL events:
{"type":"progress","phase":"replay",...}.
For simple true-parallel replay v0:
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--edges-only \
--replay-workers 4 \
--checkpoint-every 1
--replay-workers controls edge replay workers. Values greater than 1 trade strict sequential replay behavior for a deterministic shard/merge approximation.
Parallel replay v0 is an approximation: workers process deterministic shards and compute replay deltas without mutating shared state; the reducer applies those deltas in deterministic merge order, with checkpoints after each merge batch.
To enable decay during an edges-only replay:
openclawbrain replay \
--state /tmp/brain/state.json \
--sessions ./sessions/ \
--edges-only \
--decay-during-replay \
--decay-interval 10
--decay-interval N controls how many learning steps occur between each decay
pass (default 10).
Missing or rotated session files are skipped with a warning instead of aborting the run, so long rebuilds survive file rotation.
The fast-learning and harvest pipeline is sidecar-only to the core files:
learning_events.jsonl is append-only, and replay updates state.json via the same graph mutation model as existing injection commands.
Async teacher routing (offline)
query and daemon query stay LLM-free and fast. async-route-pg is a separate background loop that samples recent journaled queries, replays local traversal, asks a teacher model which candidate edges it would choose, then applies dense policy-gradient updates with apply_outcome_pg.
Dry-run is the default (no writes), machine-readable JSON:
openclawbrain async-route-pg \
--state /tmp/brain/state.json \
--since-hours 24 \
--max-queries 200 \
--sample-rate 0.1 \
--teacher openai \
--teacher-model gpt-5-mini \
--json
Apply mode (writes updates):
openclawbrain async-route-pg \
--state /tmp/brain/state.json \
--since-hours 24 \
--max-queries 200 \
--sample-rate 0.1 \
--teacher openai \
--teacher-model gpt-5-mini \
--apply \
--json
Notes:
- Default is dry-run (no state write); add
--applyto persist updates. - If
OPENAI_API_KEYis missing (or--teacher none), it still runs but reports teacher unavailable and applies no updates. - The updates improve edge weights/metadata that downstream
maintain(split/merge/prune/connect) already consumes.
Production experience
Three brains run in production on a Mac Mini M4 Pro:
| Brain | Nodes | Edges | Learning Corrections | Sessions Replayed |
|---|---|---|---|---|
| MAIN | 1,142 | 2,814 | 43 | 215 |
| PELICAN | 512 | 1,984 | 181 | 183 |
| BOUNTIFUL | 273 | 1,073 | 35 | 300 |
Design Tenets
- No network calls in core.
- No secret discovery (no dotfiles, no keychain lookup).
- Embedder identity stored in state metadata; hard-fail on dimension mismatch.
- One canonical state format (
state.json). - Traversal defaults are budget-first for safety:
beam_width=8,max_hops=30,fire_threshold=0.01.
Paper + links
jonathangu.com/openclawbrain — 8 deterministic simulations + production deployment data.
- PyPI:
pip install openclawbrain - GitHub: jonathangu/openclawbrain
- ClawHub skill: https://clawhub.ai/skills/openclawbrain
- ClawHub CLI:
clawhub install openclawbrain - Benchmarks:
python3 benchmarks/run_benchmark.py(deterministic per commit; timings vary by machine)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openclawbrain-12.2.6.tar.gz.
File metadata
- Download URL: openclawbrain-12.2.6.tar.gz
- Upload date:
- Size: 313.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a99ea483775de430556ecd079444db3e1b8b211a814896a9cf939d801c47b13e
|
|
| MD5 |
4d11cc54f22083abd5def2d78ef16a9b
|
|
| BLAKE2b-256 |
56499771fd7dbb748cef0c03c9a0fdc7aa5b14c13d6cdd5256e50225835f2731
|
Provenance
The following attestation bundles were made for openclawbrain-12.2.6.tar.gz:
Publisher:
publish.yml on jonathangu/openclawbrain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openclawbrain-12.2.6.tar.gz -
Subject digest:
a99ea483775de430556ecd079444db3e1b8b211a814896a9cf939d801c47b13e - Sigstore transparency entry: 1008031298
- Sigstore integration time:
-
Permalink:
jonathangu/openclawbrain@2c0a37d54ad9797fe463f87697a68387fbe79a3f -
Branch / Tag:
refs/tags/v12.2.6 - Owner: https://github.com/jonathangu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c0a37d54ad9797fe463f87697a68387fbe79a3f -
Trigger Event:
push
-
Statement type:
File details
Details for the file openclawbrain-12.2.6-py3-none-any.whl.
File metadata
- Download URL: openclawbrain-12.2.6-py3-none-any.whl
- Upload date:
- Size: 152.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
796c1fe40b08e8cf2943f87ec0a4159fcd2722e56bc8f27371c6c1d44e4a136a
|
|
| MD5 |
35e6cd2be0c2be225291960ffba62556
|
|
| BLAKE2b-256 |
2d7798caa405caccd2c85fc77a9f1f267ff4bc64b1ade2bfa0d24b48241ba51a
|
Provenance
The following attestation bundles were made for openclawbrain-12.2.6-py3-none-any.whl:
Publisher:
publish.yml on jonathangu/openclawbrain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openclawbrain-12.2.6-py3-none-any.whl -
Subject digest:
796c1fe40b08e8cf2943f87ec0a4159fcd2722e56bc8f27371c6c1d44e4a136a - Sigstore transparency entry: 1008031302
- Sigstore integration time:
-
Permalink:
jonathangu/openclawbrain@2c0a37d54ad9797fe463f87697a68387fbe79a3f -
Branch / Tag:
refs/tags/v12.2.6 - Owner: https://github.com/jonathangu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2c0a37d54ad9797fe463f87697a68387fbe79a3f -
Trigger Event:
push
-
Statement type: