@simbimbo/memory-ocmemog 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/LICENSE +21 -0
- package/README.md +223 -0
- package/brain/__init__.py +1 -0
- package/brain/runtime/__init__.py +13 -0
- package/brain/runtime/config.py +21 -0
- package/brain/runtime/inference.py +83 -0
- package/brain/runtime/instrumentation.py +17 -0
- package/brain/runtime/memory/__init__.py +13 -0
- package/brain/runtime/memory/api.py +152 -0
- package/brain/runtime/memory/artifacts.py +33 -0
- package/brain/runtime/memory/candidate.py +89 -0
- package/brain/runtime/memory/context_builder.py +87 -0
- package/brain/runtime/memory/conversation_state.py +1825 -0
- package/brain/runtime/memory/distill.py +198 -0
- package/brain/runtime/memory/embedding_engine.py +94 -0
- package/brain/runtime/memory/freshness.py +91 -0
- package/brain/runtime/memory/health.py +42 -0
- package/brain/runtime/memory/integrity.py +170 -0
- package/brain/runtime/memory/interaction_memory.py +57 -0
- package/brain/runtime/memory/memory_consolidation.py +60 -0
- package/brain/runtime/memory/memory_gate.py +38 -0
- package/brain/runtime/memory/memory_graph.py +54 -0
- package/brain/runtime/memory/memory_links.py +109 -0
- package/brain/runtime/memory/memory_salience.py +235 -0
- package/brain/runtime/memory/memory_synthesis.py +33 -0
- package/brain/runtime/memory/memory_taxonomy.py +35 -0
- package/brain/runtime/memory/person_identity.py +83 -0
- package/brain/runtime/memory/person_memory.py +138 -0
- package/brain/runtime/memory/pondering_engine.py +577 -0
- package/brain/runtime/memory/promote.py +237 -0
- package/brain/runtime/memory/provenance.py +356 -0
- package/brain/runtime/memory/reinforcement.py +73 -0
- package/brain/runtime/memory/retrieval.py +153 -0
- package/brain/runtime/memory/semantic_search.py +66 -0
- package/brain/runtime/memory/sentiment_memory.py +67 -0
- package/brain/runtime/memory/store.py +400 -0
- package/brain/runtime/memory/tool_catalog.py +68 -0
- package/brain/runtime/memory/unresolved_state.py +93 -0
- package/brain/runtime/memory/vector_index.py +270 -0
- package/brain/runtime/model_roles.py +11 -0
- package/brain/runtime/model_router.py +22 -0
- package/brain/runtime/providers.py +59 -0
- package/brain/runtime/security/__init__.py +3 -0
- package/brain/runtime/security/redaction.py +14 -0
- package/brain/runtime/state_store.py +25 -0
- package/brain/runtime/storage_paths.py +41 -0
- package/docs/architecture/memory.md +118 -0
- package/docs/release-checklist.md +34 -0
- package/docs/reports/ocmemog-code-audit-2026-03-14.md +155 -0
- package/docs/usage.md +223 -0
- package/index.ts +726 -0
- package/ocmemog/__init__.py +1 -0
- package/ocmemog/sidecar/__init__.py +1 -0
- package/ocmemog/sidecar/app.py +1068 -0
- package/ocmemog/sidecar/compat.py +74 -0
- package/ocmemog/sidecar/transcript_watcher.py +425 -0
- package/openclaw.plugin.json +18 -0
- package/package.json +60 -0
- package/scripts/install-ocmemog.sh +277 -0
- package/scripts/launchagents/com.openclaw.ocmemog.guard.plist +22 -0
- package/scripts/launchagents/com.openclaw.ocmemog.ponder.plist +22 -0
- package/scripts/launchagents/com.openclaw.ocmemog.sidecar.plist +27 -0
- package/scripts/ocmemog-context.sh +15 -0
- package/scripts/ocmemog-continuity-benchmark.py +178 -0
- package/scripts/ocmemog-demo.py +122 -0
- package/scripts/ocmemog-failover-test.sh +17 -0
- package/scripts/ocmemog-guard.sh +11 -0
- package/scripts/ocmemog-install.sh +93 -0
- package/scripts/ocmemog-load-test.py +106 -0
- package/scripts/ocmemog-ponder.sh +30 -0
- package/scripts/ocmemog-recall-test.py +58 -0
- package/scripts/ocmemog-reindex-vectors.py +14 -0
- package/scripts/ocmemog-reliability-soak.py +177 -0
- package/scripts/ocmemog-sidecar.sh +46 -0
- package/scripts/ocmemog-soak-report.py +58 -0
- package/scripts/ocmemog-soak-test.py +44 -0
- package/scripts/ocmemog-test-rig.py +345 -0
- package/scripts/ocmemog-transcript-append.py +45 -0
- package/scripts/ocmemog-transcript-watcher.py +8 -0
- package/scripts/ocmemog-transcript-watcher.sh +7 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# ocmemog Memory Architecture
|
|
2
|
+
|
|
3
|
+
## What this repo actually ships
|
|
4
|
+
|
|
5
|
+
ocmemog vendors a subset of brAIn's memory package and wraps it with a small FastAPI sidecar. The authoritative local implementation lives in:
|
|
6
|
+
|
|
7
|
+
- `brain/runtime/memory/store.py` for the main SQLite schema
|
|
8
|
+
- `brain/runtime/memory/retrieval.py` for keyword-first retrieval
|
|
9
|
+
- `brain/runtime/memory/vector_index.py` for embeddings and fallback semantic lookup
|
|
10
|
+
- `ocmemog/sidecar/app.py` for the plugin-facing HTTP API
|
|
11
|
+
|
|
12
|
+
Unlike brAIn, this repo does not ship the full cognition/runtime stack. Several modules under `brain/runtime/*` are compatibility shims so the copied memory package can import cleanly.
|
|
13
|
+
|
|
14
|
+
## Storage layout
|
|
15
|
+
|
|
16
|
+
By default, ocmemog stores state under `.ocmemog-state/` at the repo root unless `OCMEMOG_STATE_DIR` or `BRAIN_STATE_DIR` overrides it.
|
|
17
|
+
|
|
18
|
+
Primary files:
|
|
19
|
+
|
|
20
|
+
- `.ocmemog-state/memory/brain_memory.sqlite3`
|
|
21
|
+
- `.ocmemog-state/reports/brain_memory.log.jsonl`
|
|
22
|
+
- `.ocmemog-state/data/person_memory.db`
|
|
23
|
+
- `.ocmemog-state/data/interaction_memory.db`
|
|
24
|
+
- `.ocmemog-state/data/sentiment_memory.db`
|
|
25
|
+
- `.ocmemog-state/data/unresolved_state.db`
|
|
26
|
+
- `.ocmemog-state/data/memory_graph.db`
|
|
27
|
+
|
|
28
|
+
The main SQLite database owns these tables:
|
|
29
|
+
|
|
30
|
+
- Core memory: `knowledge`, `reflections`, `directives`, `tasks`
|
|
31
|
+
- Promotion pipeline: `experiences`, `candidates`, `promotions`
|
|
32
|
+
- Derived indexes: `memory_index`, `vector_embeddings`
|
|
33
|
+
- Supporting records: `memory_events`, `environment_cognition`, `artifacts`, `runbooks`, `lessons`
|
|
34
|
+
|
|
35
|
+
## Retrieval flow
|
|
36
|
+
|
|
37
|
+
The current sidecar behavior is simpler than brAIn's full memory architecture:
|
|
38
|
+
|
|
39
|
+
1. `/memory/search` calls `retrieval.retrieve_for_queries()`.
|
|
40
|
+
2. Retrieval scans `knowledge`, `reflections`, `directives`, and `tasks` for substring matches.
|
|
41
|
+
3. Result scoring combines:
|
|
42
|
+
- keyword hit: `1.0` on substring match
|
|
43
|
+
- reinforcement bonus: `reward_score * 0.5`
|
|
44
|
+
- confidence bonus: `promotion confidence * 0.3`
|
|
45
|
+
4. If `knowledge` has no keyword hit, retrieval falls back to `vector_index.search_memory()`.
|
|
46
|
+
5. The sidecar flattens the bucketed results into a plugin-friendly response.
|
|
47
|
+
|
|
48
|
+
Operational limits:
|
|
49
|
+
|
|
50
|
+
- Semantic fallback now rehydrates any embedded bucket (`knowledge`, `runbooks`, `lessons`) when there are no keyword hits.
|
|
51
|
+
- Default embeddings are local hash vectors (`BRAIN_EMBED_MODEL_LOCAL=simple`), which are deterministic but weak.
|
|
52
|
+
- `runbooks`, `lessons`, `directives`, `reflections`, and `tasks` are now included in the default searchable categories and embedding index.
|
|
53
|
+
|
|
54
|
+
## Write paths
|
|
55
|
+
|
|
56
|
+
The main repo-local write paths are:
|
|
57
|
+
|
|
58
|
+
- `reinforcement.log_experience()` writes to `experiences`
|
|
59
|
+
- `candidate.create_candidate()` writes to `candidates` and `memory_events`
|
|
60
|
+
- `promote.promote_candidate()` writes to `promotions` plus one of `knowledge`, `runbooks`, or `lessons`
|
|
61
|
+
- `vector_index.insert_memory()` writes to `memory_index` and `vector_embeddings`
|
|
62
|
+
- `memory_links.add_memory_link()` writes link metadata inside the main memory DB
|
|
63
|
+
- `person_memory`, `interaction_memory`, `sentiment_memory`, `unresolved_state`, and `memory_graph` each write to separate SQLite files under `.ocmemog-state/data`
|
|
64
|
+
|
|
65
|
+
## Distillation and promotion
|
|
66
|
+
|
|
67
|
+
The brAIn docs describe a richer distill/promote pipeline. In ocmemog today:
|
|
68
|
+
|
|
69
|
+
- Distillation exists in `brain/runtime/memory/distill.py`
|
|
70
|
+
- Model-backed distillation is not available because `brain/runtime/inference.py` is still a shim
|
|
71
|
+
- The practical fallback is a first-line heuristic summary plus generated verification prompts
|
|
72
|
+
- Promotion is available locally and writes promoted summaries into `knowledge`, `runbooks`, or `lessons`
|
|
73
|
+
- Successful promotion also logs a reinforcement event and attempts vector indexing
|
|
74
|
+
|
|
75
|
+
This means the pipeline is present in code, but only part of it is production-ready.
|
|
76
|
+
|
|
77
|
+
## Integrity and health
|
|
78
|
+
|
|
79
|
+
Available support paths:
|
|
80
|
+
|
|
81
|
+
- `integrity.run_integrity_check()` checks for missing tables, orphan candidates, duplicate promotions, missing memory references, and index mismatches
|
|
82
|
+
- `health.get_memory_health()` reports counts and a coarse integrity summary
|
|
83
|
+
- `brain_memory.log.jsonl` captures retrieval, embedding, integrity, and promotion events
|
|
84
|
+
|
|
85
|
+
Known caveat:
|
|
86
|
+
|
|
87
|
+
- health/integrity currently treat `memory_index` as the "vector" coverage source, even though actual embeddings live in `vector_embeddings`
|
|
88
|
+
|
|
89
|
+
## Sidecar contract
|
|
90
|
+
|
|
91
|
+
The sidecar exposes:
|
|
92
|
+
|
|
93
|
+
- `GET /healthz`
|
|
94
|
+
- `POST /memory/search`
|
|
95
|
+
- `POST /memory/get`
|
|
96
|
+
- `POST /memory/ingest`
|
|
97
|
+
- `POST /memory/distill`
|
|
98
|
+
|
|
99
|
+
The sidecar also reports runtime readiness through `mode`, `missingDeps`, `todo`, and `warnings`. That status is important because several copied brAIn modules are shimmed and should be treated as degraded.
|
|
100
|
+
|
|
101
|
+
## Runtime adapters
|
|
102
|
+
|
|
103
|
+
ocmemog ships lightweight runtime adapters for inference + embeddings. They require environment configuration:
|
|
104
|
+
|
|
105
|
+
- `brain/runtime/inference.py` → OpenAI chat completions (requires `OCMEMOG_OPENAI_API_KEY`)
|
|
106
|
+
- `brain/runtime/providers.py` → OpenAI embeddings (requires `BRAIN_EMBED_MODEL_PROVIDER=openai` + API key)
|
|
107
|
+
- `brain/runtime/model_roles.py` + `model_router.py` → role-to-model and provider routing
|
|
108
|
+
|
|
109
|
+
Effect on behavior:
|
|
110
|
+
|
|
111
|
+
- Distillation uses OpenAI when API key is set, otherwise falls back to heuristics
|
|
112
|
+
- Embeddings use OpenAI when configured, otherwise fall back to local hash or sentence-transformers
|
|
113
|
+
- Role-aware context selection is still partially stubbed because `brain.runtime.roles` is not present
|
|
114
|
+
|
|
115
|
+
## TODO: Missing runtime dependencies
|
|
116
|
+
|
|
117
|
+
- TODO: add a repo-local `brain.runtime.roles` implementation or remove role-priority logic from `context_builder`
|
|
118
|
+
- TODO: decide whether to add additional provider backends beyond OpenAI
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Release Checklist
|
|
2
|
+
|
|
3
|
+
Use this checklist before publishing an ocmemog release.
|
|
4
|
+
|
|
5
|
+
## Versioning
|
|
6
|
+
- [ ] Update `package.json` version
|
|
7
|
+
- [ ] Ensure release tag matches package version
|
|
8
|
+
- [ ] Update `CHANGELOG.md`
|
|
9
|
+
- [ ] Confirm README examples reference the current version where applicable
|
|
10
|
+
|
|
11
|
+
## Validation
|
|
12
|
+
- [ ] `bash -n scripts/install-ocmemog.sh`
|
|
13
|
+
- [ ] `bash -n scripts/ocmemog-install.sh`
|
|
14
|
+
- [ ] `./scripts/install-ocmemog.sh --help`
|
|
15
|
+
- [ ] `./scripts/install-ocmemog.sh --dry-run`
|
|
16
|
+
- [ ] `python -m unittest tests.test_regressions`
|
|
17
|
+
- [ ] `npm pack --dry-run`
|
|
18
|
+
|
|
19
|
+
## Install flow
|
|
20
|
+
- [ ] Verify default installer path still works: `./scripts/install-ocmemog.sh`
|
|
21
|
+
- [ ] Verify optional prereq install path is documented correctly
|
|
22
|
+
- [ ] Verify LaunchAgent load path still matches repo scripts
|
|
23
|
+
- [ ] Verify sidecar health check passes after install
|
|
24
|
+
|
|
25
|
+
## Public artifacts
|
|
26
|
+
- [ ] Push `main`
|
|
27
|
+
- [ ] Create/update GitHub release notes
|
|
28
|
+
- [ ] Publish/update ClawHub wrapper skill if installer/docs changed
|
|
29
|
+
- [ ] Publish npm package if auth is available
|
|
30
|
+
|
|
31
|
+
## Post-release sanity
|
|
32
|
+
- [ ] Confirm repo default branch contains the release commits
|
|
33
|
+
- [ ] Confirm GitHub release URL works
|
|
34
|
+
- [ ] Confirm package/install instructions are still accurate
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# ocmemog deep audit (2026-03-14)
|
|
2
|
+
|
|
3
|
+
**Scope:** full plugin repo, sidecar, memory runtime, scripts. Goal: public‑facing quality with minimal surprises.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1) TypeScript plugin layer
|
|
8
|
+
|
|
9
|
+
### `openclaw.plugin.json`
|
|
10
|
+
- ✅ `id: memory-ocmemog`, `kind: memory`.
|
|
11
|
+
- ✅ Config schema includes `endpoint`, `timeoutMs`.
|
|
12
|
+
- **Callout risk:** none.
|
|
13
|
+
|
|
14
|
+
### `index.ts`
|
|
15
|
+
- ✅ Uses OpenClaw plugin scaffold; forwards memory tools to sidecar.
|
|
16
|
+
- **Callout risk:** if sidecar is down, tool calls should return clear error (verify by manual test).
|
|
17
|
+
|
|
18
|
+
### `package.json`
|
|
19
|
+
- ✅ Public package metadata, MIT license, `files` list, `publishConfig.access=public`.
|
|
20
|
+
- ✅ `openclaw.extensions` points to `index.ts` (JITI loads TS at runtime).
|
|
21
|
+
- **Callout risk:** repository URL must exist when publishing.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 2) Sidecar API (FastAPI)
|
|
26
|
+
|
|
27
|
+
### `ocmemog/sidecar/app.py`
|
|
28
|
+
|
|
29
|
+
**Endpoints:**
|
|
30
|
+
- `/memory/search`, `/memory/get`, `/memory/ingest`, `/memory/distill`, `/memory/context`, `/memory/ponder`, `/metrics`, `/events`, `/dashboard`, `/healthz`.
|
|
31
|
+
|
|
32
|
+
**Security / robustness:**
|
|
33
|
+
- ✅ Added optional auth: `OCMEMOG_API_TOKEN` (header `x-ocmemog-token` or `Authorization: Bearer`).
|
|
34
|
+
- ✅ Transcript context retrieval now **allow‑listed** by `OCMEMOG_TRANSCRIPT_ROOTS`.
|
|
35
|
+
- ✅ Transcript snippet reading **streams** only needed lines.
|
|
36
|
+
- ✅ Loopback bind still default in sidecar launcher.
|
|
37
|
+
|
|
38
|
+
**Potential callouts:**
|
|
39
|
+
- If user binds to `0.0.0.0` without token, sidecar is exposed.
|
|
40
|
+
- `/events` is an open SSE stream; if exposed, may leak memory logs.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3) Compatibility / runtime shims
|
|
45
|
+
|
|
46
|
+
### `ocmemog/sidecar/compat.py`
|
|
47
|
+
- ✅ Detects missing deps; reports warnings instead of crashing.
|
|
48
|
+
- **Callout risk:** warnings are expected in “degraded” mode.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 4) Memory store & schema
|
|
53
|
+
|
|
54
|
+
### `brain/runtime/memory/store.py`
|
|
55
|
+
- ✅ SQLite schema created on demand.
|
|
56
|
+
- ✅ Added `demotions` and `cold_storage` tables (archive demoted memories).
|
|
57
|
+
|
|
58
|
+
**Callout risk:**
|
|
59
|
+
- Cold storage grows unbounded (acceptable for “disk cheap” stance).
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 5) Memory pipelines
|
|
64
|
+
|
|
65
|
+
### `brain/runtime/memory/retrieval.py`
|
|
66
|
+
- ✅ Simple keyword match + semantic fallback.
|
|
67
|
+
- **Callout risk:** keyword matching is naive; might be criticized for low recall. (Mitigate by embeddings + vector index.)
|
|
68
|
+
|
|
69
|
+
### `brain/runtime/memory/vector_index.py`
|
|
70
|
+
- ✅ Embedding index stored in SQLite; semantic search loads all embeddings in memory.
|
|
71
|
+
- **Callout risk:** O(N) scan can be slow at scale. Acceptable for local use; note in docs.
|
|
72
|
+
|
|
73
|
+
### `brain/runtime/memory/distill.py`
|
|
74
|
+
- ✅ Uses Ollama inference if configured; heuristic fallback.
|
|
75
|
+
- **Callout risk:** distill quality depends on local model; acceptable for “best effort”.
|
|
76
|
+
|
|
77
|
+
### `brain/runtime/memory/promote.py`
|
|
78
|
+
- ✅ Promotion threshold configurable (`OCMEMOG_PROMOTION_THRESHOLD`).
|
|
79
|
+
- ✅ Demotion archives into `cold_storage` and removes from hot tables.
|
|
80
|
+
- **Callout risk:** Demotion is destructive to hot table (archived safe).
|
|
81
|
+
|
|
82
|
+
### `brain/runtime/memory/context_builder.py`
|
|
83
|
+
- ✅ Uses retrieval for context blocks.
|
|
84
|
+
- **Callout risk:** role registry missing in this repo (already noted in compat warnings).
|
|
85
|
+
|
|
86
|
+
### `brain/runtime/memory/pondering_engine.py`
|
|
87
|
+
- ✅ Pondering now exposed via API and writes summaries into `reflections`.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 6) Embeddings & inference
|
|
92
|
+
|
|
93
|
+
### `brain/runtime/embedding_engine.py`
|
|
94
|
+
- ✅ Local embeddings supported (simple/hash or sentence-transformers).
|
|
95
|
+
- ✅ Provider embeddings via OpenAI or Ollama.
|
|
96
|
+
- **Callout risk:** if `BRAIN_EMBED_MODEL_LOCAL` is set, it overrides provider embeddings.
|
|
97
|
+
|
|
98
|
+
### `brain/runtime/providers.py`
|
|
99
|
+
- ✅ OpenAI and Ollama embedding calls.
|
|
100
|
+
- ✅ Added structured error logging to `brain_memory.log.jsonl`.
|
|
101
|
+
|
|
102
|
+
### `brain/runtime/inference.py`
|
|
103
|
+
- ✅ Ollama inference supported; OpenAI fallback.
|
|
104
|
+
- ✅ Added structured error logging.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 7) Sidecar scripts
|
|
109
|
+
|
|
110
|
+
### `scripts/ocmemog-sidecar.sh`
|
|
111
|
+
- ✅ Defaults to Ollama (phi3 + nomic‑embed‑text).
|
|
112
|
+
- ✅ Configurable thresholds + token.
|
|
113
|
+
|
|
114
|
+
### `scripts/ocmemog-test-rig.py`
|
|
115
|
+
- ✅ Stress rig: ingest, distill, promote, demote, ponder, research.
|
|
116
|
+
- ✅ Supports shadow promotion mode (avoid rejecting useful data).
|
|
117
|
+
|
|
118
|
+
### `scripts/ocmemog-demo.py`
|
|
119
|
+
- ✅ Presentation‑friendly demo with `--pretty`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 8) Known TODOs / warnings
|
|
124
|
+
- Sidecar reports missing role registry for role‑based prioritization.
|
|
125
|
+
- Optional dependency: `sentence-transformers` (only if you want local non‑Ollama embeddings).
|
|
126
|
+
- Vector index is naive (O(N)).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 9) Dependencies
|
|
131
|
+
|
|
132
|
+
**Python**
|
|
133
|
+
- `fastapi`
|
|
134
|
+
- `uvicorn[standard]`
|
|
135
|
+
|
|
136
|
+
**System**
|
|
137
|
+
- `ollama`
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 10) Recommendations before public launch
|
|
142
|
+
|
|
143
|
+
1) **Add a short SECURITY note** to README:
|
|
144
|
+
- sidecar is local by default
|
|
145
|
+
- if bound to 0.0.0.0, require `OCMEMOG_API_TOKEN`
|
|
146
|
+
|
|
147
|
+
2) **Add scale warning** for vector search (O(N))
|
|
148
|
+
|
|
149
|
+
3) **Tag release** `v0.1.0` and publish npm package.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 11) Summary
|
|
154
|
+
|
|
155
|
+
The codebase is publish‑ready after the security hardening and doc updates above. Remaining risks are acceptable given local‑first design. No critical missing dependencies or crashes detected.
|
package/docs/usage.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# ocmemog Memory Usage
|
|
2
|
+
|
|
3
|
+
## Current operating model
|
|
4
|
+
|
|
5
|
+
ocmemog is a repo-local OpenClaw memory sidecar backed by SQLite. It is not a full brAIn runtime clone. The safe assumption is:
|
|
6
|
+
|
|
7
|
+
- search/get over local memory are supported
|
|
8
|
+
- heuristic embeddings are supported by default
|
|
9
|
+
- several advanced brAIn memory flows are copied in but still degraded by missing runtime dependencies
|
|
10
|
+
|
|
11
|
+
## Running the sidecar
|
|
12
|
+
|
|
13
|
+
Use the provided launcher:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
scripts/ocmemog-sidecar.sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Transcript watcher (auto-ingest)
|
|
20
|
+
|
|
21
|
+
Manual watcher:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# defaults to ~/.openclaw/workspace/memory/transcripts if not set
|
|
25
|
+
export OCMEMOG_TRANSCRIPT_DIR="$HOME/.openclaw/workspace/memory/transcripts"
|
|
26
|
+
export OCMEMOG_INGEST_ENDPOINT="http://127.0.0.1:17890/memory/ingest"
|
|
27
|
+
./scripts/ocmemog-transcript-watcher.sh
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Auto-start inside sidecar:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
export OCMEMOG_TRANSCRIPT_WATCHER=true
|
|
34
|
+
./scripts/ocmemog-sidecar.sh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Useful environment variables:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export OCMEMOG_HOST=127.0.0.1
|
|
41
|
+
export OCMEMOG_PORT=17890
|
|
42
|
+
export OCMEMOG_STATE_DIR=/path/to/state
|
|
43
|
+
export OCMEMOG_DB_PATH=/path/to/brain_memory.sqlite3
|
|
44
|
+
export OCMEMOG_MEMORY_MODEL=gpt-4o-mini
|
|
45
|
+
export OCMEMOG_OPENAI_API_KEY=sk-...
|
|
46
|
+
export OCMEMOG_OPENAI_API_BASE=https://api.openai.com/v1
|
|
47
|
+
export OCMEMOG_OPENAI_EMBED_MODEL=text-embedding-3-small
|
|
48
|
+
export BRAIN_EMBED_MODEL_LOCAL=simple
|
|
49
|
+
export BRAIN_EMBED_MODEL_PROVIDER=openai
|
|
50
|
+
export OCMEMOG_TRANSCRIPT_DIR=$HOME/.openclaw/workspace/memory/transcripts
|
|
51
|
+
export OCMEMOG_TRANSCRIPT_GLOB=*.log
|
|
52
|
+
export OCMEMOG_TRANSCRIPT_POLL_SECONDS=1
|
|
53
|
+
export OCMEMOG_INGEST_KIND=memory
|
|
54
|
+
export OCMEMOG_INGEST_SOURCE=transcript
|
|
55
|
+
export OCMEMOG_TRANSCRIPT_WATCHER=true
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Default state location in this repo is `.ocmemog-state/`.
|
|
59
|
+
|
|
60
|
+
## Plugin API
|
|
61
|
+
|
|
62
|
+
Health:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
curl http://127.0.0.1:17890/healthz
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Realtime metrics + events:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
curl http://127.0.0.1:17890/metrics
|
|
72
|
+
curl http://127.0.0.1:17890/events
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Dashboard:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
open http://127.0.0.1:17890/dashboard
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Search:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl -s http://127.0.0.1:17890/memory/search \
|
|
85
|
+
-H 'content-type: application/json' \
|
|
86
|
+
-d '{"query":"deploy risk","limit":5,"categories":["knowledge","tasks"]}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If `OCMEMOG_API_TOKEN` is set, include the header:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
-H 'x-ocmemog-token: YOUR_TOKEN'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Get by reference:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
curl -s http://127.0.0.1:17890/memory/get \
|
|
99
|
+
-H 'content-type: application/json' \
|
|
100
|
+
-d '{"reference":"knowledge:12"}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Fetch linked context (transcript snippet):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
curl -s http://127.0.0.1:17890/memory/context \
|
|
107
|
+
-H 'content-type: application/json' \
|
|
108
|
+
-d '{"reference":"knowledge:12","radius":10}'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Helper script:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
./scripts/ocmemog-context.sh knowledge:12 10
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Run pondering (writes summaries into reflections):
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
curl -s http://127.0.0.1:17890/memory/ponder \
|
|
121
|
+
-H 'content-type: application/json' \
|
|
122
|
+
-d '{"max_items":5}'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Fetch latest ponder recommendations:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
curl -s http://127.0.0.1:17890/memory/ponder/latest?limit=5
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Ingest content:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
curl -s http://127.0.0.1:17890/memory/ingest \
|
|
135
|
+
-H 'content-type: application/json' \
|
|
136
|
+
-d '{"content":"remember this","kind":"memory","memory_type":"knowledge"}'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Ingest with context anchors (links to chat/transcript):
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
curl -s http://127.0.0.1:17890/memory/ingest \
|
|
143
|
+
-H 'content-type: application/json' \
|
|
144
|
+
-d '{
|
|
145
|
+
"content":"remember this",
|
|
146
|
+
"kind":"memory",
|
|
147
|
+
"memory_type":"knowledge",
|
|
148
|
+
"session_id":"session-123",
|
|
149
|
+
"thread_id":"thread-abc",
|
|
150
|
+
"message_id":"msg-987",
|
|
151
|
+
"transcript_path":"/path/to/transcript.log",
|
|
152
|
+
"transcript_offset":420,
|
|
153
|
+
"timestamp":"2026-02-22 16:04:52"
|
|
154
|
+
}'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Distill recent experiences:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
curl -s http://127.0.0.1:17890/memory/distill \
|
|
161
|
+
-H 'content-type: application/json' \
|
|
162
|
+
-d '{"limit":10}'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Notes:
|
|
166
|
+
|
|
167
|
+
- Valid sidecar categories today are `knowledge`, `reflections`, `directives`, `tasks`, `runbooks`, and `lessons`.
|
|
168
|
+
- `/memory/get` currently expects a `table:id` reference.
|
|
169
|
+
- Runtime degradation is reported in every sidecar response.
|
|
170
|
+
|
|
171
|
+
## What is safe to rely on
|
|
172
|
+
|
|
173
|
+
- `store.init_db()` creates the local schema automatically
|
|
174
|
+
- `retrieval.retrieve_for_queries()` is the main sidecar search path
|
|
175
|
+
- `vector_index.search_memory()` provides a semantic fallback over `knowledge`, `runbooks`, `lessons`, `directives`, `reflections`, and `tasks` when keyword retrieval misses
|
|
176
|
+
- `probe_runtime()` exposes missing shim replacements and optional embedding warnings
|
|
177
|
+
|
|
178
|
+
## What is not safe to rely on yet
|
|
179
|
+
|
|
180
|
+
- `brain/runtime/memory/api.py`
|
|
181
|
+
- It targets missing/legacy tables and columns.
|
|
182
|
+
- Provider-backed embeddings
|
|
183
|
+
- Available when `BRAIN_EMBED_MODEL_PROVIDER=openai` and `OCMEMOG_OPENAI_API_KEY` is set.
|
|
184
|
+
- Falls back to local embeddings when missing.
|
|
185
|
+
- Model-backed distillation
|
|
186
|
+
- Available when `OCMEMOG_OPENAI_API_KEY` is set; otherwise falls back to heuristic distill.
|
|
187
|
+
- Role-prioritized context building
|
|
188
|
+
- `brain.runtime.roles.role_registry` is not bundled here.
|
|
189
|
+
- Full brAIn memory parity
|
|
190
|
+
- The repo ships only a subset of the original runtime architecture.
|
|
191
|
+
|
|
192
|
+
## Suggested local workflows
|
|
193
|
+
|
|
194
|
+
To inspect memory state quickly:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
python3 - <<'PY'
|
|
198
|
+
from brain.runtime.memory import store
|
|
199
|
+
store.init_db()
|
|
200
|
+
conn = store.connect()
|
|
201
|
+
for table in ("knowledge", "reflections", "directives", "tasks", "candidates", "promotions"):
|
|
202
|
+
count = conn.execute(f"SELECT COUNT(*) FROM {table}").fetchone()[0]
|
|
203
|
+
print(table, count)
|
|
204
|
+
conn.close()
|
|
205
|
+
PY
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
To rebuild embeddings for recent knowledge rows:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
python3 - <<'PY'
|
|
212
|
+
from brain.runtime.memory import vector_index
|
|
213
|
+
print(vector_index.index_memory())
|
|
214
|
+
PY
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## TODO: Missing runtime dependencies
|
|
218
|
+
|
|
219
|
+
- TODO: wire a real inference backend before enabling distill/promote as an operator-facing workflow
|
|
220
|
+
- TODO: wire real provider execution if `BRAIN_EMBED_MODEL_PROVIDER` is meant to do anything
|
|
221
|
+
- TODO: add or remove role-based context selection; the current import path is absent
|
|
222
|
+
- TODO: harden `/memory/get` with a table allow-list before exposing the sidecar outside trusted local use
|
|
223
|
+
- TODO: decide whether to expose `runbooks` and `lessons` in the plugin API
|