@animalabs/connectome-host 0.7.3 → 0.8.0
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/.env.example +12 -5
- package/.github/PULL_REQUEST_TEMPLATE.md +3 -2
- package/.github/workflows/changelog.yml +9 -4
- package/.github/workflows/ci.yml +5 -3
- package/.github/workflows/publish.yml +12 -6
- package/CHANGELOG.md +401 -10
- package/CONTRIBUTING.md +47 -19
- package/HEADLESS-FLEET-PLAN.md +22 -0
- package/README.md +39 -1
- package/bun.lock +27 -31
- package/changelog.d/README.md +28 -0
- package/docs/AGENT-ONBOARDING.md +1 -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 +6 -6
- package/recipes/SETUP.md +11 -5
- package/recipes/TRIUMVIRATE-SETUP.md +68 -14
- package/recipes/knowledge-miner.json +0 -30
- package/recipes/mock-test.json +19 -0
- package/recipes/triumvirate.json +6 -1
- package/scripts/audit-module-optins.ts +288 -0
- package/scripts/release-changelog.ts +210 -21
- package/src/cache-keepalive-log.ts +41 -0
- package/src/commands.ts +96 -0
- package/src/framework-strategy.ts +50 -4
- package/src/gate-telemetry.ts +106 -0
- package/src/headless.ts +24 -0
- package/src/index.ts +179 -64
- package/src/mcpl-config.ts +99 -1
- package/src/modules/fleet-module.ts +60 -1
- package/src/modules/fleet-types.ts +30 -1
- package/src/modules/identity-module.ts +310 -2
- package/src/modules/instructions-module.ts +265 -0
- package/src/modules/mcpl-admin-module.ts +89 -13
- package/src/modules/retrieval-module.ts +249 -51
- package/src/modules/retrieval-trace-page.ts +254 -0
- package/src/modules/retrieval-trace.ts +904 -0
- package/src/modules/subagent-module.ts +18 -0
- package/src/modules/tts-relay-module.ts +33 -18
- package/src/modules/web-ui-module.ts +445 -894
- package/src/recipe.ts +787 -29
- 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 +1206 -0
- package/src/web/protocol.ts +75 -10
- package/src/workspace-mounts.ts +73 -0
- package/test/audit-module-optins.test.ts +174 -0
- package/test/cache-keepalive-log.test.ts +83 -0
- package/test/conversations-recipe.test.ts +142 -0
- package/test/fleet-panel-request.test.ts +90 -0
- package/test/framework-fkm-composition.test.ts +35 -3
- package/test/framework-strategy-defaults.test.ts +41 -0
- package/test/frontdesk-strategy.test.ts +25 -37
- package/test/gate-telemetry-adapter.test.ts +84 -0
- package/test/gate-telemetry.test.ts +91 -0
- package/test/headless-panel-request.test.ts +201 -0
- package/test/identity-and-surfaces.test.ts +212 -1
- package/test/instructions-module.test.ts +258 -0
- package/test/mcpl-admin-module.test.ts +64 -0
- package/test/mcpl-agent-overlay.test.ts +51 -3
- package/test/mcpl-child-env.test.ts +64 -0
- package/test/mock-headless-child.ts +14 -0
- package/test/nudge-command.test.ts +47 -0
- package/test/recipe-cache-keepalive.test.ts +59 -0
- package/test/recipe-compression-fallback.test.ts +19 -0
- package/test/recipe-hybrid-prose-routing.test.ts +12 -0
- package/test/recipe-instructions.test.ts +176 -0
- package/test/recipe-kv-unified.test.ts +87 -0
- package/test/recipe-mcp-source.test.ts +54 -0
- package/test/recipe-openai-compatible.test.ts +54 -0
- package/test/recipe-path-resolution.test.ts +19 -8
- package/test/recipe-provider.test.ts +14 -0
- package/test/recipe-save-unresolved.test.ts +244 -0
- package/test/recipe-source-only.test.ts +38 -0
- package/test/release-changelog.test.ts +202 -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/subagent-prose-routing.test.ts +109 -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/test/workspace-mounts.test.ts +68 -0
- package/web/src/App.tsx +160 -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/Health.tsx +61 -1
- 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/.env.example
CHANGED
|
@@ -23,11 +23,18 @@ ANTHROPIC_API_KEY=sk-ant-...
|
|
|
23
23
|
# GITLAB_TOKEN=glpat-...
|
|
24
24
|
# GITLAB_API_URL=https://gitlab.example.com/api/v4
|
|
25
25
|
|
|
26
|
-
# Notion
|
|
26
|
+
# Notion — only if you add a Notion MCP server block back to
|
|
27
|
+
# knowledge-miner.json (none ships by default; see TRIUMVIRATE-SETUP.md Step 6)
|
|
27
28
|
# NOTION_STORAGE_URL=http://localhost:8000
|
|
28
29
|
# NOTION_WORKSPACE_ID=...
|
|
29
30
|
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
31
|
+
# Web UI credentials (triumvirate.json: webui). Defaults to admin:admin —
|
|
32
|
+
# CHANGE THESE for anything reachable beyond your own machine.
|
|
33
|
+
# WEBUI_USERNAME=admin
|
|
34
|
+
# WEBUI_PASSWORD=admin
|
|
35
|
+
|
|
36
|
+
# Scribe — audio/video transcription. Only if you add a scribe block back to
|
|
37
|
+
# knowledge-miner.json (none ships by default; see TRIUMVIRATE-SETUP.md Step 6)
|
|
38
|
+
# GEMINI_API_KEY=... # required by the scribe block (bare ${GEMINI_API_KEY}); powers transcription
|
|
39
|
+
# NOTION_API_KEY=... # optional (block uses ${NOTION_API_KEY:-}); only scribe--scribe_notion_page needs it
|
|
40
|
+
# SCRIBE_GLOSSARY_URL=... # optional (block uses ${SCRIBE_GLOSSARY_URL:-}); unset = transcribe without a glossary
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
- [ ]
|
|
23
|
-
|
|
22
|
+
- [ ] Changelog fragment added — `changelog.d/<slug>.<breaking|added|changed|fixed>.md`
|
|
23
|
+
(see `changelog.d/README.md`) — or this change is internal-only /
|
|
24
|
+
test-only / docs-only (apply the `no-changelog` label).
|
|
24
25
|
|
|
25
26
|
<!-- AI-assisted contributions are welcome and normal here — see
|
|
26
27
|
CONTRIBUTING.md for the attribution convention (footer + Co-Authored-By). -->
|
|
@@ -14,19 +14,24 @@ jobs:
|
|
|
14
14
|
if: "!contains(github.event.pull_request.labels.*.name, 'no-changelog')"
|
|
15
15
|
|
|
16
16
|
steps:
|
|
17
|
-
- uses: actions/checkout@v6
|
|
17
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
|
18
18
|
with:
|
|
19
19
|
fetch-depth: 0
|
|
20
20
|
|
|
21
|
-
- name: Require
|
|
21
|
+
- name: Require changelog fragment when src/ changes
|
|
22
22
|
run: |
|
|
23
23
|
base="${{ github.event.pull_request.base.sha }}"
|
|
24
24
|
head="${{ github.event.pull_request.head.sha }}"
|
|
25
25
|
changed=$(git diff --name-only "$base...$head")
|
|
26
|
+
# Fragments must be *added* — a deleted or renamed fragment also
|
|
27
|
+
# appears in --name-only and must not satisfy the check.
|
|
28
|
+
added=$(git diff --name-only --diff-filter=A "$base...$head")
|
|
26
29
|
echo "Changed files:"
|
|
27
30
|
echo "$changed"
|
|
28
|
-
if echo "$changed" | grep -q '^src/'
|
|
29
|
-
|
|
31
|
+
if echo "$changed" | grep -q '^src/' \
|
|
32
|
+
&& ! echo "$added" | grep -Eq '^changelog\.d/[^/]+\.(breaking|added|changed|fixed)\.md$' \
|
|
33
|
+
&& ! echo "$changed" | grep -qx 'CHANGELOG.md'; then
|
|
34
|
+
echo "::error::This PR touches src/ but carries no changelog entry. Add a fragment changelog.d/<slug>.<breaking|added|changed|fixed>.md (see CONTRIBUTING.md), or apply the 'no-changelog' label if the change is internal-only."
|
|
30
35
|
exit 1
|
|
31
36
|
fi
|
|
32
37
|
echo "OK"
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -25,15 +25,17 @@ jobs:
|
|
|
25
25
|
os: [ubuntu-latest, macos-latest]
|
|
26
26
|
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@v6
|
|
28
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
|
29
|
+
with:
|
|
30
|
+
persist-credentials: false
|
|
29
31
|
|
|
30
32
|
- name: Setup Node.js
|
|
31
|
-
uses: actions/setup-node@v6
|
|
33
|
+
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
|
32
34
|
with:
|
|
33
35
|
node-version: 24
|
|
34
36
|
|
|
35
37
|
- name: Setup Bun
|
|
36
|
-
uses: oven-sh/setup-bun@v2
|
|
38
|
+
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
|
37
39
|
with:
|
|
38
40
|
bun-version: 1.3.14
|
|
39
41
|
|
|
@@ -15,15 +15,17 @@ jobs:
|
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@v6
|
|
18
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
|
19
|
+
with:
|
|
20
|
+
persist-credentials: false
|
|
19
21
|
|
|
20
22
|
- name: Setup Node.js
|
|
21
|
-
uses: actions/setup-node@v6
|
|
23
|
+
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
|
22
24
|
with:
|
|
23
25
|
node-version: 24
|
|
24
26
|
|
|
25
27
|
- name: Setup Bun
|
|
26
|
-
uses: oven-sh/setup-bun@v2
|
|
28
|
+
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
|
27
29
|
with:
|
|
28
30
|
bun-version: 1.3.14
|
|
29
31
|
|
|
@@ -51,7 +53,9 @@ jobs:
|
|
|
51
53
|
id-token: write
|
|
52
54
|
|
|
53
55
|
steps:
|
|
54
|
-
- uses: actions/checkout@v6
|
|
56
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
|
57
|
+
with:
|
|
58
|
+
persist-credentials: false
|
|
55
59
|
|
|
56
60
|
- name: Require changelog section for this release
|
|
57
61
|
run: |
|
|
@@ -63,7 +67,7 @@ jobs:
|
|
|
63
67
|
fi
|
|
64
68
|
|
|
65
69
|
- name: Setup Node.js
|
|
66
|
-
uses: actions/setup-node@v6
|
|
70
|
+
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
|
|
67
71
|
with:
|
|
68
72
|
# node 24 ships npm >= 11.5.1, required for OIDC publishing.
|
|
69
73
|
node-version: 24
|
|
@@ -91,7 +95,9 @@ jobs:
|
|
|
91
95
|
contents: write
|
|
92
96
|
|
|
93
97
|
steps:
|
|
94
|
-
- uses: actions/checkout@v6
|
|
98
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
|
|
99
|
+
with:
|
|
100
|
+
persist-credentials: false
|
|
95
101
|
|
|
96
102
|
- name: Mirror changelog section into release notes
|
|
97
103
|
env:
|
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,408 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
Entries land with the change that causes them, as fragment files in
|
|
4
|
+
[`changelog.d/`](changelog.d/) that are folded into a version section at
|
|
5
|
+
release time — see [CONTRIBUTING.md](CONTRIBUTING.md#changelog).
|
|
6
|
+
|
|
3
7
|
## Unreleased
|
|
4
8
|
|
|
9
|
+
## 0.8.0 — 2026-09-05
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Recipes accept `agent.proseRouting: "disabled"` for tool-only external publication when paired with a supporting Agent Framework release.
|
|
14
|
+
- **`modules.instructions`** — a shared living-instructions file (a CLAUDE.md
|
|
15
|
+
analogue kept in a workspace mount) injected into every agent's context on
|
|
16
|
+
every turn, ephemeral subagents included. `true` for defaults
|
|
17
|
+
(`instructions/AGENTS.md`, 32 KB cap, `system` position) or
|
|
18
|
+
`{ path, header, maxBytes, position }`. Reads resolve through the workspace
|
|
19
|
+
mount (scoping + traversal guard apply), are bounded to `maxBytes`, reject
|
|
20
|
+
symlinks leading outside the mount (realpath containment), are cached by
|
|
21
|
+
`(realpath, mtime, size)`, and fail open — a missing file never blocks
|
|
22
|
+
inference. Recipe validation cross-checks the path's mount prefix against
|
|
23
|
+
the effective workspace mounts (explicit and implicit alike) at load time,
|
|
24
|
+
requires `autoMaterialize: true` on a read-write instructions mount so
|
|
25
|
+
agent curation edits actually reach the disk-side injection, and rejects
|
|
26
|
+
the host-managed `_config` mount (it materializes only on branch-changing
|
|
27
|
+
commands). Validation and the runtime share one mount builder
|
|
28
|
+
(`src/workspace-mounts.ts`), so the two cannot drift.
|
|
29
|
+
|
|
30
|
+
- Recipes accept the default-off `agent.strategy.compressionSourceOnly` flag and pass it through to Context Manager's residence-scoped L1 compression request builder (#103).
|
|
31
|
+
|
|
32
|
+
- Gate telemetry stamps why the turn fired: `x-gate-origin` (heartbeat |
|
|
33
|
+
event | mail | operator | raw reason), `x-gate-channel` and
|
|
34
|
+
`x-gate-counterparty` (adapter-namespaced ids, never content or display
|
|
35
|
+
names) ride the stream lane under the same `GATE_TELEMETRY=1` + base-URL
|
|
36
|
+
gate as the debt stamp; background calls on the complete lane carry debt
|
|
37
|
+
only (#113).
|
|
38
|
+
|
|
39
|
+
- Gate-bound Anthropic calls carry an `x-gate-debt-chunks` header with the
|
|
40
|
+
live compression-debt pending-chunk count (membrane `dynamicHeaders`,
|
|
41
|
+
antra-tess/membrane#65) — the gateway records it per ledger row and strips
|
|
42
|
+
it before the vendor. Double-gated on `GATE_TELEMETRY=1` AND a configured
|
|
43
|
+
`ANTHROPIC_BASE_URL`, so the stamp can never reach a vendor endpoint;
|
|
44
|
+
unreadable state sends no header rather than a guess (#109).
|
|
45
|
+
|
|
46
|
+
- Health tab renders the per-agent compression-debt reduction (state, pending
|
|
47
|
+
chunks, oldest age, merge queue) and says "not reported by this stack" when
|
|
48
|
+
absent — the queue is now distinct from context composition, and the top
|
|
49
|
+
line reads "inference queued" (#110).
|
|
50
|
+
|
|
51
|
+
- Add complete fail-closed recipe validation and strategy passthrough for `foldingStrategy: "kv-unified"`; partial policies, invalid occupancy bands, unsafe approximation grids, and implicit treeification are rejected at load time.
|
|
52
|
+
|
|
53
|
+
- **`agent.provider: 'openai-compatible'`** — run an agent against any
|
|
54
|
+
OpenAI chat-completions endpoint (Ollama, vLLM, Together, Groq, NanoGPT,
|
|
55
|
+
...) via membrane's existing `OpenAICompatibleAdapter`, which no host ever
|
|
56
|
+
wired. The recipe names the endpoint (`agent.baseUrl`, validated as an
|
|
57
|
+
absolute http(s) URL at load) and the model (required — no default for an
|
|
58
|
+
arbitrary endpoint); the key comes from `OPENAI_COMPATIBLE_API_KEY`
|
|
59
|
+
only (no `OPENAI_API_KEY` fallback — `baseUrl` is recipe-controlled, so a
|
|
60
|
+
fallback would silently send a real OpenAI credential to an arbitrary
|
|
61
|
+
endpoint) and may be absent for local servers.
|
|
62
|
+
`agent.baseUrl` with any other provider is rejected at load time.
|
|
63
|
+
|
|
64
|
+
- Recipes can pass the Context Manager source-only compression controls through Host/FKM, including the new default-off L1 and merge final-fallback modes, with boolean validation and cross-agent isolation.
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- **`agent.cacheKeepalive` — hold an idle agent's 1h prompt cache warm.** With
|
|
69
|
+
`cacheTtl: "1h"`, an idle agent's cached prefix expires after an hour and its
|
|
70
|
+
next wake pays a **2x cache write** over the entire context. Reading an entry
|
|
71
|
+
restarts its clock, so membrane now replays the last request with
|
|
72
|
+
`max_tokens: 0` (prefill only) to refresh it at cache-**read** price (0.1x).
|
|
73
|
+
On by default for the anthropic provider; `{ "enabled": false }` opts out.
|
|
74
|
+
- **Cost is proportional to actual idleness, not to `maxIdleHours`.** A poke
|
|
75
|
+
fires only when the entry is genuinely near expiry, so a busy agent never
|
|
76
|
+
fires one — its own traffic already refreshed the TTL. Measured on mythos
|
|
77
|
+
llm-calls over 36h: 563 of 637 gaps were under 5 minutes, only 5 exceeded
|
|
78
|
+
1h.
|
|
79
|
+
- Knobs: `maxIdleHours` (default 24, measured from the last **real** request
|
|
80
|
+
so pokes cannot extend their own mandate) and `refreshAfterMinutes`
|
|
81
|
+
(default 45). Recipe validation **rejects `refreshAfterMinutes >= the cache
|
|
82
|
+
TTL`** — such a keepalive always fires after the entry has already expired,
|
|
83
|
+
paying a full cache write on every poke while still looking like a healthy
|
|
84
|
+
successful call.
|
|
85
|
+
- Events land in `service-stderr.log`, warn-level for `ineffective` and
|
|
86
|
+
`disabled`, so a background spender is legible without opening a billing
|
|
87
|
+
dashboard.
|
|
88
|
+
- Sizing, from fable-cm's 11-day log (~500k-token prefix): 49.7M tokens of
|
|
89
|
+
`cache_creation` landed on turns following a >1h idle gap — ~$944 of write
|
|
90
|
+
premium at fable-5 rates that this converts to ~$308 of reads.
|
|
91
|
+
|
|
92
|
+
- **`provider: "mock"` — run the whole host with zero provider spend and no
|
|
93
|
+
credentials.** Wires membrane's existing `MockAdapter` (previously
|
|
94
|
+
unreachable from any recipe) as a first-class provider: echoes the last
|
|
95
|
+
user message by default, or returns `agent.mock.defaultResponse` with
|
|
96
|
+
`agent.mock.echoMode: false` for deterministic scripted output. No API
|
|
97
|
+
key is required or read. Mock calls still ride the generic logging
|
|
98
|
+
decorator, so `llm-calls.*.jsonl` receipts work exactly as they do for
|
|
99
|
+
real providers. `recipes/mock-test.json` is a ready-made offline smoke
|
|
100
|
+
recipe (loopback webui, everything else off).
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
|
|
104
|
+
- **Hybrid prose routing.** Recipes may set `agent.proseRouting: "hybrid"`: unprefixed text keeps ordinary frozen-locus delivery, while a leading `>>>destination` publication envelope routes through Agent Framework’s existing authorized cross-surface resolver. Source text retains the envelope; recipients see only the body; success/failure returns to resident context.
|
|
105
|
+
|
|
106
|
+
- **`conversations` recipe block — per-channel conversation forks.** Maps to
|
|
107
|
+
agent-framework's `ConversationRouter`: the recipe's agent becomes a dormant
|
|
108
|
+
trunk template, and qualifying incoming channel messages spawn per-channel
|
|
109
|
+
fork agents seeded from the trunk's current context. Recipe surface: `bind` /
|
|
110
|
+
`trigger` rules per channel kind (`dm`/`groupDm`/`channel`), `idleTtlMs`
|
|
111
|
+
(default 12h), `closurePrompt`, and `agentPrefix`. The host fills
|
|
112
|
+
`templateAgent` from the recipe and creates a fresh stateful strategy instance
|
|
113
|
+
for each fork. Absent block means no routing and no behavior change.
|
|
114
|
+
|
|
115
|
+
- **Protective reaction-suppression baseline for Discord adapters.** Stdio
|
|
116
|
+
MCPL children now receive `DISCORD_SUPPRESSED_REACTIONS_BASELINE` — the
|
|
117
|
+
agent-framework's exported refusal-annotation set (`REFUSAL_REACTION_BASELINE`,
|
|
118
|
+
comma-joined) — so a never-configured Discord adapter defaults to
|
|
119
|
+
suppressing exactly the markers this host's framework stamps, instead of
|
|
120
|
+
defaulting to nothing. An operator-set value on the server entry
|
|
121
|
+
supersedes the house baseline, and the adapter's own precedence (filters-file
|
|
122
|
+
key including explicit `[]` → legacy operator env → baseline) governs
|
|
123
|
+
enforcement; lost configuration stays stale rather than re-defaulting.
|
|
124
|
+
Requires an agent-framework release carrying the `REFUSAL_REACTION_BASELINE`
|
|
125
|
+
export.
|
|
126
|
+
|
|
127
|
+
- **Standing autobiographical production target.** Recipes may set `agent.strategy.productionBudgetTokens` to keep the summary forest deep enough for a later live context-budget descent without a fold storm. This is a context-token target passed through to Context Manager, not a provider-spend ceiling; omission preserves Context Manager defaults.
|
|
128
|
+
|
|
129
|
+
- **`mcpl_list` reports manifest freshness.** Each loaded server now shows the
|
|
130
|
+
last validated manifest revision plus fetch and grant-negotiation timestamps.
|
|
131
|
+
Older Agent Framework versions remain legible as `manifest=unknown`, and the
|
|
132
|
+
server-authored revision is quoted and bounded before reaching model-facing
|
|
133
|
+
text.
|
|
134
|
+
|
|
135
|
+
- **`BEDROCK_BASE_URL` env hook** for the bedrock provider — mirrors
|
|
136
|
+
`ANTHROPIC_BASE_URL`, routing bedrock-runtime calls through an inference
|
|
137
|
+
gateway (gate.animalabs.ai/bedrock/<credSet>). The gate reads the agent
|
|
138
|
+
token from the SigV4 Credential (`AWS_ACCESS_KEY_ID` slot), discards the
|
|
139
|
+
client signature, and re-signs with real AWS creds. First user: Princess,
|
|
140
|
+
moved off the first-party Anthropic API (classifier "bio" false-positive
|
|
141
|
+
streak) onto Bedrock Sonnet 4.5 via gate apse1 — needs membrane ≥1dcd4e3
|
|
142
|
+
for `global.` inference-profile id pass-through.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- **Dependency floor: agent-framework `^0.10.0`, chronicle `^0.3.0`,
|
|
147
|
+
membrane `^0.5.78`.** af 0.10.0 brings `ConversationRouter` (the
|
|
148
|
+
per-channel conversation-fork machinery this release’s `conversations`
|
|
149
|
+
recipe surface targets, and includes the current `hybrid` prose router) and exports `nudgeAgent`, which `/nudge` has
|
|
150
|
+
called since it landed — on every published af before 0.9.0 that call
|
|
151
|
+
was a guaranteed `TypeError`, so the floor also makes `/nudge` actually
|
|
152
|
+
work. Chronicle `^0.3.0` aligns the whole tree on one chronicle copy
|
|
153
|
+
(previously context-manager `0.6.3` nested its own `0.3.0` next to the
|
|
154
|
+
host's `0.2.x`). Operators: run a clean `npm ci` — a stale
|
|
155
|
+
`node_modules` predating the lock is the known failure mode here.
|
|
156
|
+
|
|
157
|
+
- **The public triumvirate recipes boot from a fresh clone.**
|
|
158
|
+
`knowledge-miner.json` no longer ships a `syncntn` (Notion) block pointing at
|
|
159
|
+
an org-internal adapter that isn't publicly available — with `NOTION_*` env
|
|
160
|
+
vars unset the block failed recipe load, and with them set it died at spawn
|
|
161
|
+
on the dangling `../syncntn` path. The `scribe` block is dropped for the
|
|
162
|
+
same reason: it hard-required `GEMINI_API_KEY` and a `../scribe-mcp`
|
|
163
|
+
sibling checkout, neither mentioned anywhere in the setup guides — a
|
|
164
|
+
guide-following fresh install always got a crashed miner. Notion and
|
|
165
|
+
Scribe are now add-a-block opt-ins, documented in SETUP.md and
|
|
166
|
+
TRIUMVIRATE-SETUP.md (the miner prompt's tool-name contracts are
|
|
167
|
+
unchanged). `triumvirate.json` declares
|
|
168
|
+
webui Basic-Auth defaulting to `admin`/`admin` (override via
|
|
169
|
+
`WEBUI_USERNAME` / `WEBUI_PASSWORD` in `.env`) instead of bare
|
|
170
|
+
`"webui": true`, which the non-loopback bind guard refuses to start.
|
|
171
|
+
|
|
172
|
+
- **agent-framework `^0.11.0`** (was `^0.10.0`). Activates `proseRouting:
|
|
173
|
+
"disabled"` for recipes that set it (#100 accepted the key; the runtime now
|
|
174
|
+
implements it — generated prose is never published externally, only explicit
|
|
175
|
+
tools speak), plus AF 0.11's Windows workspace-mount fix and the
|
|
176
|
+
org-acceleration 429 cooldown. Clears the last two standing cross-package
|
|
177
|
+
`tsc` errors — the typecheck is fully clean at this lock.
|
|
178
|
+
|
|
179
|
+
- Changelog entries now land as per-change fragment files in `changelog.d/`
|
|
180
|
+
(`<slug>.<breaking|added|changed|fixed>.md`), folded into the version
|
|
181
|
+
section at release time — concurrent PRs no longer conflict in
|
|
182
|
+
`CHANGELOG.md`. Editing `## Unreleased` directly still works and is merged
|
|
183
|
+
at the same point.
|
|
184
|
+
|
|
185
|
+
- **membrane `^0.5.80`** (was `^0.5.78`, lockfile-resolved 0.5.79). Two
|
|
186
|
+
latent cache behaviors the host already configures become ACTIVE with this
|
|
187
|
+
relock: the prompt-cache keepalive (`agent.cacheKeepalive`, on by default —
|
|
188
|
+
previously passed to an adapter version with no such field and silently
|
|
189
|
+
ignored, so idle gaps over the 1h TTL repaid a full cache write on wake)
|
|
190
|
+
and the floating cache marker (incremental prompt caching inside the native
|
|
191
|
+
tool loop, membrane's default-on). Both reduce cost; neither changes
|
|
192
|
+
visible agent behavior. Also clears two of the four standing cross-package
|
|
193
|
+
`tsc` errors (the membrane-typing pair).
|
|
194
|
+
|
|
195
|
+
- Depend on `@animalabs/agent-framework` ^0.12.0 and `@animalabs/membrane` ^0.5.82 —
|
|
196
|
+
the published versions that implement the active-turn trigger and the
|
|
197
|
+
lane-aware `dynamicHeaders` the wake-cause stamp (#113) relies on; the
|
|
198
|
+
compatibility cast and optional lookup are gone, and an adapter-level test
|
|
199
|
+
proves a stream call carries the origin trio while a complete call carries
|
|
200
|
+
debt only.
|
|
201
|
+
|
|
202
|
+
### Fixed
|
|
203
|
+
|
|
204
|
+
- **Prompt-cache keepalive events all go to stderr**, so every one of them lands
|
|
205
|
+
in `service-stderr.log` beside `[inference-refusal]` instead of being split by
|
|
206
|
+
severity across two sinks. Routine `refreshed` events previously went to
|
|
207
|
+
stdout — which the host unit leaves on the journal — so the log an operator
|
|
208
|
+
actually greps showed nothing. Observed on fable-cm 2026-08-23: the keepalive
|
|
209
|
+
refreshed a 523,102-token prefix three times, correctly and with zero cache
|
|
210
|
+
writes, while a monitor tailing `service-stderr.log` reported no activity for
|
|
211
|
+
three hours. A background spender that can't be found in the operator's log is
|
|
212
|
+
indistinguishable from one that never ran.
|
|
213
|
+
|
|
214
|
+
- Plumb `agent.strategy.compressionRecallBudgetTokens` through recipe validation and Framework strategy construction, with positive-integer validation instead of silently accepting an inert key.
|
|
215
|
+
|
|
216
|
+
- **Saved recipe snapshots no longer contain resolved secrets.** `loadRecipe`
|
|
217
|
+
substitutes every `${VAR}` — API tokens included — and the host then wrote
|
|
218
|
+
that fully resolved recipe to `$DATA_DIR/.recipe.json` at default file mode:
|
|
219
|
+
plaintext credentials in the exact directory deployments bind-mount and back
|
|
220
|
+
up (found by an external recipe review that verified live tokens in a backed
|
|
221
|
+
up `data/` directory on a production VM). The snapshot now keeps the
|
|
222
|
+
pre-substitution form — `${VAR}` references literal, a URL `systemPrompt`
|
|
223
|
+
kept as the URL — and a resumed session re-runs substitution, validation,
|
|
224
|
+
and the prompt fetch against the *current* environment, so secret rotation
|
|
225
|
+
and remote prompt updates take effect on restart without re-cooking. The
|
|
226
|
+
file is written 0600 and re-chmod'd 0600 on every save. Legacy resolved
|
|
227
|
+
snapshots (no `$unresolved` marker) still load verbatim, with no
|
|
228
|
+
substitution, so a literal `${...}` surviving in prose cannot fail them;
|
|
229
|
+
resuming an unresolved snapshot whose required env var has since disappeared
|
|
230
|
+
fails loudly naming the variable instead of silently starting the default
|
|
231
|
+
recipe.
|
|
232
|
+
|
|
233
|
+
- **Ephemeral subagents inherit the caller's `proseRouting` mode.** They
|
|
234
|
+
previously always ran AF's `'locus'` default regardless of the recipe, so a
|
|
235
|
+
resident running `proseRouting: "disabled"` still spawned subagents whose
|
|
236
|
+
between-tool-calls prose published live into its open channel as parent
|
|
237
|
+
speech (field-confirmed on a deployed resident, 2026-08-26 — including
|
|
238
|
+
after the recipe adopted `"disabled"`, which reached only the resident).
|
|
239
|
+
|
|
240
|
+
### Fixed
|
|
241
|
+
|
|
242
|
+
- **`mcpServers.<id>.source` accepts cook's npm registry form.**
|
|
243
|
+
`validateRecipe` demanded `source.url`, but connectome-cook's source grammar
|
|
244
|
+
also has `{ "npm": "pkg@version" }` — which the shipped knowledge-miner
|
|
245
|
+
recipe uses for its gitlab server, so that recipe failed to load
|
|
246
|
+
(`mcpServers.gitlab.source.url must be a non-empty string`). Exactly one of
|
|
247
|
+
`url` / `npm` is now required; the field remains build-tooling metadata,
|
|
248
|
+
ignored at runtime.
|
|
249
|
+
|
|
250
|
+
## 0.7.4 — 2026-08-03
|
|
251
|
+
|
|
252
|
+
### Changed
|
|
253
|
+
|
|
254
|
+
- **Frontdesk agents ride the adaptive path.** `frontdesk` strategies now
|
|
255
|
+
default to adaptive resolution + kv-stable folding, same as
|
|
256
|
+
`autobiographical` (a recipe can pin `adaptiveResolution: false` to keep the
|
|
257
|
+
old hierarchical renderer). The hierarchical renderer reserves nothing for
|
|
258
|
+
the raw tail and cannot shed summary mass, so a long-lived frontdesk agent
|
|
259
|
+
eventually saturates its fixed context budget into a terminal
|
|
260
|
+
`UncoveredDropError` refusal loop — the 2026-08-03 boter clerk outage.
|
|
261
|
+
Details and deltas:
|
|
262
|
+
- Topic-aware chunking now rides context-manager's `chunkBoundaryHint` seam
|
|
263
|
+
(requires CM ≥0.6.3) instead of a fork of `rebuildChunks` that silently
|
|
264
|
+
bypassed chunk-record persistence and the fail-closed orphan guard.
|
|
265
|
+
- Existing frontdesk stores carry no chunk records (the fork never wrote
|
|
266
|
+
them); context-manager's `migrateChunkRecords` backfills them from L1
|
|
267
|
+
`sourceIds` on first load, so upgraded stores do not re-compress lived
|
|
268
|
+
history. First boot re-plans folds (one-time KV churn, possibly a burst of
|
|
269
|
+
L1 production for the un-summarized frontier).
|
|
270
|
+
- The salience-biased L1 emission order is retired (it was a hierarchical-
|
|
271
|
+
renderer concept); unanswered questions/@mentions are still preserved
|
|
272
|
+
verbatim through the compression prompt.
|
|
273
|
+
- Witnessed chunks now get the base witnessed compression prompt; the fork
|
|
274
|
+
predated witnessed prompts and overrode them.
|
|
275
|
+
|
|
276
|
+
### Added
|
|
277
|
+
|
|
278
|
+
- **Every WebUI inspection panel now works per fleet child.** One persistent
|
|
279
|
+
scope dropdown in the sidebar header ("inspecting: …") replaces the
|
|
280
|
+
per-tab pill rows Lessons/Files carried — MCPL, Context, Settings, Pins,
|
|
281
|
+
Health, and the main-pane Context document all follow it, instead of the
|
|
282
|
+
previous split where only Lessons/Files could switch (statefully, via
|
|
283
|
+
duplicated pickers), Context 404'd by mis-sending the child name as an
|
|
284
|
+
`?agent=` param, and MCPL/Settings/Pins/Health were silently locked to the
|
|
285
|
+
fleetmaster. Backed by one generic fleet IPC verb pair
|
|
286
|
+
(`panel-request`/`panel-response`) dispatching into a shared panel layer
|
|
287
|
+
(`src/web/panel-data.ts`) that both the WebUI host and headless children
|
|
288
|
+
run — a new panel op needs no protocol change to work fleet-wide.
|
|
289
|
+
Details:
|
|
290
|
+
- `/debug/context/{,makeup,coverage,curve,preview,maintenance}` and
|
|
291
|
+
`/healthz` accept `?scope=<child>` — the host proxies to the child over
|
|
292
|
+
the fleet IPC and answers with its JSON verbatim (still curl-able;
|
|
293
|
+
connectome-doctor / fleet hub can now watch children through the host).
|
|
294
|
+
`/curve?scope=<child>` passes through to the scoped JSON.
|
|
295
|
+
- The MCPL tab shows the scoped process's **live** loaded servers
|
|
296
|
+
(connection status, tool counts — the long-missing fleet mcpl snapshot)
|
|
297
|
+
above the shared registry file; registry edits stay host-scope (the
|
|
298
|
+
file is one cwd-shared registry, so a "child-local edit" would be a
|
|
299
|
+
lie) and the panel says so instead of hiding the fact.
|
|
300
|
+
- Settings mutations, dry-run previews (single-flight guard now lives in
|
|
301
|
+
the target process), and pin add/remove run inside the scoped child;
|
|
302
|
+
child pins snapshots ship picker candidates (real store ids) since the
|
|
303
|
+
SPA has no window into a child's message store.
|
|
304
|
+
- Scoped WS responses (`lessons-list`, `workspace-*`, `mcpl-list`,
|
|
305
|
+
`settings-state`, `pins-list`) now echo their `scope`, and the SPA
|
|
306
|
+
drops replies that arrive after the operator switched — fixing a
|
|
307
|
+
pre-existing race where a slow child's lessons/files could render under
|
|
308
|
+
another child's header.
|
|
309
|
+
- Child health snapshots include the child's recent provider-call ledger.
|
|
310
|
+
- **TUI: context budget gauge.** The status bar's `ctx:` readout and the fleet
|
|
311
|
+
tree's per-agent readouts show `142k/180k` against the *live* runtime budget
|
|
312
|
+
(runtime overrides win over the recipe), and the status segment goes yellow at
|
|
313
|
+
75% / red at 90% — "how close to compression/trouble" at a glance instead of a
|
|
314
|
+
bare number.
|
|
315
|
+
- **TUI: fleet view viewport.** The tree now scrolls with the cursor
|
|
316
|
+
(`┈ N lines above/below ┈` markers) instead of clipping past the bottom of the
|
|
317
|
+
terminal — previously a large fleet let the cursor walk below the fold and
|
|
318
|
+
Del:stop targeted rows the operator couldn't see.
|
|
319
|
+
- **TUI: fleet view opens with a summary header** — agent counts
|
|
320
|
+
(running/done/failed/cancelled across local subagents *and* fleet children),
|
|
321
|
+
children up/crashed, session cost — plus the active ops alerts in full (the
|
|
322
|
+
status bar only has room for a count).
|
|
323
|
+
- **TUI: event timestamps.** Alerts, tool batches, subagent results, wake
|
|
324
|
+
triggers, branch switches, errors and user messages get an `HH:MM` prefix, so
|
|
325
|
+
scrollback read an hour later still answers "when".
|
|
326
|
+
- **TUI: root-agent tool completions are visible.** Verbose shows every
|
|
327
|
+
`✓ tool (1.2s)`; terse shows the slow ones (≥2s). Slow *running* tools show a
|
|
328
|
+
live elapsed in the status bar after 5s — "still executing" and "stuck" no
|
|
329
|
+
longer look identical.
|
|
330
|
+
- **TUI: the status bar names the worst active alert** (`⚠ 2 ·
|
|
331
|
+
compression-quarantine`), with quarantine and inference-exhausted outranking
|
|
332
|
+
the merely-recent.
|
|
333
|
+
|
|
334
|
+
### Changed
|
|
335
|
+
|
|
336
|
+
- **TUI: thinking honors the Ctrl+V verbose toggle.** Terse mode collapses live
|
|
337
|
+
thinking to a counting one-liner (`💭 thinking… ~1.2k tok`) and replayed
|
|
338
|
+
history thinking to one truncated line per block — the toggle's label always
|
|
339
|
+
claimed this.
|
|
340
|
+
- **TUI: session-history replay caps at the last 50 messages** (marker points at
|
|
341
|
+
the web UI for the rest) instead of flooding scrollback with the whole session.
|
|
342
|
+
- **TUI: elapsed times are humane everywhere** — `5m48s`, not `348s`; the fleet
|
|
343
|
+
tree and both peek views now agree.
|
|
344
|
+
- **TUI: peek-proc renders child `ops:alert` events properly** (red `⚠ kind:
|
|
345
|
+
message`, cyan for `-clear`) instead of a dim `· ops:alert` dot line, and no
|
|
346
|
+
longer prints dot lines for per-block/per-round bookkeeping events.
|
|
347
|
+
- **TUI: the status-left segment truncates to fit** the terminal width instead of
|
|
348
|
+
shoving the tokens/mem segment off the row.
|
|
349
|
+
|
|
350
|
+
### Fixed
|
|
351
|
+
|
|
352
|
+
- `cancel-subagent-result` was missing from the headless runtime's
|
|
353
|
+
subscription-filter exemptions: a parent that narrowed the event stream
|
|
354
|
+
could never see its own cancel confirmations.
|
|
355
|
+
- The Vite dev server proxies `/debug`, `/healthz`, `/curve`, and `/files`
|
|
356
|
+
to the running host — previously every HTTP panel fetch 404'd under
|
|
357
|
+
`bun run dev`.
|
|
358
|
+
- **TUI: "Branch switched" announcements survive.** The line was printed *before*
|
|
359
|
+
`refreshFromStore()` cleared the scrollbox, so it was destroyed unread.
|
|
360
|
+
|
|
361
|
+
### Upgrade notes
|
|
362
|
+
|
|
363
|
+
- **subagents/lessons/retrieval are now opt-in** (they were opt-out, and
|
|
364
|
+
DEFAULT_RECIPE enabled all three). A recipe that omits them ran them under
|
|
365
|
+
v0.7.2 and stops running them on this upgrade — that is the fix for
|
|
366
|
+
"lessons injected despite following the onboarding guide" (Discord issue
|
|
367
|
+
#32) working as intended. A recipe that *explicitly* enables them keeps
|
|
368
|
+
them, deliberately: a defaults change cannot tell old boilerplate from a
|
|
369
|
+
real choice. Before upgrading an existing deployment, run
|
|
370
|
+
|
|
371
|
+
bun scripts/audit-module-optins.ts <recipes-and-data-dirs...>
|
|
372
|
+
|
|
373
|
+
It reports every explicit enable, every omission that changes behavior,
|
|
374
|
+
and every retrieval-without-lessons combination that would go silently
|
|
375
|
+
inert — and modifies nothing; the decisions stay with the operator.
|
|
376
|
+
Persisted `data/.recipe.json` files are launch-time snapshots, not
|
|
377
|
+
authoritative sources — the audit lists them separately as pointers back
|
|
378
|
+
to the source recipe. Retrieved-lesson injection also moved from the
|
|
379
|
+
system prompt to after the last user message, which keeps the stable
|
|
380
|
+
prefix KV-cacheable.
|
|
381
|
+
|
|
382
|
+
### Added
|
|
383
|
+
|
|
384
|
+
- **Operator retrieval traces.** The Web UI now exposes operator-only,
|
|
385
|
+
process-memory retrieval traces at `/debug/retrieval` and a readable
|
|
386
|
+
lesson-selection viewer at `/debug/retrieval/view`, including invoking-agent
|
|
387
|
+
attribution, mechanical candidates, relevance decisions, cache provenance,
|
|
388
|
+
and the exact injected lesson block. Exact conversation/model inputs remain
|
|
389
|
+
opt-in via literal `includeInputs=1`.
|
|
390
|
+
|
|
391
|
+
### Fixed
|
|
392
|
+
|
|
393
|
+
- **OpenAI retrieval reasoning effort.** Recipes using `openai-responses` or
|
|
394
|
+
`openai-codex` can set `modules.retrieval.reasoningEffort` independently of
|
|
395
|
+
the primary agent. Unsupported providers fail recipe validation instead of
|
|
396
|
+
receiving an invalid OpenAI-shaped request, and reasoning-enabled retrieval
|
|
397
|
+
requires an explicit model instead of falling through to the Claude default.
|
|
398
|
+
|
|
399
|
+
- **`mcpl_list` reports the live MCPL policy boundary.** Each server now shows
|
|
400
|
+
connected/retrying state, whether its initial policy was established, its
|
|
401
|
+
effective grant, host-masked and deny-by-default capability paths, and the
|
|
402
|
+
separate host-owned `host/command` authority. During a rolling upgrade,
|
|
403
|
+
fields unavailable from an older agent-framework render as `unknown` rather
|
|
404
|
+
than as a misleading empty grant.
|
|
405
|
+
|
|
5
406
|
## 0.7.3 — 2026-08-01
|
|
6
407
|
|
|
7
408
|
### Changed
|
|
@@ -68,8 +469,6 @@
|
|
|
68
469
|
write, output, breakpoints, duration and verdict, with refusals and errors
|
|
69
470
|
highlighted. Cumulative totals for the session remain in the Usage panel.
|
|
70
471
|
|
|
71
|
-
## Unreleased
|
|
72
|
-
|
|
73
472
|
## 0.7.0 — 2026-07-26
|
|
74
473
|
|
|
75
474
|
### Added
|
|
@@ -89,8 +488,6 @@
|
|
|
89
488
|
`/debug/context/makeup` this costs nothing and makes no `count_tokens` network
|
|
90
489
|
call, so it is safe on the 15s health poll.
|
|
91
490
|
|
|
92
|
-
## Unreleased
|
|
93
|
-
|
|
94
491
|
## 0.6.1 — 2026-07-26
|
|
95
492
|
|
|
96
493
|
### Fixed
|
|
@@ -105,8 +502,6 @@
|
|
|
105
502
|
text/id filter. Caught by checking the endpoint against a real store before
|
|
106
503
|
anyone used the panel.
|
|
107
504
|
|
|
108
|
-
## Unreleased
|
|
109
|
-
|
|
110
505
|
## 0.6.0 — 2026-07-26
|
|
111
506
|
|
|
112
507
|
### Added
|
|
@@ -170,8 +565,6 @@
|
|
|
170
565
|
measured cost, and notes runs are serialized so a second click is refused
|
|
171
566
|
rather than queueing another pause.
|
|
172
567
|
|
|
173
|
-
## Unreleased
|
|
174
|
-
|
|
175
568
|
## 0.5.3 — 2026-07-26
|
|
176
569
|
|
|
177
570
|
### Added
|
|
@@ -294,8 +687,6 @@
|
|
|
294
687
|
- `compressionMaxTokens` recipe passthrough — cap compression output for
|
|
295
688
|
models with low output ceilings (2c78936).
|
|
296
689
|
|
|
297
|
-
## Unreleased
|
|
298
|
-
|
|
299
690
|
### Fixed
|
|
300
691
|
|
|
301
692
|
- **TUI bug sweep** (#64): operator-safety and observability fixes.
|