7.1 KiB
7.1 KiB
retain
Queue durable facts for asynchronous write into the active Hindsight bank.
Source
- Entry:
packages/coding-agent/src/tools/hindsight-retain.ts - Model-facing prompt:
packages/coding-agent/src/prompts/tools/retain.md - Key collaborators:
packages/coding-agent/src/hindsight/state.ts— per-session queue, flush, auto-retain.packages/coding-agent/src/hindsight/backend.ts— session bootstrap, prompt injection, subagent aliasing.packages/coding-agent/src/hindsight/bank.ts— bank id derivation, tag scoping, mission setup.packages/coding-agent/src/hindsight/client.ts— HTTPretain/retainBatchcalls.packages/coding-agent/src/hindsight/content.ts— retention transcript shaping, memory-tag stripping.packages/coding-agent/src/hindsight/mental-models.ts— bank-scoped mental-model seeding and cache rendering.packages/coding-agent/src/hindsight/seeds.json— built-in mental-model seed definitions.packages/coding-agent/src/hindsight/transcript.ts— extracts user/assistant turns for auto-retain.
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
items |
Array<{ content: string; context?: string }> |
Yes | One or more memories to queue. minItems: 1. Each item must be self-contained; context is optional per-item provenance. |
Outputs
Returns a single-shot tool result:
content[0].type = "text"content[0].text = "<count> memory queued."or"<count> memories queued."details = { count: number }
The write is not confirmed before the tool returns. The queue flushes later; flush failures emit a session warning notice and are not returned to the model.
Flow
HindsightRetainTool.createIf(...)only exposes the tool whenmemory.backend == "hindsight"inpackages/coding-agent/src/tools/hindsight-retain.ts.execute(...)fetchessession.getHindsightSessionState()and throws if the Hindsight backend was not started.- Each input item is handed to
HindsightSessionState.enqueueRetain(...)inpackages/coding-agent/src/hindsight/state.ts. HindsightRetainQueue.enqueue(...)appends the item and either:- flushes immediately when the queue reaches
RETAIN_FLUSH_BATCH_SIZE, or - starts a debounce timer for
RETAIN_FLUSH_INTERVAL_MS.
- flushes immediately when the queue reaches
- On flush,
HindsightRetainQueue.#doFlush(...):- verifies the session still owns this state,
- calls
ensureBankMission(...)once per bank/process before writing, - maps queued items to
MemoryItemInputwithcontext ?? config.retainContext,metadata.session_id, and bank-scope tags, - sends one async
retainBatch(...)request.
- The tool returns immediately after enqueueing; it does not await the HTTP write.
Modes / Variants
- Tool path: queued batch write only.
- Bank scoping comes from
computeBankScope(...)inpackages/coding-agent/src/hindsight/bank.ts:global— one shared bank, no project tags.per-project— bank id gets-<cwd basename>appended.per-project-tagged— shared bank plusproject:<cwd basename>tags on retained memories.
- Session scope:
- tool-called retains are per-session queued work in
HindsightSessionState, - persisted memories are cross-session server-side bank data,
- subagents alias the parent
HindsightSessionState, so theirretaincalls write into the same bank and queue.
- tool-called retains are per-session queued work in
Side Effects
- Filesystem
- None for retained memories. No local memory file is written.
- Network
POST /v1/default/banks/{bank_id}/memoriesviaretainBatch(...)inpackages/coding-agent/src/hindsight/client.ts.- Optional
PUT /v1/default/banks/{bank_id}viaensureBankMission(...)before first write per bank/process.
- Session state (transcript, memory, jobs, checkpoints, registries)
- Appends to the in-memory
HindsightRetainQueueon the activeHindsightSessionState. - Includes
metadata.session_idon each retained item. - Shares parent state for subagents (
aliasOfpath inpackages/coding-agent/src/hindsight/backend.ts).
- Appends to the in-memory
- User-visible prompts / interactive UI
- On async flush failure, emits
session.emitNotice("warning", ...); the model is not told.
- On async flush failure, emits
- Background work / cancellation
- Flush runs later on timer, queue-size threshold,
agent_end, backendenqueue(...), or backendclear(...).
- Flush runs later on timer, queue-size threshold,
Limits & Caps
- Input schema requires
items.length >= 1inpackages/coding-agent/src/tools/hindsight-retain.ts. - Queue flush threshold:
RETAIN_FLUSH_BATCH_SIZE = 16inpackages/coding-agent/src/hindsight/state.ts. - Queue debounce:
RETAIN_FLUSH_INTERVAL_MS = 5_000inpackages/coding-agent/src/hindsight/state.ts. - Queue writes use
retainBatch(..., { async: true }); the client does not wait for server-side consolidation. - Shared auto-retain settings on the same backend:
hindsight.retainEveryNTurnsdefault3hindsight.retainOverlapTurnsdefault2hindsight.retainContextdefault"omp"hindsight.retainModedefault"full-session"frompackages/coding-agent/src/config/settings-schema.ts.
Errors
- Throws
Hindsight backend is not initialised for this session.when no state exists. - Queue enqueue on disposed state throws
Hindsight retain queue is closed. - Flush-time API failures are caught in
HindsightRetainQueue.#doFlush(...), logged, and converted into a warning notice instead of a tool error. - Mission creation failures are swallowed in
ensureBankMission(...); writes continue.
Notes
- Storage is server-side.
hindsightBackend.clear(...)only clears local cache/state and warns that upstream deletion must happen in Hindsight UI ordeleteBank; seepackages/coding-agent/src/hindsight/backend.ts. - Auto-retain uses the same bank but a different path than this tool:
retainSession(...)extracts plain user/assistant transcript frompackages/coding-agent/src/hindsight/transcript.ts, strips<memories>/<mental_models>blocks viastripMemoryTags(...), and calls single-itemretain(...). retainitself does not seed or read mental models. Mental-model bootstrap lives in the shared backend:HindsightSessionState.runMentalModelLoad(...)optionally resolves seeds frompackages/coding-agent/src/hindsight/seeds.json, creates missing models withensureMentalModels(...), then caches a rendered<mental_models>block for prompt injection.- Built-in seeds are
user-preferences,project-conventions, andproject-decisions.projectTagged: trueseeds inherit the active scope's retain tags; untagged seeds read the whole bank. - Mental-model defaults from
packages/coding-agent/src/config/settings-schema.ts:hindsight.mentalModelsEnabled = true,hindsight.mentalModelAutoSeed = true,hindsight.mentalModelRefreshIntervalMs = 5 * 60 * 1000,hindsight.mentalModelMaxRenderChars = 16_000. First-turn loading waits up toMENTAL_MODEL_FIRST_TURN_DEADLINE_MS = 1500inpackages/coding-agent/src/hindsight/mental-models.ts. - Seed lifecycle is create-only. Changing
packages/coding-agent/src/hindsight/seeds.jsondoes not mutate existing server-side models. recall.mdandreflect.mdrely on the same bank, scoping, and mental-model bootstrap; refer back here for the shared backend behavior.