@animalabs/connectome-host 0.3.9 → 0.3.10
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 +7 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +26 -0
- package/.github/workflows/changelog.yml +32 -0
- package/.github/workflows/publish.yml +46 -0
- package/CHANGELOG.md +59 -0
- package/CONTRIBUTING.md +126 -0
- package/README.md +52 -5
- package/package.json +2 -1
- package/scripts/release-changelog.ts +32 -0
- package/src/codex-subscription-adapter.ts +938 -0
- package/src/commands.ts +45 -0
- package/src/extensions.ts +201 -0
- package/src/framework-agent-config.ts +17 -9
- package/src/framework-strategy.ts +21 -0
- package/src/index.ts +102 -19
- package/src/logging-bedrock-adapter.ts +145 -0
- package/src/modules/web-ui-module.ts +45 -1
- package/src/recipe.ts +138 -9
- package/src/tui.ts +165 -34
- package/src/web/protocol.ts +35 -0
- package/test/codex-subscription-adapter.test.ts +226 -0
- package/test/fast-command.test.ts +39 -0
- package/test/recipe-extensions.test.ts +295 -0
- package/test/recipe-provider.test.ts +14 -1
- package/test/web-ui-observers.test.ts +14 -0
- package/test/web-ui-protocol.test.ts +0 -0
- package/web/src/App.tsx +235 -20
- package/web/src/Branches.tsx +150 -0
- package/web/src/Context.tsx +21 -13
- package/web/src/Health.tsx +274 -0
- package/web/src/Lessons.tsx +2 -1
package/.env.example
CHANGED
|
@@ -7,6 +7,13 @@ ANTHROPIC_API_KEY=sk-ant-...
|
|
|
7
7
|
# OPENAI_API_KEY=sk-...
|
|
8
8
|
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
9
9
|
|
|
10
|
+
# For recipes with agent.provider="openai-codex" (ChatGPT subscription):
|
|
11
|
+
# Install the Codex CLI and sign in with ChatGPT. If no login exists,
|
|
12
|
+
# connectome-host will show a device-code login on the first model call.
|
|
13
|
+
# CODEX_BINARY=codex
|
|
14
|
+
# CODEX_HOME=/absolute/path/to/.codex
|
|
15
|
+
# CODEX_BASE_URL=https://chatgpt.com/backend-api/codex
|
|
16
|
+
|
|
10
17
|
# --- Recipe ${VAR} substitutions ---------------------------------------
|
|
11
18
|
# Recipes in recipes/ reference these via ${VAR}. Unset = that branch of
|
|
12
19
|
# the recipe fails to load; remove the referencing mcpServers block from
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## Problem
|
|
2
|
+
|
|
3
|
+
<!-- What is wrong / missing, and for whom. Link the issue if one exists. -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- What this PR does. For cross-repo or stacked work, list companion PRs
|
|
8
|
+
and merge-order guidance ("safe in either order because…"). -->
|
|
9
|
+
|
|
10
|
+
## Tests
|
|
11
|
+
|
|
12
|
+
<!-- Evidence, not assertion: paste the numbers.
|
|
13
|
+
e.g. `bun test`: 342 pass / 2 fail — failure count identical to main baseline. -->
|
|
14
|
+
|
|
15
|
+
## Not verified
|
|
16
|
+
|
|
17
|
+
<!-- Anything you did not exercise (live integrations, platforms, migration
|
|
18
|
+
paths). "Nothing — verified end-to-end" is a fine answer; silence is not. -->
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
- [ ] `CHANGELOG.md` updated under `## Unreleased` — or this change is
|
|
23
|
+
internal-only / test-only / docs-only (apply the `no-changelog` label).
|
|
24
|
+
|
|
25
|
+
<!-- AI-assisted contributions are welcome and normal here — see
|
|
26
|
+
CONTRIBUTING.md for the attribution convention (footer + Co-Authored-By). -->
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Changelog
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
changelog-entry:
|
|
12
|
+
name: Changelog entry present
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
if: "!contains(github.event.pull_request.labels.*.name, 'no-changelog')"
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0
|
|
20
|
+
|
|
21
|
+
- name: Require CHANGELOG.md update when src/ changes
|
|
22
|
+
run: |
|
|
23
|
+
base="${{ github.event.pull_request.base.sha }}"
|
|
24
|
+
head="${{ github.event.pull_request.head.sha }}"
|
|
25
|
+
changed=$(git diff --name-only "$base...$head")
|
|
26
|
+
echo "Changed files:"
|
|
27
|
+
echo "$changed"
|
|
28
|
+
if echo "$changed" | grep -q '^src/' && ! echo "$changed" | grep -qx 'CHANGELOG.md'; then
|
|
29
|
+
echo "::error::This PR touches src/ but not CHANGELOG.md. Add an entry under 'Unreleased' (see CONTRIBUTING.md), or apply the 'no-changelog' label if the change is internal-only."
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
echo "OK"
|
|
@@ -53,6 +53,15 @@ jobs:
|
|
|
53
53
|
steps:
|
|
54
54
|
- uses: actions/checkout@v6
|
|
55
55
|
|
|
56
|
+
- name: Require changelog section for this release
|
|
57
|
+
run: |
|
|
58
|
+
ver="${GITHUB_REF_NAME#v}"
|
|
59
|
+
esc=$(printf '%s' "$ver" | sed 's/[.]/\\./g')
|
|
60
|
+
if ! grep -Eq "^## ${esc}([^0-9]|$)" CHANGELOG.md; then
|
|
61
|
+
echo "::error::CHANGELOG.md has no '## ${ver}' section for tag ${GITHUB_REF_NAME}. Retitle the Unreleased section before tagging (see CONTRIBUTING.md)."
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
|
|
56
65
|
- name: Setup Node.js
|
|
57
66
|
uses: actions/setup-node@v6
|
|
58
67
|
with:
|
|
@@ -68,3 +77,40 @@ jobs:
|
|
|
68
77
|
|
|
69
78
|
- name: Publish
|
|
70
79
|
run: npm publish --access public --provenance
|
|
80
|
+
|
|
81
|
+
github-release:
|
|
82
|
+
name: GitHub release notes
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
needs: build-and-test
|
|
85
|
+
# Deliberately independent of the npm publish job: some consumers run
|
|
86
|
+
# github-clone checkouts, and release notes must exist even when npm
|
|
87
|
+
# publish fails — the two jobs succeed or fail on their own.
|
|
88
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
89
|
+
|
|
90
|
+
permissions:
|
|
91
|
+
contents: write
|
|
92
|
+
|
|
93
|
+
steps:
|
|
94
|
+
- uses: actions/checkout@v6
|
|
95
|
+
|
|
96
|
+
- name: Mirror changelog section into release notes
|
|
97
|
+
env:
|
|
98
|
+
GH_TOKEN: ${{ github.token }}
|
|
99
|
+
run: |
|
|
100
|
+
ver="${GITHUB_REF_NAME#v}"
|
|
101
|
+
# Section header is '## X.Y.Z — YYYY-MM-DD'; match the version
|
|
102
|
+
# field exactly (string compare, no regex escaping needed).
|
|
103
|
+
awk -v ver="$ver" '
|
|
104
|
+
/^## / { if (in_section) exit; if ($2 == ver) { in_section = 1; next } }
|
|
105
|
+
in_section { print }
|
|
106
|
+
' CHANGELOG.md | sed '/./,$!d' > notes.md
|
|
107
|
+
if ! [ -s notes.md ]; then
|
|
108
|
+
echo "::error::No CHANGELOG.md section found for ${ver}."
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
|
|
112
|
+
gh release edit "$GITHUB_REF_NAME" --notes-file notes.md
|
|
113
|
+
else
|
|
114
|
+
gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" \
|
|
115
|
+
--notes-file notes.md --verify-tag
|
|
116
|
+
fi
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.3.10 — 2026-07-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Provider transports**: `provider: "bedrock"` for legacy Claude models
|
|
10
|
+
(3.5 Sonnet 0620/1022, Opus 3) surviving on AWS APAC after Anthropic API
|
|
11
|
+
retirement — AWS_* env credentials, model-ID mapping via membrane, prompt
|
|
12
|
+
caching forced off (legacy models reject `cache_control`; verified live).
|
|
13
|
+
`provider: "openai-codex"` (ChatGPT subscription, device-code login,
|
|
14
|
+
`/fast` toggle) and `provider: "openrouter"` formalized with validation.
|
|
15
|
+
- **Bedrock wire logging**: `LoggingBedrockAdapter` writes
|
|
16
|
+
`llm-calls.<iso>.jsonl` on the bedrock path — tool names per request,
|
|
17
|
+
stop_reason + block shapes per response, raw request retained on errors.
|
|
18
|
+
- **Prefill-era bot migration**: recipe `agent.formatter: "anthropic-xml"`
|
|
19
|
+
(membrane classic prefill) + `agent.prefillUserMessage` scaffold — together
|
|
20
|
+
reproduce a chapterx borg's exact prompting structure inside a resident
|
|
21
|
+
(first used for the Supreme Sonnet isekai, 2026-07-21).
|
|
22
|
+
|
|
23
|
+
- Contribution policy: `CONTRIBUTING.md` (how changes land, review process,
|
|
24
|
+
AI-attribution convention, changelog rules — binding for PRs and direct
|
|
25
|
+
pushes, humans and AIs alike) and a PR template.
|
|
26
|
+
- CI `changelog` check: PRs touching `src/` must also touch `CHANGELOG.md`,
|
|
27
|
+
opt out with the `no-changelog` label. The publish workflow now refuses to
|
|
28
|
+
release a `vX.Y.Z` tag with no matching `## X.Y.Z` changelog section.
|
|
29
|
+
- Release mechanics automated: `npm version <level>` cuts `Unreleased` into
|
|
30
|
+
`## X.Y.Z — date` via the `version` hook (`scripts/release-changelog.ts`),
|
|
31
|
+
and on release tags CI creates the GitHub release with that section as
|
|
32
|
+
its notes — independent of the npm publish job, so notes exist for
|
|
33
|
+
github-clone consumers even when a publish fails.
|
|
34
|
+
- **Web UI observability catch-up**: `ops:alert` traces render as persistent
|
|
35
|
+
banner rows in the SPA (compression quarantine, refusal streaks,
|
|
36
|
+
inference-exhausted; `<kind>-clear` stands them down); a Health sidebar tab
|
|
37
|
+
polls `/healthz` for per-agent status, failure streaks, refusal stats,
|
|
38
|
+
runtime settings, and quarantine, and reconciles durable-state alerts on
|
|
39
|
+
connect. New protocol frames `request-branches`/`branches-list` back a
|
|
40
|
+
Chronicle branch-lineage panel opened from the header branch chip, with
|
|
41
|
+
checkout via the existing `/checkout` command path (read-only for
|
|
42
|
+
observers; listing rides the `messages` scope). The `/curve` link now
|
|
43
|
+
lives in the Context panel header.
|
|
44
|
+
- **TUI modernization**: `p` on an agent inside a fleet child opens an
|
|
45
|
+
honest per-agent peek — the child's event stream filtered by `agentName`,
|
|
46
|
+
covering the child's root agent and its subagents (sub-subagents of the
|
|
47
|
+
parent), with phase/tokens/task header from the tree reducer. `ops:alert`
|
|
48
|
+
traces from the local framework AND from every fleet child surface as red
|
|
49
|
+
chat lines plus a persistent `⚠ N alerts` status-bar segment; all-clears
|
|
50
|
+
stand alerts down. The token line now shows the session cost estimate
|
|
51
|
+
when priced.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- Dead `PlaceholderPanel` removed from the SPA; stale doc pointers
|
|
56
|
+
(`WEBUI-PLAN.md`, knowledge-miner references) corrected; README now
|
|
57
|
+
documents the web UI, headless mode, and current TUI peek semantics.
|
|
58
|
+
|
|
59
|
+
## 0.3.2 — 2026-07-14
|
|
60
|
+
|
|
61
|
+
Retro-filed: 0.3.1–0.3.9 predate the changelog policy and were released
|
|
62
|
+
without cutting this file; only the entry below was recorded at the time.
|
|
63
|
+
|
|
5
64
|
### Breaking (recipe authors only)
|
|
6
65
|
|
|
7
66
|
- `modules.fleet.children[].recipe` paths now resolve at recipe-load time
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Contributing to connectome-host
|
|
2
|
+
|
|
3
|
+
connectome-host is part of the Connectome ecosystem
|
|
4
|
+
([agent-framework](https://github.com/anima-research/agent-framework),
|
|
5
|
+
[membrane](https://github.com/antra-tess/membrane),
|
|
6
|
+
[context-manager](https://github.com/anima-research/context-manager),
|
|
7
|
+
[chronicle](https://github.com/anima-research/chronicle)). These conventions
|
|
8
|
+
describe how work actually lands here — they codify existing practice rather
|
|
9
|
+
than aspiration. When in doubt, recent merged PRs are the best reference.
|
|
10
|
+
|
|
11
|
+
Everything below applies to every change however it lands — external PR or
|
|
12
|
+
maintainer direct push — and to human and AI authors identically. There is
|
|
13
|
+
no separate rulebook for either.
|
|
14
|
+
|
|
15
|
+
## How changes land
|
|
16
|
+
|
|
17
|
+
- External contributions come as PRs against `main`, from a fork or a repo
|
|
18
|
+
branch. Maintainers also land small changes directly on `main`; don't be
|
|
19
|
+
surprised by history that never saw a PR.
|
|
20
|
+
- Branch names: `feat/<kebab-case>`, `fix/<kebab-case>`, `docs/`, `chore/`.
|
|
21
|
+
Including the issue number is welcome (`fix/43-scope-module-injections`).
|
|
22
|
+
- PRs are merged as **true merge commits** — no squash, no rebase-merge.
|
|
23
|
+
Because nothing is squashed, keep individual commits coherent.
|
|
24
|
+
- To update a stale branch, rebase onto `main` or merge `main` in; both are
|
|
25
|
+
accepted.
|
|
26
|
+
- Stacked PRs and cross-repo companion PRs are fine, but **declare them** in
|
|
27
|
+
the body with merge-order guidance ("stacked on #7 — review that first";
|
|
28
|
+
"safe to merge in either order because …").
|
|
29
|
+
|
|
30
|
+
## What a PR should contain
|
|
31
|
+
|
|
32
|
+
Body shape (the PR template mirrors this): **Problem / Changes / Tests**,
|
|
33
|
+
plus, when applicable, **Not verified**, **Out of scope**, and
|
|
34
|
+
**Companion PRs**. The conventions that matter:
|
|
35
|
+
|
|
36
|
+
- **Evidence over assertion.** State the test baseline numerically:
|
|
37
|
+
"`bun test`: N pass / M fail, failure count identical to `main` baseline."
|
|
38
|
+
A claim like "all tests pass" without the count will be re-verified anyway,
|
|
39
|
+
so save the reviewer the trip.
|
|
40
|
+
- **Say what you did NOT verify.** An honest "not exercised end-to-end
|
|
41
|
+
against a live Zulip" is respected; a silent gap that review uncovers is
|
|
42
|
+
not.
|
|
43
|
+
- **Tests accompany behavior changes.** Review scrutinizes test substance,
|
|
44
|
+
not mere presence — a test that can't fail on the unfixed code will be
|
|
45
|
+
called out.
|
|
46
|
+
- **Changelog entry** under `## Unreleased` for anything behavior-affecting
|
|
47
|
+
(see below).
|
|
48
|
+
|
|
49
|
+
Conventional-commit-style titles (`feat(recipe): …`, `fix(subagent): …`) are
|
|
50
|
+
the house default; plain descriptive titles are accepted.
|
|
51
|
+
|
|
52
|
+
## Review process — what to expect
|
|
53
|
+
|
|
54
|
+
- Review arrives as **ordinary PR comments**, not GitHub review approvals —
|
|
55
|
+
the comment thread is the gate. Reviews are frequently AI-generated and
|
|
56
|
+
explicitly labeled as such, with a severity verdict and itemized findings.
|
|
57
|
+
- The reviewer will typically **run your branch** (typecheck, test suite,
|
|
58
|
+
loading a recipe) and paste transcripts. Claims are checked, not trusted.
|
|
59
|
+
- Respond by pushing fix commits and replying per finding — "Addressed in
|
|
60
|
+
`<sha>`" — rather than force-pushing a rewritten branch. A re-review then
|
|
61
|
+
flips the verdict.
|
|
62
|
+
- Maintainers may push small review fixes **directly to your branch** to keep
|
|
63
|
+
things moving. Say so in the PR body if you'd rather they didn't.
|
|
64
|
+
- PRs are never closed silently: a closed PR gets a one-line disposition
|
|
65
|
+
comment (usually supersession by another PR).
|
|
66
|
+
|
|
67
|
+
## AI-assisted contributions
|
|
68
|
+
|
|
69
|
+
AI-written code is the norm in this ecosystem, welcome from everyone, and
|
|
70
|
+
held to exactly the same evidence standards as anything else. Declare it the
|
|
71
|
+
way we do:
|
|
72
|
+
|
|
73
|
+
- the `🤖 Generated with [Claude Code](https://claude.com/claude-code)`
|
|
74
|
+
footer (or equivalent for your tooling) in the PR body, and
|
|
75
|
+
- a `Co-Authored-By:` trailer naming the model in commits.
|
|
76
|
+
|
|
77
|
+
What earns an automated contribution a changes-requested review is not being
|
|
78
|
+
AI-generated — it's arriving without the suite having been run, with tests
|
|
79
|
+
that don't fail on unfixed code, or with claims the branch itself disproves.
|
|
80
|
+
|
|
81
|
+
## Changelog
|
|
82
|
+
|
|
83
|
+
`CHANGELOG.md` keeps a standing `## Unreleased` section with
|
|
84
|
+
`### Breaking` / `### Added` / `### Changed` / `### Fixed` subsections
|
|
85
|
+
(loosely [Keep a Changelog](https://keepachangelog.com/)).
|
|
86
|
+
|
|
87
|
+
- **The entry lands with the change** — same commit, or at least the same
|
|
88
|
+
PR. This binds direct pushes to `main` just as much as PRs. On PRs, CI
|
|
89
|
+
enforces it softly: touching `src/` without touching `CHANGELOG.md` fails
|
|
90
|
+
the `changelog` check unless the `no-changelog` label is applied.
|
|
91
|
+
- **What needs an entry:** anything an operator, recipe author, or module
|
|
92
|
+
developer would notice — behavior, config/recipe schema, CLI, tool
|
|
93
|
+
surfaces, defaults. Internal refactors, test-only, and docs-only changes
|
|
94
|
+
don't.
|
|
95
|
+
- **Breaking entries are audience-scoped.** Name the audience in the heading
|
|
96
|
+
(`### Breaking (recipe authors only)`) and cover: **who needs to act**,
|
|
97
|
+
**migration**, and **unchanged** (what readers might fear broke but
|
|
98
|
+
didn't). The fleet recipe-path entry in `CHANGELOG.md` is the canonical
|
|
99
|
+
example of the format.
|
|
100
|
+
- **Releases** (maintainers): `npm version <patch|minor|major>` does the
|
|
101
|
+
whole cut — the `version` hook retitles `Unreleased` to
|
|
102
|
+
`## X.Y.Z — YYYY-MM-DD` (keeping a fresh `Unreleased` above it, and
|
|
103
|
+
refusing to release when there are no entries), then npm commits and tags.
|
|
104
|
+
`git push --follow-tags` triggers CI, which refuses a tag with no matching
|
|
105
|
+
changelog section, publishes `@animalabs/connectome-host` to npm, and
|
|
106
|
+
creates the GitHub release with that section as its notes. The two release
|
|
107
|
+
jobs are independent: some consumers run github-clone checkouts, so
|
|
108
|
+
release notes must exist even when npm publish fails. Version bumps are a
|
|
109
|
+
maintainer release-time action, not part of feature PRs.
|
|
110
|
+
|
|
111
|
+
## Building and testing
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
bun install
|
|
115
|
+
bun test # test suite
|
|
116
|
+
bunx tsc --noEmit # typecheck
|
|
117
|
+
bun src/index.ts # run (generic assistant)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Push-time CI (`ci.yml`) builds and tests every push and PR on ubuntu and
|
|
121
|
+
macos, installing the web app with a strict lockfile (`npm ci`) — if you
|
|
122
|
+
touched `web/` dependencies, regenerate the lock with `npm run relock:web`
|
|
123
|
+
so it carries both platforms' native binaries.
|
|
124
|
+
|
|
125
|
+
See `docs/DEV-ENVIRONMENT.md` for the full dev setup and `docs/` generally
|
|
126
|
+
for architecture and operations guides.
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# connectome-host
|
|
2
2
|
|
|
3
|
-
A general-purpose agent
|
|
3
|
+
A general-purpose agent host with recipe-based configuration. Point it at any use case by loading a recipe — a JSON file that defines the system prompt, MCP servers, modules, and agent settings. Interact through the web UI (browser operator console), the interactive TUI, or run headless under a fleet parent.
|
|
4
4
|
|
|
5
5
|
Built on the Connectome stack: [@animalabs/agent-framework](https://github.com/anima-research/agent-framework) + [@animalabs/context-manager](https://github.com/anima-research/context-manager) + [@animalabs/chronicle](https://github.com/anima-research/chronicle) + [@animalabs/membrane](https://github.com/anima-research/membrane).
|
|
6
6
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
# Prerequisites: Bun, Rust toolchain,
|
|
10
|
+
# Prerequisites: Bun, Rust toolchain, and provider credentials
|
|
11
11
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
12
12
|
|
|
13
13
|
bun install
|
|
@@ -96,8 +96,31 @@ Recipe servers merge with `mcpl-servers.json`. The file wins on conflict, so use
|
|
|
96
96
|
|
|
97
97
|
See [`recipes/SETUP.md`](recipes/SETUP.md) for a detailed setup guide for the knowledge-miner recipe.
|
|
98
98
|
|
|
99
|
+
### ChatGPT subscription provider
|
|
100
|
+
|
|
101
|
+
Install the Codex CLI, sign in with `codex login`, then select the subscription
|
|
102
|
+
transport in a recipe:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"agent": {
|
|
107
|
+
"provider": "openai-codex",
|
|
108
|
+
"model": "gpt-5.4",
|
|
109
|
+
"codex": { "fastMode": false },
|
|
110
|
+
"systemPrompt": "You are a helpful assistant."
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Connectome asks the Codex app-server to refresh the ChatGPT login and starts a
|
|
116
|
+
device-code flow if needed. No `OPENAI_API_KEY` is used for this provider. Use
|
|
117
|
+
`/fast on` or `/fast off` at runtime. Connectome requests Codex's Fast tier and
|
|
118
|
+
warns if the service reports that it fell back to Standard; Fast mode consumes
|
|
119
|
+
subscription credits at a higher rate when applied.
|
|
120
|
+
|
|
99
121
|
## What it provides
|
|
100
122
|
|
|
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
|
|
101
124
|
- **TUI + readline modes**: OpenTUI interactive terminal or `--no-tui` for pipes/CI
|
|
102
125
|
- **Subagent forking**: Spawn/fork parallel agents with fleet tree view (Tab to toggle)
|
|
103
126
|
- **Persistent lessons**: Knowledge store with confidence scores, tags, and semantic retrieval
|
|
@@ -109,7 +132,7 @@ See [`recipes/SETUP.md`](recipes/SETUP.md) for a detailed setup guide for the kn
|
|
|
109
132
|
## Prerequisites
|
|
110
133
|
|
|
111
134
|
- [Node.js](https://nodejs.org/) 20+ and [Bun](https://bun.sh/) runtime
|
|
112
|
-
- An Anthropic API key
|
|
135
|
+
- An Anthropic API key, OpenAI API key, or the Codex CLI signed in with ChatGPT
|
|
113
136
|
|
|
114
137
|
### Install
|
|
115
138
|
|
|
@@ -122,7 +145,11 @@ npm install
|
|
|
122
145
|
| Variable | Default | Description |
|
|
123
146
|
|----------|---------|-------------|
|
|
124
147
|
| `ANTHROPIC_API_KEY` | (required) | Anthropic API key |
|
|
125
|
-
| `
|
|
148
|
+
| `OPENAI_API_KEY` | — | OpenAI Platform key for `openai-responses` recipes |
|
|
149
|
+
| `CODEX_BINARY` | `codex` | Codex CLI executable for `openai-codex` subscription auth |
|
|
150
|
+
| `CODEX_HOME` | `~/.codex` | Codex credential/config directory |
|
|
151
|
+
| `CODEX_BASE_URL` | ChatGPT Codex backend | Optional subscription transport override |
|
|
152
|
+
| `MODEL` | from recipe or provider default | Override model |
|
|
126
153
|
| `DATA_DIR` | `./data` | Session and recipe storage |
|
|
127
154
|
|
|
128
155
|
## Running
|
|
@@ -130,10 +157,29 @@ npm install
|
|
|
130
157
|
```bash
|
|
131
158
|
bun src/index.ts # Interactive TUI
|
|
132
159
|
bun src/index.ts --no-tui # Readline mode
|
|
160
|
+
bun src/index.ts --headless # Daemon: JSONL IPC over unix socket, no terminal
|
|
133
161
|
echo "Hello" | bun src/index.ts # Piped mode
|
|
134
162
|
bun --watch src/index.ts # Dev mode
|
|
135
163
|
```
|
|
136
164
|
|
|
165
|
+
## Web UI
|
|
166
|
+
|
|
167
|
+
Enable with `"modules": { "webui": true }` (or `{ "port": 7340, "host": "0.0.0.0" }`)
|
|
168
|
+
in the recipe. The host serves the SPA and its WebSocket protocol on port 7340;
|
|
169
|
+
non-loopback binds require basic-auth credentials. Build the SPA bundle once with
|
|
170
|
+
`bun run build:web` (also runs on `npm install` via postinstall).
|
|
171
|
+
|
|
172
|
+
- Chat with full interiority: thinking blocks, tool calls + results, live streaming
|
|
173
|
+
- Sidebar: agent/fleet tree, lessons, MCPL servers, workspace files, context makeup + compression coverage, health (runtime settings, failure streaks, compression quarantine)
|
|
174
|
+
- Header branch chip opens the Chronicle branch lineage tree (checkout from the UI)
|
|
175
|
+
- Ops alerts (compression quarantine, refusal streaks, inference-exhausted) render as persistent banner rows
|
|
176
|
+
- Usage panel: per-agent costs and a billing-grade call ledger with cache verdicts
|
|
177
|
+
- `/curve` — compression-curve visualization; `/healthz` — liveness JSON for doctor/fleet tooling
|
|
178
|
+
- Read-only observer access via Ed25519 device keys with per-grant scopes (see `docs/webui-deployment.md`)
|
|
179
|
+
|
|
180
|
+
For SPA development: `cd web && bun run dev` proxies the Vite dev server onto a
|
|
181
|
+
locally running host.
|
|
182
|
+
|
|
137
183
|
## Slash commands
|
|
138
184
|
|
|
139
185
|
| Command | Effect |
|
|
@@ -156,6 +202,7 @@ bun --watch src/index.ts # Dev mode
|
|
|
156
202
|
| `/mcp remove <id>` | Remove a server |
|
|
157
203
|
| `/mcp env <id> KEY=VALUE [...]` | Set env vars on a server |
|
|
158
204
|
| `/budget [tokens]` | Show/set stream token budget |
|
|
205
|
+
| `/fast [on\|off\|status]` | Toggle Codex subscription Fast mode |
|
|
159
206
|
| `/session list\|new\|switch\|rename\|delete` | Session management |
|
|
160
207
|
| `/quit` | Exit |
|
|
161
208
|
|
|
@@ -176,7 +223,7 @@ bun --watch src/index.ts # Dev mode
|
|
|
176
223
|
| Up/Down | Navigate tree |
|
|
177
224
|
| Enter/Right | Expand/collapse |
|
|
178
225
|
| Left | Collapse |
|
|
179
|
-
| `p` | Peek
|
|
226
|
+
| `p` | Peek the selected node's live stream — local subagents, fleet children, or a single agent/subagent inside a fleet child |
|
|
180
227
|
| `Delete` | Stop a running subagent |
|
|
181
228
|
|
|
182
229
|
## Architecture
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animalabs/connectome-host",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.10",
|
|
4
4
|
"description": "General-purpose agent TUI host with recipe-based configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "bun src/index.ts",
|
|
8
8
|
"dev": "bun --watch src/index.ts",
|
|
9
9
|
"test": "bun test",
|
|
10
|
+
"version": "bun scripts/release-changelog.ts && git add CHANGELOG.md",
|
|
10
11
|
"build:web": "npm --prefix web install && npm --prefix web run build",
|
|
11
12
|
"build:web:ci": "npm ci --prefix web && npm --prefix web run build",
|
|
12
13
|
"relock:web": "rm -rf web/node_modules web/package-lock.json && npm --prefix web install",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Runs as npm's `version` lifecycle hook (see package.json): at that point
|
|
2
|
+
// package.json already carries the new version, and files staged here are
|
|
3
|
+
// included in the release commit that `npm version` then creates and tags.
|
|
4
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
|
|
6
|
+
const { version } = JSON.parse(readFileSync("package.json", "utf8"));
|
|
7
|
+
const path = "CHANGELOG.md";
|
|
8
|
+
const text = readFileSync(path, "utf8");
|
|
9
|
+
|
|
10
|
+
const header = text.match(/^## Unreleased[ \t]*$/m);
|
|
11
|
+
if (!header || header.index === undefined) {
|
|
12
|
+
console.error("CHANGELOG.md: no '## Unreleased' section — add one before releasing.");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const escaped = version.replace(/[.]/g, "\\.");
|
|
17
|
+
if (new RegExp(`^## ${escaped}([^0-9]|$)`, "m").test(text)) {
|
|
18
|
+
console.error(`CHANGELOG.md: a '## ${version}' section already exists.`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const afterHeader = text.slice(header.index + header[0].length);
|
|
23
|
+
const nextSection = afterHeader.search(/^## /m);
|
|
24
|
+
const unreleasedBody = nextSection === -1 ? afterHeader : afterHeader.slice(0, nextSection);
|
|
25
|
+
if (!/^\s*[-*] /m.test(unreleasedBody)) {
|
|
26
|
+
console.error(`CHANGELOG.md: '## Unreleased' has no entries — nothing to release as ${version}.`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
31
|
+
writeFileSync(path, text.replace(header[0], `## Unreleased\n\n## ${version} — ${date}`));
|
|
32
|
+
console.log(`CHANGELOG.md: cut Unreleased into '## ${version} — ${date}'.`);
|