dsh-memory-observer
Background observational memory for DeepSeek Harness sessions.
Long agent sessions lose their thread the moment the history is compacted: a summary of a summary of a summary. This plugin does the memory work while you work instead, so the model keeps the decisions, constraints, and rationale that matter without anyone triggering a slow "remember this" step.
It is an independent DSH implementation of the ideas in
elpapi42/pi-observational-memory,
built around DSH's own extension points: a per-agent system-prompt section, the
host storage domain, a same-origin settings API, and the compaction seam.
turn/end
│ (source tokens since the last observation reach the threshold)
▼
observer ──▶ observations ──▶ reflector ──▶ reflections
│ │
└──── active memory rendered into the system prompt
│
memory_recall (id ──▶ exact source events)
What you get
- Observations recorded quietly after each turn: decisions and their reasons, constraints, preferences, verified results, open work, exact identifiers.
- Reflections distilled from those observations: durable facts that keep the session oriented across many compactions.
- No conversation pollution. The plugin never appends session events; memory reaches the model as a system-prompt section, so fork, resume, replay, and compaction keep working.
- Source-backed recall. Every entry carries a 12-character id; the
memory_recalltool returns the exact source events behind it. - A real settings page. Settings → 观察式记忆 / Observational Memory lets you tune cadence, budgets, worker model, and behaviour, with live status and a one-click reset. No YAML editing required.
- Fast compaction. When
dsh-compaction-basicasks for a summary, prepared memory is rendered instead of paying for another long model call. - Durable. Memory and overrides live in DSH storage domains, so a plugin reload or app restart restores them.
Install
From npm (recommended):
dsh plugin add dsh-memory-observer
Or from inside a DSH session with the bundle manager:
plugin_manager install_bundle { target: "dsh-memory-observer" }
From a local checkout:
plugin_manager install_bundle { target: "E:\\path\\to\\dsh-memory-observer" }
The bundle inserts one row (observational-memory) and enables the shipped
compaction-basic engine, so the prepared memory layer has a compaction pass to
serve. Remove the last compaction-basic entry from cordis.patch.yml if this
profile must stay compaction-free; the memory layer and memory_recall keep
working without it. After the first client-half install, refresh the Web page
once so the Settings section is registered.
Settings
The settings page is registered in the Settings panel and covers:
- Cadence — observation/reflection thresholds, injection threshold, start delay
- Memory budget — observation pool, observation/reflection caps, source chars, worker output cap
- Worker model — provider, model id, reasoning effort
- Behaviour — pause background work, fast compaction, debug log, subagents
- Status — tracked sessions, observation/reflection counts, worker state, last error
Saved values are stored in the observational_memory_settings storage domain
and applied immediately. Reset to row config clears the overrides and falls
back to the plugin row's config.
Configuration reference
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
Mount the plugin at all (requires reload). |
passive |
false |
Stop proactive background work; prepared memory and recall still work. |
observeAfterTokens |
8000 |
Surface tokens between observer runs. |
reflectAfterTokens |
12000 |
Surface tokens between reflection runs. |
injectAfterTokens |
0 |
Request pressure above which memory is injected; 0 = as soon as memory exists. |
maxObservations |
80 |
Active observation cap; oldest entries move to the archive index. |
maxReflections |
20 |
Reflection cap for the rendered layer. |
observationPoolTokens |
2400 |
Token budget of observations rendered into the prompt. |
maxSourceChars |
36000 |
Transcript chars per observer run (newest slice wins). |
agentMaxTokens |
2500 |
Output cap for one memory-worker call. |
debounceMs |
1200 |
Quiet delay after a turn before background work starts. |
fastCompaction |
true |
Serve compaction summaries from prepared memory. |
includeSubagents |
false |
Track subagent sessions separately. |
debugLog |
false |
One host log line per observer/reflector run. |
model |
session model | Optional worker route: { provider, model, reasoningEffort }. Disable or minimize reasoning — a reasoning-heavy worker can spend its whole output cap before emitting JSON. |
Verification
/om-statusreports counters and the source-token clock;/om-viewprints the rendered memory block.memory_recallis registered as a per-agent tool.- The session's current
system/messagecontains## Observational memory. - Memory persists in
observational_memory, overrides inobservational_memory_settings(~/.dsh/storages/*.jsonon desktop).
Limits
- The worker uses the session model unless
modeloverrides it; pool pruning is deterministic (oldest first), not model-driven. - Fast compaction engages only when a compaction backend is loaded and calls the
session's model with
purpose: "compaction". - Memory is derived state; the session log remains the source of truth.
- The
/om-statusand/om-viewcommand surfaces are registered through the standard registry; their rendered appearance is not covered by automated tests.
License
MIT © AntonyLang. See LICENSE.
No comments yet. Be the first to write one.