Skip to content

Commit 1db6e9a

Browse files
authored
Merge pull request #35 from basicmachines-co/codex/basic-memory-context-engine
Complete Basic Memory ContextEngine integration
2 parents 55736d4 + 492c91b commit 1db6e9a

32 files changed

+1217
-61
lines changed

.githooks/pre-commit

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if ! command -v bun >/dev/null 2>&1; then
5+
echo "bun is required to run pre-commit checks." >&2
6+
exit 1
7+
fi
8+
9+
echo "Running pre-commit checks..."
10+
bun run lint
11+
bun run check-types

CONTEXT_ENGINE_PLAN.md

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# Basic Memory ContextEngine Plan
2+
3+
## Goal
4+
5+
Complete the Basic Memory integration with OpenClaw's native memory lifecycle so BM works as a decorator around the default OpenClaw flow instead of relying on `agent_start` / `agent_end` shims.
6+
7+
The target model is:
8+
9+
- OpenClaw owns session state, context assembly pipeline, and compaction.
10+
- Basic Memory owns durable knowledge, cross-session recall, and long-term capture.
11+
- This plugin enriches the default flow without replacing it.
12+
13+
## Scope
14+
15+
This plan is for [issue #34](https://github.com/basicmachines-co/openclaw-basic-memory/issues/34), updated to match the "complement, don't replace" direction discussed there.
16+
17+
We will use the new OpenClaw `ContextEngine` lifecycle introduced in OpenClaw `2026.3.7` on March 6, 2026, but we will not implement a custom compaction strategy.
18+
19+
## Non-Goals
20+
21+
- Do not replace or override OpenClaw compaction behavior.
22+
- Do not compete with lossless-claw or other alternate context engines.
23+
- Do not turn BM into the canonical source of current-session state.
24+
- Do not remove existing BM tools such as `memory_search`, `memory_get`, `search_notes`, `read_note`, and note CRUD tools.
25+
- Do not add aggressive semantic retrieval on every turn.
26+
27+
## Design Principles
28+
29+
### Decorator, not replacement
30+
31+
The plugin should behave like a wrapper around the default OpenClaw memory model:
32+
33+
- OpenClaw tracks the live conversation.
34+
- BM stores durable notes, tasks, decisions, and cross-session context.
35+
- The plugin bridges the two systems at official lifecycle boundaries.
36+
37+
### Keep the baseline flow intact
38+
39+
Where the ContextEngine API requires behavior that OpenClaw already provides well, we should pass through to the default behavior instead of re-implementing it.
40+
41+
### Add value only where BM is strongest
42+
43+
BM should improve:
44+
45+
- session bootstrap recall
46+
- durable post-turn capture
47+
- subagent memory inheritance
48+
- cross-session continuity through notes and graph search
49+
50+
BM should not try to improve:
51+
52+
- session-local compaction
53+
- low-level pruning logic
54+
- runtime token budgeting heuristics
55+
56+
## Current State
57+
58+
Today the plugin uses:
59+
60+
- `api.on("agent_start", ...)` for recall
61+
- `api.on("agent_end", ...)` for capture
62+
- composited `memory_search` / `memory_get` tools for explicit retrieval
63+
64+
This works, but it lives beside OpenClaw's memory lifecycle instead of inside it.
65+
66+
Relevant current files:
67+
68+
- `index.ts`
69+
- `hooks/recall.ts`
70+
- `hooks/capture.ts`
71+
- `tools/memory-provider.ts`
72+
- `types/openclaw.d.ts`
73+
74+
Current dependency constraint:
75+
76+
- `package.json` currently pins `openclaw` peer support to `>=2026.1.29`
77+
- the local installed dependency is `openclaw@2026.2.6`
78+
- ContextEngine work requires moving to the `2026.3.7+` SDK surface
79+
80+
## Target Architecture
81+
82+
Add a `BasicMemoryContextEngine` that composes with the default OpenClaw flow.
83+
84+
Expected lifecycle usage:
85+
86+
- `bootstrap`
87+
- initialize BM session-side recall state
88+
- gather small, high-signal context such as active tasks and recent activity
89+
- `assemble`
90+
- pass through OpenClaw messages
91+
- optionally add a compact BM recall block when useful
92+
- `afterTurn`
93+
- persist durable takeaways from the completed turn into BM
94+
- `prepareSubagentSpawn`
95+
- prepare a minimal BM handoff for a child session
96+
- `onSubagentEnded`
97+
- capture child results back into BM
98+
- `compact`
99+
- do not customize
100+
- use legacy/default pass-through behavior only if the interface requires it
101+
102+
## Phase Plan
103+
104+
## Phase 1
105+
106+
### Commit goal
107+
108+
`feat(context-engine): move recall and capture into native lifecycle`
109+
110+
### Deliverables
111+
112+
- bump OpenClaw compatibility to `2026.3.7+`
113+
- replace the local SDK shim with the real ContextEngine-capable SDK types where possible
114+
- add a `BasicMemoryContextEngine`
115+
- register the engine through `api.registerContextEngine(...)`
116+
- migrate recall behavior from `agent_start` into `bootstrap`
117+
- migrate capture behavior from `agent_end` into `afterTurn`
118+
- keep existing BM tools and service startup behavior intact
119+
- keep compaction fully default
120+
121+
### Expected behavior
122+
123+
- session startup still recalls active tasks and recent activity
124+
- turns still get captured into BM
125+
- plugin behavior is functionally similar to today, but now uses official lifecycle hooks
126+
127+
### Test coverage
128+
129+
- engine registration works
130+
- `bootstrap` returns expected initialized state when recall finds data
131+
- `bootstrap` is a no-op when recall finds nothing
132+
- `afterTurn` captures only valid turn content
133+
- `afterTurn` handles failures without breaking the run
134+
- existing service startup and BM client lifecycle tests still pass
135+
136+
## Phase 2
137+
138+
### Commit goal
139+
140+
`feat(context-engine): add bounded assemble-time BM recall`
141+
142+
### Deliverables
143+
144+
- implement a minimal `assemble` hook
145+
- preserve incoming OpenClaw messages in order
146+
- add an optional BM recall block only when there is useful context
147+
- bound the size of injected BM context so it stays cheap and predictable
148+
- avoid per-turn graph-heavy retrieval unless explicitly configured later
149+
150+
### Expected behavior
151+
152+
- the model sees a small BM memory summary automatically when helpful
153+
- explicit `memory_search` and `memory_get` remain available for deeper retrieval
154+
- OpenClaw remains in charge of the actual context pipeline and compaction
155+
156+
### Test coverage
157+
158+
- `assemble` returns original messages unchanged when no recall block exists
159+
- `assemble` adds a BM block when recall content exists
160+
- injected content is size-bounded
161+
- assembly remains stable across repeated turns when recall content is unchanged
162+
163+
## Phase 3
164+
165+
### Commit goal
166+
167+
`feat(context-engine): add subagent memory handoff`
168+
169+
### Deliverables
170+
171+
- implement `prepareSubagentSpawn`
172+
- implement `onSubagentEnded`
173+
- create a small BM handoff model for parent to child context transfer
174+
- capture child outputs or summaries back into the parent knowledge base
175+
- keep subagent integration lightweight and failure-tolerant
176+
177+
### Expected behavior
178+
179+
- subagents start with relevant BM context instead of a cold memory start
180+
- useful child outputs become durable BM knowledge after completion
181+
- failures in handoff/capture do not break subagent execution
182+
183+
### Test coverage
184+
185+
- child handoff is created for subagent sessions
186+
- rollback path works if spawn fails after preparation
187+
- child completion writes back expected BM artifacts
188+
- delete/release/sweep paths are handled safely
189+
190+
## Implementation Notes
191+
192+
### Engine shape
193+
194+
Prefer a small, explicit implementation instead of pushing logic back into `index.ts`.
195+
196+
Likely new files:
197+
198+
- `context-engine/basic-memory-context-engine.ts`
199+
- `context-engine/basic-memory-context-engine.test.ts`
200+
- optional small helper modules for recall/capture formatting
201+
202+
### Hook migration
203+
204+
After Phase 1 lands, the old event-hook path in `index.ts` should be removed or disabled so we do not double-capture or double-recall.
205+
206+
### Tool preservation
207+
208+
The BM tool surface remains part of the product even after lifecycle integration:
209+
210+
- composited `memory_search` and `memory_get`
211+
- graph CRUD tools
212+
- schema tools
213+
- slash commands and CLI commands
214+
215+
Lifecycle integration complements explicit retrieval; it does not replace it.
216+
217+
### Compatibility posture
218+
219+
This work should be shipped as the canonical BM integration path for OpenClaw `2026.3.7+`.
220+
221+
If we need a temporary compatibility story for older OpenClaw versions, keep it shallow and time-boxed. The long-term target should be one code path based on the native lifecycle.
222+
223+
## Risks
224+
225+
### Single-slot context engine model
226+
227+
OpenClaw currently resolves one `contextEngine` slot, not a middleware stack.
228+
229+
Implication:
230+
231+
- our engine must behave like "default behavior plus BM enrichment"
232+
- we should not assume we can stack with other context engines automatically
233+
234+
### Over-injection
235+
236+
If `assemble` injects too much, BM could bloat prompt cost and work against the default system.
237+
238+
Mitigation:
239+
240+
- keep Phase 2 narrow
241+
- bound injected size
242+
- prefer summaries over raw note dumps
243+
244+
### Double-processing during migration
245+
246+
If old hooks and new lifecycle paths run together, recall and capture may happen twice.
247+
248+
Mitigation:
249+
250+
- Phase 1 should explicitly remove or disable the legacy hook wiring
251+
- add tests that assert only one capture path is active
252+
253+
## Success Criteria
254+
255+
This feature is complete when:
256+
257+
- recall and capture happen through ContextEngine lifecycle hooks, not event shims
258+
- BM enriches default session context without taking over compaction
259+
- subagents inherit and return useful durable memory
260+
- explicit BM tools remain intact
261+
- the architecture clearly reflects "BM decorates OpenClaw memory"
262+
263+
## Commit Sequence
264+
265+
1. `feat(context-engine): move recall and capture into native lifecycle`
266+
2. `feat(context-engine): add bounded assemble-time BM recall`
267+
3. `feat(context-engine): add subagent memory handoff`
268+
269+
## Out of Scope for This Stack
270+
271+
- custom `compact` logic
272+
- BM-driven token budgeting
273+
- replacing post-compaction context reinjection
274+
- new retrieval heuristics beyond a compact recall block
275+
- multi-engine composition support inside OpenClaw core

biome.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
2+
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
33
"assist": {
44
"actions": {
55
"source": {

0 commit comments

Comments
 (0)