@animalabs/connectome-host 0.7.2 → 0.7.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 +203 -10
- package/HEADLESS-FLEET-PLAN.md +22 -0
- package/README.md +22 -11
- package/docs/AGENT-ONBOARDING.md +20 -1
- package/docs/debug-context-api.md +2 -2
- package/docs/retrieval-traces.md +173 -0
- package/docs/webui-deployment.md +2 -1
- package/package.json +3 -3
- package/scripts/audit-module-optins.ts +288 -0
- package/scripts/warmup-session.ts +17 -3
- package/src/codex-subscription-adapter.ts +13 -1
- package/src/framework-agent-config.ts +59 -4
- package/src/framework-strategy.ts +33 -3
- package/src/headless.ts +14 -0
- package/src/index.ts +95 -35
- package/src/logging-adapter.ts +13 -2
- package/src/mcpl-config.ts +8 -0
- package/src/modules/fleet-module.ts +60 -1
- package/src/modules/fleet-types.ts +30 -1
- package/src/modules/identity-module.ts +274 -0
- package/src/modules/mcpl-admin-module.ts +78 -5
- package/src/modules/observers-module.ts +12 -0
- package/src/modules/retrieval-module.ts +254 -52
- package/src/modules/retrieval-trace-page.ts +254 -0
- package/src/modules/retrieval-trace.ts +904 -0
- package/src/modules/settings-module.ts +28 -2
- package/src/modules/subscription-gc-module.ts +54 -1
- package/src/modules/tts-relay-module.ts +33 -18
- package/src/modules/web-ui-module.ts +445 -894
- package/src/recipe.ts +137 -12
- package/src/retrieval-config.ts +39 -0
- package/src/strategies/frontdesk-strategy.ts +34 -125
- package/src/tui.ts +325 -54
- package/src/web/panel-data.ts +1187 -0
- package/src/web/protocol.ts +75 -10
- package/test/audit-module-optins.test.ts +167 -0
- package/test/bedrock-prompt-caching.test.ts +170 -0
- package/test/fleet-panel-request.test.ts +90 -0
- package/test/framework-strategy-defaults.test.ts +110 -0
- package/test/frontdesk-strategy.test.ts +25 -37
- package/test/headless-panel-request.test.ts +201 -0
- package/test/identity-and-surfaces.test.ts +157 -0
- package/test/mcpl-admin-module.test.ts +23 -0
- package/test/mock-headless-child.ts +14 -0
- package/test/retrieval-auth-loopback.test.ts +49 -0
- package/test/retrieval-config.test.ts +74 -0
- package/test/retrieval-module.test.ts +821 -0
- package/test/subscription-gc-module.test.ts +152 -0
- package/test/tui-format.test.ts +106 -0
- package/test/web-ui-context-coverage.test.ts +1 -1
- package/test/web-ui-module.test.ts +189 -3
- package/test/web-ui-observers.test.ts +8 -5
- package/test/web-ui-protocol.test.ts +0 -0
- package/web/bun.lock +345 -0
- package/web/src/App.tsx +159 -44
- package/web/src/Context.tsx +35 -8
- package/web/src/ContextDocument.tsx +20 -5
- package/web/src/Files.tsx +2 -8
- package/web/src/Lessons.tsx +2 -38
- package/web/src/Mcpl.tsx +80 -14
- package/web/src/Pins.tsx +5 -0
- package/web/src/Settings.tsx +5 -0
- package/web/vite.config.ts +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,209 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.7.4 — 2026-08-03
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Frontdesk agents ride the adaptive path.** `frontdesk` strategies now
|
|
10
|
+
default to adaptive resolution + kv-stable folding, same as
|
|
11
|
+
`autobiographical` (a recipe can pin `adaptiveResolution: false` to keep the
|
|
12
|
+
old hierarchical renderer). The hierarchical renderer reserves nothing for
|
|
13
|
+
the raw tail and cannot shed summary mass, so a long-lived frontdesk agent
|
|
14
|
+
eventually saturates its fixed context budget into a terminal
|
|
15
|
+
`UncoveredDropError` refusal loop — the 2026-08-03 boter clerk outage.
|
|
16
|
+
Details and deltas:
|
|
17
|
+
- Topic-aware chunking now rides context-manager's `chunkBoundaryHint` seam
|
|
18
|
+
(requires CM ≥0.6.3) instead of a fork of `rebuildChunks` that silently
|
|
19
|
+
bypassed chunk-record persistence and the fail-closed orphan guard.
|
|
20
|
+
- Existing frontdesk stores carry no chunk records (the fork never wrote
|
|
21
|
+
them); context-manager's `migrateChunkRecords` backfills them from L1
|
|
22
|
+
`sourceIds` on first load, so upgraded stores do not re-compress lived
|
|
23
|
+
history. First boot re-plans folds (one-time KV churn, possibly a burst of
|
|
24
|
+
L1 production for the un-summarized frontier).
|
|
25
|
+
- The salience-biased L1 emission order is retired (it was a hierarchical-
|
|
26
|
+
renderer concept); unanswered questions/@mentions are still preserved
|
|
27
|
+
verbatim through the compression prompt.
|
|
28
|
+
- Witnessed chunks now get the base witnessed compression prompt; the fork
|
|
29
|
+
predated witnessed prompts and overrode them.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Every WebUI inspection panel now works per fleet child.** One persistent
|
|
34
|
+
scope dropdown in the sidebar header ("inspecting: …") replaces the
|
|
35
|
+
per-tab pill rows Lessons/Files carried — MCPL, Context, Settings, Pins,
|
|
36
|
+
Health, and the main-pane Context document all follow it, instead of the
|
|
37
|
+
previous split where only Lessons/Files could switch (statefully, via
|
|
38
|
+
duplicated pickers), Context 404'd by mis-sending the child name as an
|
|
39
|
+
`?agent=` param, and MCPL/Settings/Pins/Health were silently locked to the
|
|
40
|
+
fleetmaster. Backed by one generic fleet IPC verb pair
|
|
41
|
+
(`panel-request`/`panel-response`) dispatching into a shared panel layer
|
|
42
|
+
(`src/web/panel-data.ts`) that both the WebUI host and headless children
|
|
43
|
+
run — a new panel op needs no protocol change to work fleet-wide.
|
|
44
|
+
Details:
|
|
45
|
+
- `/debug/context/{,makeup,coverage,curve,preview,maintenance}` and
|
|
46
|
+
`/healthz` accept `?scope=<child>` — the host proxies to the child over
|
|
47
|
+
the fleet IPC and answers with its JSON verbatim (still curl-able;
|
|
48
|
+
connectome-doctor / fleet hub can now watch children through the host).
|
|
49
|
+
`/curve?scope=<child>` passes through to the scoped JSON.
|
|
50
|
+
- The MCPL tab shows the scoped process's **live** loaded servers
|
|
51
|
+
(connection status, tool counts — the long-missing fleet mcpl snapshot)
|
|
52
|
+
above the shared registry file; registry edits stay host-scope (the
|
|
53
|
+
file is one cwd-shared registry, so a "child-local edit" would be a
|
|
54
|
+
lie) and the panel says so instead of hiding the fact.
|
|
55
|
+
- Settings mutations, dry-run previews (single-flight guard now lives in
|
|
56
|
+
the target process), and pin add/remove run inside the scoped child;
|
|
57
|
+
child pins snapshots ship picker candidates (real store ids) since the
|
|
58
|
+
SPA has no window into a child's message store.
|
|
59
|
+
- Scoped WS responses (`lessons-list`, `workspace-*`, `mcpl-list`,
|
|
60
|
+
`settings-state`, `pins-list`) now echo their `scope`, and the SPA
|
|
61
|
+
drops replies that arrive after the operator switched — fixing a
|
|
62
|
+
pre-existing race where a slow child's lessons/files could render under
|
|
63
|
+
another child's header.
|
|
64
|
+
- Child health snapshots include the child's recent provider-call ledger.
|
|
65
|
+
- **TUI: context budget gauge.** The status bar's `ctx:` readout and the fleet
|
|
66
|
+
tree's per-agent readouts show `142k/180k` against the *live* runtime budget
|
|
67
|
+
(runtime overrides win over the recipe), and the status segment goes yellow at
|
|
68
|
+
75% / red at 90% — "how close to compression/trouble" at a glance instead of a
|
|
69
|
+
bare number.
|
|
70
|
+
- **TUI: fleet view viewport.** The tree now scrolls with the cursor
|
|
71
|
+
(`┈ N lines above/below ┈` markers) instead of clipping past the bottom of the
|
|
72
|
+
terminal — previously a large fleet let the cursor walk below the fold and
|
|
73
|
+
Del:stop targeted rows the operator couldn't see.
|
|
74
|
+
- **TUI: fleet view opens with a summary header** — agent counts
|
|
75
|
+
(running/done/failed/cancelled across local subagents *and* fleet children),
|
|
76
|
+
children up/crashed, session cost — plus the active ops alerts in full (the
|
|
77
|
+
status bar only has room for a count).
|
|
78
|
+
- **TUI: event timestamps.** Alerts, tool batches, subagent results, wake
|
|
79
|
+
triggers, branch switches, errors and user messages get an `HH:MM` prefix, so
|
|
80
|
+
scrollback read an hour later still answers "when".
|
|
81
|
+
- **TUI: root-agent tool completions are visible.** Verbose shows every
|
|
82
|
+
`✓ tool (1.2s)`; terse shows the slow ones (≥2s). Slow *running* tools show a
|
|
83
|
+
live elapsed in the status bar after 5s — "still executing" and "stuck" no
|
|
84
|
+
longer look identical.
|
|
85
|
+
- **TUI: the status bar names the worst active alert** (`⚠ 2 ·
|
|
86
|
+
compression-quarantine`), with quarantine and inference-exhausted outranking
|
|
87
|
+
the merely-recent.
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- **TUI: thinking honors the Ctrl+V verbose toggle.** Terse mode collapses live
|
|
92
|
+
thinking to a counting one-liner (`💭 thinking… ~1.2k tok`) and replayed
|
|
93
|
+
history thinking to one truncated line per block — the toggle's label always
|
|
94
|
+
claimed this.
|
|
95
|
+
- **TUI: session-history replay caps at the last 50 messages** (marker points at
|
|
96
|
+
the web UI for the rest) instead of flooding scrollback with the whole session.
|
|
97
|
+
- **TUI: elapsed times are humane everywhere** — `5m48s`, not `348s`; the fleet
|
|
98
|
+
tree and both peek views now agree.
|
|
99
|
+
- **TUI: peek-proc renders child `ops:alert` events properly** (red `⚠ kind:
|
|
100
|
+
message`, cyan for `-clear`) instead of a dim `· ops:alert` dot line, and no
|
|
101
|
+
longer prints dot lines for per-block/per-round bookkeeping events.
|
|
102
|
+
- **TUI: the status-left segment truncates to fit** the terminal width instead of
|
|
103
|
+
shoving the tokens/mem segment off the row.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- `cancel-subagent-result` was missing from the headless runtime's
|
|
108
|
+
subscription-filter exemptions: a parent that narrowed the event stream
|
|
109
|
+
could never see its own cancel confirmations.
|
|
110
|
+
- The Vite dev server proxies `/debug`, `/healthz`, `/curve`, and `/files`
|
|
111
|
+
to the running host — previously every HTTP panel fetch 404'd under
|
|
112
|
+
`bun run dev`.
|
|
113
|
+
- **TUI: "Branch switched" announcements survive.** The line was printed *before*
|
|
114
|
+
`refreshFromStore()` cleared the scrollbox, so it was destroyed unread.
|
|
115
|
+
|
|
116
|
+
### Upgrade notes
|
|
117
|
+
|
|
118
|
+
- **subagents/lessons/retrieval are now opt-in** (they were opt-out, and
|
|
119
|
+
DEFAULT_RECIPE enabled all three). A recipe that omits them ran them under
|
|
120
|
+
v0.7.2 and stops running them on this upgrade — that is the fix for
|
|
121
|
+
"lessons injected despite following the onboarding guide" (Discord issue
|
|
122
|
+
#32) working as intended. A recipe that *explicitly* enables them keeps
|
|
123
|
+
them, deliberately: a defaults change cannot tell old boilerplate from a
|
|
124
|
+
real choice. Before upgrading an existing deployment, run
|
|
125
|
+
|
|
126
|
+
bun scripts/audit-module-optins.ts <recipes-and-data-dirs...>
|
|
127
|
+
|
|
128
|
+
It reports every explicit enable, every omission that changes behavior,
|
|
129
|
+
and every retrieval-without-lessons combination that would go silently
|
|
130
|
+
inert — and modifies nothing; the decisions stay with the operator.
|
|
131
|
+
Persisted `data/.recipe.json` files are launch-time snapshots, not
|
|
132
|
+
authoritative sources — the audit lists them separately as pointers back
|
|
133
|
+
to the source recipe. Retrieved-lesson injection also moved from the
|
|
134
|
+
system prompt to after the last user message, which keeps the stable
|
|
135
|
+
prefix KV-cacheable.
|
|
136
|
+
|
|
137
|
+
### Added
|
|
138
|
+
|
|
139
|
+
- **Operator retrieval traces.** The Web UI now exposes operator-only,
|
|
140
|
+
process-memory retrieval traces at `/debug/retrieval` and a readable
|
|
141
|
+
lesson-selection viewer at `/debug/retrieval/view`, including invoking-agent
|
|
142
|
+
attribution, mechanical candidates, relevance decisions, cache provenance,
|
|
143
|
+
and the exact injected lesson block. Exact conversation/model inputs remain
|
|
144
|
+
opt-in via literal `includeInputs=1`.
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- **OpenAI retrieval reasoning effort.** Recipes using `openai-responses` or
|
|
149
|
+
`openai-codex` can set `modules.retrieval.reasoningEffort` independently of
|
|
150
|
+
the primary agent. Unsupported providers fail recipe validation instead of
|
|
151
|
+
receiving an invalid OpenAI-shaped request, and reasoning-enabled retrieval
|
|
152
|
+
requires an explicit model instead of falling through to the Claude default.
|
|
153
|
+
|
|
154
|
+
- **`mcpl_list` reports the live MCPL policy boundary.** Each server now shows
|
|
155
|
+
connected/retrying state, whether its initial policy was established, its
|
|
156
|
+
effective grant, host-masked and deny-by-default capability paths, and the
|
|
157
|
+
separate host-owned `host/command` authority. During a rolling upgrade,
|
|
158
|
+
fields unavailable from an older agent-framework render as `unknown` rather
|
|
159
|
+
than as a misleading empty grant.
|
|
160
|
+
|
|
161
|
+
## 0.7.3 — 2026-08-01
|
|
162
|
+
|
|
163
|
+
### Changed
|
|
164
|
+
|
|
165
|
+
- **Prompt caching enabled on Bedrock for models that support it**
|
|
166
|
+
(Discord issue #35). The previous transport-wide `promptCaching: false`
|
|
167
|
+
was a workaround for "your request did not allow prompt caching" —
|
|
168
|
+
which turned out to be the account-level denial for 3.5 Sonnet v2
|
|
169
|
+
(caching there was preview-only and dropped at Bedrock's GA), not a
|
|
170
|
+
transport property. Caching is now gated per model
|
|
171
|
+
(`bedrockModelSupportsPromptCaching`): on for the Bedrock caching-GA
|
|
172
|
+
lineup (3.5 Haiku, 3.7 Sonnet, Claude 4+), off for the pre-GA families
|
|
173
|
+
(Claude v2/instant, Claude 3, 3.5 Sonnet — matched at the family
|
|
174
|
+
boundary, so bare aliases and `-latest` forms gate the same as dated
|
|
175
|
+
ids; non-Claude Bedrock ids are conservatively off). New recipe field
|
|
176
|
+
`agent.promptCaching: boolean` overrides the gate in either direction
|
|
177
|
+
on any provider, and lands at both layers — per-agent config and
|
|
178
|
+
Membrane's default for internal callers (compression/merge) — for
|
|
179
|
+
accounts/regions whose entitlements differ from the GA table.
|
|
180
|
+
`cacheTtl` is withheld at the host layer on bedrock (Agent Framework
|
|
181
|
+
still supplies its own default downstream; membrane ≥ 0.5.77 strips
|
|
182
|
+
the ttl field at the provider boundary, so the wire request never
|
|
183
|
+
carries it either way). Verified live 2026-07-31: every currently
|
|
184
|
+
invokable Claude on Bedrock (all 4-era; 3.5-era and opus-4-0514 are
|
|
185
|
+
EOL there) writes and reads the cache cleanly. Requires
|
|
186
|
+
`@animalabs/membrane` ≥ 0.5.77 (cache_control ttl strip, stream cache
|
|
187
|
+
usage capture, 4-era inference-profile model mapping); the dependency
|
|
188
|
+
and lockfile are bumped accordingly in this change.
|
|
189
|
+
|
|
190
|
+
- **Subscription-GC closes carry honest provenance and respect explicit
|
|
191
|
+
opens** (Discord issue #5, the Mythos "channel settings keep resetting"
|
|
192
|
+
mechanism). GC closes are now recorded as `subscription-gc`, never
|
|
193
|
+
`agent-tool`; a channel the resident/operator explicitly opened is no
|
|
194
|
+
longer auto-closed under the *default* budget — a configured per-channel
|
|
195
|
+
numeric budget in `agent_settings.channel_idle_limits` counts as an
|
|
196
|
+
explicit idle lease and still closes at that budget. (The override state
|
|
197
|
+
records no actor — agent, operator, or imported are all possible — so
|
|
198
|
+
receipts say `configured-budget`, claiming no more than the state
|
|
199
|
+
proves.) Pins and policy-opened channels behave as before. Requires
|
|
200
|
+
agent-framework with machine-close provenance; against an older
|
|
201
|
+
framework GC behaves as it did.
|
|
202
|
+
- **GC closes emit an operator-side ops receipt** (`subscription-gc-close`
|
|
203
|
+
via the framework ops channel: failures.log + `ops:alert` trace +
|
|
204
|
+
webhook) naming channel, threshold, decision source, and the restore
|
|
205
|
+
action — ids and thresholds only, no content. A durable listening-state
|
|
206
|
+
change no longer looks spontaneous from outside the transcript.
|
|
207
|
+
|
|
5
208
|
## 0.7.2 — 2026-07-27
|
|
6
209
|
|
|
7
210
|
### Added
|
|
@@ -21,8 +224,6 @@
|
|
|
21
224
|
write, output, breakpoints, duration and verdict, with refusals and errors
|
|
22
225
|
highlighted. Cumulative totals for the session remain in the Usage panel.
|
|
23
226
|
|
|
24
|
-
## Unreleased
|
|
25
|
-
|
|
26
227
|
## 0.7.0 — 2026-07-26
|
|
27
228
|
|
|
28
229
|
### Added
|
|
@@ -42,8 +243,6 @@
|
|
|
42
243
|
`/debug/context/makeup` this costs nothing and makes no `count_tokens` network
|
|
43
244
|
call, so it is safe on the 15s health poll.
|
|
44
245
|
|
|
45
|
-
## Unreleased
|
|
46
|
-
|
|
47
246
|
## 0.6.1 — 2026-07-26
|
|
48
247
|
|
|
49
248
|
### Fixed
|
|
@@ -58,8 +257,6 @@
|
|
|
58
257
|
text/id filter. Caught by checking the endpoint against a real store before
|
|
59
258
|
anyone used the panel.
|
|
60
259
|
|
|
61
|
-
## Unreleased
|
|
62
|
-
|
|
63
260
|
## 0.6.0 — 2026-07-26
|
|
64
261
|
|
|
65
262
|
### Added
|
|
@@ -123,8 +320,6 @@
|
|
|
123
320
|
measured cost, and notes runs are serialized so a second click is refused
|
|
124
321
|
rather than queueing another pause.
|
|
125
322
|
|
|
126
|
-
## Unreleased
|
|
127
|
-
|
|
128
323
|
## 0.5.3 — 2026-07-26
|
|
129
324
|
|
|
130
325
|
### Added
|
|
@@ -247,8 +442,6 @@
|
|
|
247
442
|
- `compressionMaxTokens` recipe passthrough — cap compression output for
|
|
248
443
|
models with low output ceilings (2c78936).
|
|
249
444
|
|
|
250
|
-
## Unreleased
|
|
251
|
-
|
|
252
445
|
### Fixed
|
|
253
446
|
|
|
254
447
|
- **TUI bug sweep** (#64): operator-safety and observability fixes.
|
package/HEADLESS-FLEET-PLAN.md
CHANGED
|
@@ -223,12 +223,34 @@ One JSON object per line. All events include `type`; most include `ts` (epoch ms
|
|
|
223
223
|
{"type":"text","content":"Please resummarize last week"}
|
|
224
224
|
{"type":"command","command":"/status"}
|
|
225
225
|
{"type":"shutdown","graceful":true}
|
|
226
|
+
{"type":"panel-request","op":"settings","params":{"agent":"clerk"},"corrId":"panel-1"}
|
|
226
227
|
```
|
|
227
228
|
|
|
228
229
|
- `subscribe` is idempotent. Typically sent once right after connection. Supports simple glob (`tool:*`, `inference:*`).
|
|
229
230
|
- `text` produces an `external-message` event with `source: 'headless'` — same effect as user typing into the child's own TUI.
|
|
230
231
|
- `command` routes through the child's `commands.ts` handler exactly as if typed locally.
|
|
231
232
|
- `shutdown` sets `graceful`; child completes in-flight inference, then exits. `graceful: false` is equivalent to SIGTERM.
|
|
233
|
+
- `panel-request` runs one operator-panel operation in the child via the shared
|
|
234
|
+
`runPanelOp` dispatcher (`src/web/panel-data.ts`) — the same code the WebUI
|
|
235
|
+
host runs for its own process, so parent and child views of any panel can
|
|
236
|
+
never drift. Ops: `mcpl`, `settings`, `settings-update`, `settings-reset`,
|
|
237
|
+
`settings-cancel-transition`, `pins`, `pin-add`, `pin-remove`, `health`,
|
|
238
|
+
`context-makeup`, `context-coverage`, `context-curve`, `context-preview`,
|
|
239
|
+
`context-maintenance`, `debug-context`. The child answers with a single
|
|
240
|
+
`panel-response`:
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{"type":"panel-response","op":"settings","corrId":"panel-1","ok":true,"data":{...}}
|
|
244
|
+
{"type":"panel-response","op":"settings","corrId":"panel-1","ok":false,"error":"Agent not found: x","status":404}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
`status` is HTTP-ish so the parent's `?scope=<child>` proxy routes
|
|
248
|
+
(`/debug/context/*`, `/healthz`) can answer faithfully. `panel-response`
|
|
249
|
+
(like the other request/response snapshots) bypasses the subscription
|
|
250
|
+
filter. Parent-side, `FleetModule.requestPanel()` wraps the corrId
|
|
251
|
+
bookkeeping in a promise and never rejects — unreachable children resolve
|
|
252
|
+
`{ok:false,status:502}`, silence resolves `{ok:false,status:504}` after the
|
|
253
|
+
timeout (default 30s).
|
|
232
254
|
|
|
233
255
|
### Connection lifecycle
|
|
234
256
|
|
package/README.md
CHANGED
|
@@ -29,12 +29,7 @@ A recipe is a JSON file that configures everything domain-specific:
|
|
|
29
29
|
"model": "claude-opus-4-6",
|
|
30
30
|
"timezone": "America/Los_Angeles",
|
|
31
31
|
"systemPrompt": "You are a ...",
|
|
32
|
-
"maxTokens": 16384
|
|
33
|
-
"strategy": {
|
|
34
|
-
"type": "autobiographical",
|
|
35
|
-
"headWindowTokens": 4000,
|
|
36
|
-
"recentWindowTokens": 30000
|
|
37
|
-
}
|
|
32
|
+
"maxTokens": 16384
|
|
38
33
|
},
|
|
39
34
|
"mcpServers": {
|
|
40
35
|
"my-server": {
|
|
@@ -44,9 +39,6 @@ A recipe is a JSON file that configures everything domain-specific:
|
|
|
44
39
|
}
|
|
45
40
|
},
|
|
46
41
|
"modules": {
|
|
47
|
-
"subagents": true,
|
|
48
|
-
"lessons": true,
|
|
49
|
-
"retrieval": true,
|
|
50
42
|
"wake": true,
|
|
51
43
|
"files": { "namespace": "products" }
|
|
52
44
|
},
|
|
@@ -60,6 +52,14 @@ A recipe is a JSON file that configures everything domain-specific:
|
|
|
60
52
|
Chronicle and MCPL protocol timestamps remain epoch/UTC. If the recipe omits
|
|
61
53
|
it, `AGENT_TIMEZONE` is used, then the process timezone.
|
|
62
54
|
|
|
55
|
+
**Memory defaults**: `agent.strategy` may be omitted entirely. The default is
|
|
56
|
+
the autobiographical memory strategy with adaptive resolution, **KV-stable
|
|
57
|
+
folding** (compile plans that preserve prompt-cache prefixes), compression by
|
|
58
|
+
the agent's own model, and summaries voiced as the agent itself
|
|
59
|
+
(`summaryParticipant` defaults to `agent.name`). Set a `strategy` block only
|
|
60
|
+
to tune windows/budgets or opt into a different strategy type — see
|
|
61
|
+
`docs/AGENT-ONBOARDING.md` for sizing guidance on long-lived agents.
|
|
62
|
+
|
|
63
63
|
### Recipe loading
|
|
64
64
|
|
|
65
65
|
| Command | Behavior |
|
|
@@ -122,13 +122,23 @@ subscription credits at a higher rate when applied.
|
|
|
122
122
|
|
|
123
123
|
- **Web UI**: browser operator console (`modules.webui`) — live chat with full interiority (thinking, tool calls, streaming), agent/fleet tree, context makeup + compression coverage, call ledger with cache verdicts and billing-grade costs, health/ops alerts, Chronicle branch tree, lessons, MCPL config, workspace files; scoped read-only observer access via device keys
|
|
124
124
|
- **TUI + readline modes**: OpenTUI interactive terminal or `--no-tui` for pipes/CI
|
|
125
|
-
- **Subagent forking
|
|
126
|
-
- **Persistent lessons
|
|
125
|
+
- **Subagent forking** (opt-in, `modules.subagents`): Spawn/fork parallel agents with fleet tree view (Tab to toggle)
|
|
126
|
+
- **Persistent lessons** (opt-in, `modules.lessons`): Knowledge store with confidence scores and tags. Automatic retrieval-injection of lessons into context (`modules.retrieval`) is a separate opt-in — it adds per-turn context churn and retrieval-model calls, so enable it only for agents that actually curate a lesson library
|
|
127
127
|
- **Time-travel**: Chronicle-backed undo/redo, named checkpoints, branch exploration
|
|
128
128
|
- **Session management**: Isolated sessions with auto-naming
|
|
129
129
|
- **MCPL support**: Connect any MCP/MCPL server; wake subscriptions for selective event triggering
|
|
130
130
|
- **File products**: Write reports and documents, materialize to disk
|
|
131
131
|
|
|
132
|
+
For `openai-responses` and `openai-codex`, an object-valued
|
|
133
|
+
`modules.retrieval` can set `reasoningEffort` (`none`, `minimal`, `low`,
|
|
134
|
+
`medium`, `high`, `xhigh`, or `max`) independently of the primary agent.
|
|
135
|
+
Retrieval calls are independent one-shot requests, so there is no separate
|
|
136
|
+
retrieval reasoning-context setting. When `reasoningEffort` is configured,
|
|
137
|
+
`model` must also be set explicitly: the historical retrieval default is a
|
|
138
|
+
Claude model and cannot be sent through an OpenAI adapter. Anthropic/Claude
|
|
139
|
+
uses different native thinking controls and does not accept this OpenAI-shaped
|
|
140
|
+
option.
|
|
141
|
+
|
|
132
142
|
## Prerequisites
|
|
133
143
|
|
|
134
144
|
- [Node.js](https://nodejs.org/) 20+ and [Bun](https://bun.sh/) runtime
|
|
@@ -175,6 +185,7 @@ non-loopback binds require basic-auth credentials. Build the SPA bundle once wit
|
|
|
175
185
|
- Ops alerts (compression quarantine, refusal streaks, inference-exhausted) render as persistent banner rows
|
|
176
186
|
- Usage panel: per-agent costs and a billing-grade call ledger with cache verdicts
|
|
177
187
|
- `/curve` — compression-curve visualization; `/healthz` — liveness JSON for doctor/fleet tooling
|
|
188
|
+
- `/debug/retrieval/view` — operator-only per-run lesson selection viewer (see `docs/retrieval-traces.md`)
|
|
178
189
|
- Read-only observer access via Ed25519 device keys with per-grant scopes (see `docs/webui-deployment.md`)
|
|
179
190
|
|
|
180
191
|
For SPA development: `cd web && bun run dev` proxies the Vite dev server onto a
|
package/docs/AGENT-ONBOARDING.md
CHANGED
|
@@ -257,7 +257,8 @@ ln -sfn ../../../connectome-local/context-manager/node_modules/@animalabs/chroni
|
|
|
257
257
|
}
|
|
258
258
|
},
|
|
259
259
|
"modules": { "webui": { "port": 7343, "host": "127.0.0.1",
|
|
260
|
-
"basicAuth": { "username": "${WEBUI_USER}", "password": "${WEBUI_PASS}" } }
|
|
260
|
+
"basicAuth": { "username": "${WEBUI_USER}", "password": "${WEBUI_PASS}" } },
|
|
261
|
+
"subagents": false, "lessons": false, "retrieval": false
|
|
261
262
|
/* + wake policies, workspace mounts (files/, notes/) */ },
|
|
262
263
|
"mcpServers": {
|
|
263
264
|
"shell": { /* terminal-sessions stdio server; env: SESSION_SERVER_TOKEN, SESSION_SERVER_PORT */ },
|
|
@@ -271,6 +272,24 @@ Use `"cacheTtl": "1h"` for Connectome deployments. This is also the runtime
|
|
|
271
272
|
default when the field is omitted. Set `"5m"` only for intentionally rapid
|
|
272
273
|
workloads whose cache is normally reused within five minutes.
|
|
273
274
|
|
|
275
|
+
**`subagents`/`lessons`/`retrieval` are NOT part of the standard recipe.**
|
|
276
|
+
All three are opt-in. RetrievalModule in particular injects context-dependent
|
|
277
|
+
content into every compile (and spends up to two configured retrieval-model calls), so it must
|
|
278
|
+
be an explicit opt-in for agents that actually curate a lesson library.
|
|
279
|
+
Current host code defaults all three to off, but keep the explicit `false`
|
|
280
|
+
entries in the recipe anyway — older host checkouts treated these as opt-out,
|
|
281
|
+
and an accidentally-enabled RetrievalModule has caused severe prompt-cache
|
|
282
|
+
churn in the field.
|
|
283
|
+
|
|
284
|
+
**Memory defaults.** Current host code defaults an omitted/partial `strategy`
|
|
285
|
+
to the fleet-standard shape: autobiographical + `adaptiveResolution: true` +
|
|
286
|
+
`foldingStrategy: "kv-stable"` + same-model compression (`compressionModel`
|
|
287
|
+
falls back to `agent.model`) + `summaryParticipant` = `agent.name`. Keep the
|
|
288
|
+
skeleton's explicit values anyway: older host checkouts default folding to
|
|
289
|
+
`flat-profile` and summary voice to the literal `'Claude'` (the stranger's-voice
|
|
290
|
+
hazard), and explicit values survive host downgrades and copy-paste to other
|
|
291
|
+
deployments.
|
|
292
|
+
|
|
274
293
|
**`.env`** (`chmod 600`). Common vars:
|
|
275
294
|
|
|
276
295
|
```
|
|
@@ -75,8 +75,8 @@ The trade-off is fidelity: the default response **omits the dynamically
|
|
|
75
75
|
gathered injections** (lessons, retrieval results, MCPL `beforeInference`
|
|
76
76
|
context), because gathering those is *not* free or transparent:
|
|
77
77
|
|
|
78
|
-
- module `gatherContext` can run inference — e.g. the retrieval module makes
|
|
79
|
-
|
|
78
|
+
- module `gatherContext` can run inference — e.g. the retrieval module makes configured model calls, which cost tokens and add
|
|
79
|
+
latency;
|
|
80
80
|
- MCPL `beforeInference` hooks are arbitrary RPCs to external servers with
|
|
81
81
|
side effects, and a preview never sends the paired `afterInference`, which
|
|
82
82
|
can leave a stateful server half-open.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Retrieval Traces
|
|
2
|
+
|
|
3
|
+
The retrieval module can record a bounded, per-run explanation of automatic
|
|
4
|
+
lesson selection. The trace shows which concepts the selector returned, which
|
|
5
|
+
lessons matched mechanically, which candidates survived relevance filtering,
|
|
6
|
+
and the exact lesson block injected into the next compile.
|
|
7
|
+
|
|
8
|
+
Tracing is diagnostic. It does not change selection, trigger an extra model
|
|
9
|
+
call, or claim access to hidden chain-of-thought.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Enable lessons, retrieval, and the Web UI in the recipe:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"modules": {
|
|
18
|
+
"lessons": true,
|
|
19
|
+
"retrieval": {
|
|
20
|
+
"model": "gpt-5.4-mini",
|
|
21
|
+
"maxInjected": 5,
|
|
22
|
+
"reasoningEffort": "high"
|
|
23
|
+
},
|
|
24
|
+
"webui": {
|
|
25
|
+
"host": "127.0.0.1",
|
|
26
|
+
"port": 7340,
|
|
27
|
+
"basicAuth": {
|
|
28
|
+
"username": "${WEBUI_USER}",
|
|
29
|
+
"password": "${WEBUI_PASS}"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`reasoningEffort` accepts `none`, `minimal`, `low`, `medium`, `high`, `xhigh`,
|
|
37
|
+
or `max`. It is optional, applies to both retrieval calls, and does not inherit
|
|
38
|
+
the primary agent's reasoning setting. This field is supported only when
|
|
39
|
+
`agent.provider` is `openai-responses` or `openai-codex`; Anthropic/Claude uses
|
|
40
|
+
separate native thinking controls and is rejected here rather than receiving an
|
|
41
|
+
invalid OpenAI-shaped request.
|
|
42
|
+
|
|
43
|
+
Retrieval remains opt-in and requires the lessons module. Depending on the
|
|
44
|
+
candidate count, one turn can use one selector call plus an optional relevance
|
|
45
|
+
call.
|
|
46
|
+
|
|
47
|
+
## Operator viewer
|
|
48
|
+
|
|
49
|
+
Open:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
http://127.0.0.1:7340/debug/retrieval/view
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The viewer highlights selected lessons, lists all mechanically matched
|
|
56
|
+
candidates and their match provenance, summarizes the relevance decision, and
|
|
57
|
+
keeps the retained trace JSON behind a diagnostic disclosure. Each run is
|
|
58
|
+
labeled with the invoking agent name. Separate Host processes retain separate
|
|
59
|
+
trace stores and viewers; the endpoint does not aggregate fleet children.
|
|
60
|
+
|
|
61
|
+
## JSON endpoint
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
GET /debug/retrieval[?limit=20][&includeInputs=1]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Parameter | Default | Meaning |
|
|
68
|
+
|---|---:|---|
|
|
69
|
+
| `limit` | `20` | Newest traces to return, clamped to `1..100`. |
|
|
70
|
+
| `includeInputs` | off | Exact recent conversation and model-stage inputs are included only when the value is the literal `1`. |
|
|
71
|
+
|
|
72
|
+
Example envelope:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"schemaVersion": 1,
|
|
77
|
+
"enabled": true,
|
|
78
|
+
"includeInputs": false,
|
|
79
|
+
"traces": []
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Each trace can include:
|
|
84
|
+
|
|
85
|
+
- configured model and request-level reasoning parameters;
|
|
86
|
+
- recent-context hash, message count, and available message IDs;
|
|
87
|
+
- selector prompt, raw returned text, normalized provider blocks, parsed
|
|
88
|
+
concepts, and parse mode;
|
|
89
|
+
- every mechanical candidate, lesson snapshot, and content/tag match reason;
|
|
90
|
+
- relevance-call output or the reason validation was skipped;
|
|
91
|
+
- final relevant and injected lesson IDs, exact lesson snapshots, injection
|
|
92
|
+
namespace/position, and rendered `## Retrieved Knowledge` block;
|
|
93
|
+
- cache-hit provenance, outcome, duration, and errors.
|
|
94
|
+
|
|
95
|
+
Opaque or redacted reasoning blocks are retained only as provider-returned
|
|
96
|
+
content blocks. The trace does not decrypt them or present them as hidden
|
|
97
|
+
chain-of-thought. Each lesson snapshot is a point-in-time copy of every
|
|
98
|
+
`Lesson` field: `id`, `content`, `confidence`, `tags`, `evidence`, `created`,
|
|
99
|
+
`updated`, `deprecated`, and optional `deprecationReason`.
|
|
100
|
+
|
|
101
|
+
If retrieval is disabled, the endpoint returns `enabled: false` and an empty
|
|
102
|
+
trace list.
|
|
103
|
+
|
|
104
|
+
## Authentication and privacy
|
|
105
|
+
|
|
106
|
+
Both routes require password-derived operator authentication, including on a
|
|
107
|
+
loopback bind. Web UI Basic Auth must be configured; the routes accept either
|
|
108
|
+
direct valid Basic Auth or a full session created by password sign-in. A
|
|
109
|
+
loopback-only Web UI without configured credentials returns `401` for these two
|
|
110
|
+
routes, while other Web UI routes retain their historical loopback behavior.
|
|
111
|
+
Read-only observer cookies are rejected even when they carry the `debug` scope.
|
|
112
|
+
|
|
113
|
+
Exact recent conversation and stage inputs are omitted by default because they
|
|
114
|
+
can contain private text. Use `includeInputs=1` deliberately; values such as
|
|
115
|
+
`true` or `yes` do not enable disclosure. Lesson contents, selector output,
|
|
116
|
+
candidate provenance, and the final injected block remain visible in the
|
|
117
|
+
default trace because they are the subject of the diagnostic.
|
|
118
|
+
|
|
119
|
+
Every response from either retrieval route uses `Cache-Control: no-store`,
|
|
120
|
+
including authentication failures, not-yet-bound responses, and internal
|
|
121
|
+
errors.
|
|
122
|
+
|
|
123
|
+
## Retention and failure behavior
|
|
124
|
+
|
|
125
|
+
The retrieval module retains at most the newest 100 traces and, by default, at
|
|
126
|
+
most 8 MiB of UTF-8 encoded trace JSON in process memory. The limits are
|
|
127
|
+
enforced after every active trace mutation. When the byte budget is reached,
|
|
128
|
+
the oldest traces are evicted until both limits are satisfied. Traces are not
|
|
129
|
+
written to Chronicle and disappear when the Host restarts. Cache provenance is
|
|
130
|
+
rewritten when a referenced source is evicted or truncated, while each
|
|
131
|
+
cache-hit trace keeps its own complete selected-lesson snapshots when they fit
|
|
132
|
+
within the budget.
|
|
133
|
+
|
|
134
|
+
If one trace alone exceeds the byte budget, it is replaced with a small record
|
|
135
|
+
whose `truncation.kind` is `tombstone` and whose reason and original encoded
|
|
136
|
+
size make clear that the detailed payload is unavailable. Tombstones are never
|
|
137
|
+
presented as exact traces. Payloads that fit remain complete.
|
|
138
|
+
|
|
139
|
+
Trace recording is fail-open: metadata collection and serialization failures
|
|
140
|
+
must not block retrieval or the primary inference. Arbitrary provider blocks
|
|
141
|
+
and request-level provider parameters are converted to JSON-safe snapshots
|
|
142
|
+
before they are exposed. Their retained representations bound recursion depth,
|
|
143
|
+
total nodes, array items, object keys,
|
|
144
|
+
individual strings, and aggregate string bytes. When a bound applies, the
|
|
145
|
+
stage's `responseContentTruncation` records the explicit reason and active
|
|
146
|
+
limits. Cycles, BigInts, nonfinite numbers, and unreadable properties remain
|
|
147
|
+
safe to serialize using explicit unavailable-value records.
|
|
148
|
+
|
|
149
|
+
Viewing an existing trace is read-only. Retrieval itself still performs its
|
|
150
|
+
normal model calls and lesson lookup when the agent gathers context.
|
|
151
|
+
|
|
152
|
+
## Response codes
|
|
153
|
+
|
|
154
|
+
| Status | Meaning |
|
|
155
|
+
|---:|---|
|
|
156
|
+
| `200` | Viewer or trace response returned. |
|
|
157
|
+
| `401` | Missing operator authentication, including observer-only sessions. |
|
|
158
|
+
| `500` | Retrieval Trace listing failed; the response remains noncacheable. |
|
|
159
|
+
| `503` | Host application has not bound to the Web UI yet. |
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
- `enabled: false`: enable both `modules.lessons` and `modules.retrieval`, then
|
|
164
|
+
restart with the updated recipe.
|
|
165
|
+
- Empty `traces`: no retrieval run has completed or started since this Host
|
|
166
|
+
process began.
|
|
167
|
+
- Many candidates but few selected lessons: the relevance stage is filtering
|
|
168
|
+
mechanical keyword matches. `maxInjected` is a ceiling, not a quota.
|
|
169
|
+
- `sourceTraceEvicted: true`: a cache hit refers to a run older than the
|
|
170
|
+
in-memory retention window; the exact selected lesson snapshots remain on the
|
|
171
|
+
cache-hit trace.
|
|
172
|
+
- `sourceTraceTruncated: true`: the referenced source is retained only as a
|
|
173
|
+
tombstone; inspect the complete snapshots on the cache-hit trace itself.
|
package/docs/webui-deployment.md
CHANGED
|
@@ -160,7 +160,8 @@ Query params:
|
|
|
160
160
|
- `agent=<name>` — defaults to the recipe's root agent
|
|
161
161
|
- `injections=1` — opt into full fidelity: gather the dynamic injections too.
|
|
162
162
|
**Not transparent** — this can run inference (e.g. the retrieval module's
|
|
163
|
-
|
|
163
|
+
configured model calls cost tokens) and fires MCPL `beforeInference` hooks
|
|
164
|
+
(whose paired
|
|
164
165
|
`afterInference` is never sent, so a stateful server may be left half-open).
|
|
165
166
|
- `pretty=1` — pretty-print the JSON
|
|
166
167
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animalabs/connectome-host",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"description": "General-purpose agent TUI host with recipe-based configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@animalabs/agent-framework": "^0.7.2",
|
|
18
18
|
"@animalabs/chronicle": "^0.2.0",
|
|
19
|
-
"@animalabs/context-manager": "^0.6.
|
|
20
|
-
"@animalabs/membrane": "^0.5.
|
|
19
|
+
"@animalabs/context-manager": "^0.6.3",
|
|
20
|
+
"@animalabs/membrane": "^0.5.77",
|
|
21
21
|
"@opentui/core": "^0.1.82"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|