@junghanacs/entwurf 0.12.2 → 0.12.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/AGENTS.md +2 -2
- package/CHANGELOG.md +39 -0
- package/README.md +9 -5
- package/VERIFY.md +4 -4
- package/demo/README.md +5 -5
- package/demo/demo-baseline.sh +2 -2
- package/demo/demo.sh +3 -3
- package/docs/setup-clean-host.md +27 -10
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-store-doctor.js +55 -0
- package/mcp/entwurf-bridge/tsconfig.build.json +14 -6
- package/package.json +9 -9
- package/pi/entwurf-targets.json +3 -6
- package/pi-extensions/lib/acp/acp-client.ts +2 -2
- package/pi-extensions/lib/acp/models.ts +7 -9
- package/run.sh +74 -21
- package/scripts/check-acp-backend-preflight.ts +1 -1
- package/scripts/check-acp-config.ts +3 -3
- package/scripts/check-acp-event-mapper.ts +1 -1
- package/scripts/check-acp-provider-surface.ts +1 -1
- package/scripts/check-acp-sdk-surface.ts +22 -22
- package/scripts/check-acp-session-reuse.ts +3 -3
- package/scripts/check-acp-session-store.ts +6 -6
- package/scripts/check-acp-tool-surface.ts +2 -2
- package/scripts/check-entwurf-session-identity.ts +9 -9
- package/scripts/check-model-lock.ts +2 -2
- package/scripts/check-package-source-routing.ts +4 -4
- package/scripts/meta-bridge-doctor.sh +55 -10
- package/scripts/meta-bridge-state.py +2 -0
- package/scripts/resolve-acp-bridge.ts +1 -1
- package/scripts/smoke-acp-bundled-mcp-live.ts +1 -1
- package/scripts/smoke-acp-carrier-augment-live.ts +1 -1
- package/scripts/smoke-acp-mcp-live.ts +1 -1
- package/scripts/smoke-acp-memory-containment-live.ts +8 -9
- package/scripts/smoke-acp-overlay-live.ts +8 -9
- package/scripts/smoke-acp-provider-live.ts +1 -1
- package/scripts/smoke-acp-raw-turn-live.ts +12 -11
- package/scripts/smoke-acp-session-reuse-live.ts +24 -9
- package/scripts/smoke-acp-skill-live.ts +1 -1
- package/scripts/smoke-meta-install-state.sh +3 -3
package/AGENTS.md
CHANGED
|
@@ -217,8 +217,8 @@ Code-level invariants pinned at the same time:
|
|
|
217
217
|
|
|
218
218
|
## Runtime Dependencies
|
|
219
219
|
|
|
220
|
-
- `@modelcontextprotocol/sdk` and `zod` are the substrate runtime deps. With the Claude-first ACP plugin shipped, the Claude/ACP backend deps are pinned alongside them: `@agentclientprotocol/claude-agent-acp` (`0.
|
|
221
|
-
- `pi` (`@earendil-works/pi-ai`) on PATH at the pinned range (`>= 0.80.
|
|
220
|
+
- `@modelcontextprotocol/sdk` and `zod` are the substrate runtime deps. With the Claude-first ACP plugin shipped, the Claude/ACP backend deps are pinned alongside them: `@agentclientprotocol/claude-agent-acp` (`0.54.1`), `@agentclientprotocol/sdk` (`1.1.0`), `@anthropic-ai/sdk` (`0.100.1`). The Codex/Gemini ACP packages stay out of scope (native already reaches Codex; Gemini/major tools use native).
|
|
221
|
+
- `pi` (`@earendil-works/pi-ai`) on PATH at the pinned range (`>= 0.80.3 < 0.81` — devDep exact `0.80.3` + next-minor ceiling). Mismatches are caught by `check-dep-versions` / `check-pi-runtime-version`. 0.80 moved the standalone root `getModels()` to the deprecated `@earendil-works/pi-ai/compat` entrypoint; the curated Claude surface (`pi-extensions/lib/acp/models.ts`) imports `getModels` from `/compat` — the single subpath allowlisted in `check-pi-import-surface`. NOT the 0.80 provider-factory `providers/anthropic` subpath: although it typechecks, pi's extension loader (jiti alias map in pi-coding-agent `core/extensions/loader.ts`) resolves only the bare root, `/compat`, and `/oauth` for extensions — a `providers/*` import resolves to the unresolvable `dist/compat.js/providers/…` and crashes extension load (caught live by `smoke-resident-garden-guard`, not by static typecheck). This `/compat` use is an **extension-loader compatibility shim** chosen by loader constraint, not a preference for a deprecated API — the `<0.81` ceiling guards it; when 0.81 changes `compat` or the loader alias map, re-evaluate against whatever root/loader surface 0.81 then exposes.
|
|
222
222
|
|
|
223
223
|
## Working Style
|
|
224
224
|
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to this project will be documented here. Format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.12.4 — 2026-07-01
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **Installed `doctor-meta-bridge` no longer false-fails on node_modules strip-types.** The doctor previously ran `scripts/meta-bridge-store-doctor.ts` and `scripts/check-entwurf-v2-surface.ts` through Node strip-types even from an npm/pnpm-installed package. Node refuses type stripping under `node_modules` (`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`), so real floor hosts reported false store-scan / v2-surface failures while development clones stayed green. The doctor now branches by package location: installed packages run the prebuilt `mcp/entwurf-bridge/dist/scripts/meta-bridge-store-doctor.js` with plain `node` and defer the repo-only v2 source-shape gate after confirming the shipped source and runtime wiring; development clones keep the raw `.ts` gates.
|
|
12
|
+
- **The store-doctor helper now ships as a node_modules-safe dist artifact.** The bridge build emits `dist/scripts/meta-bridge-store-doctor.js` alongside the MCP bridge closure, reusing the already-shipped `meta-session.js` dependency without adding a new runtime package lane. `check-pack` / `check-pack-install` require the artifact in the tarball and prove it scans a real fixture store under `node_modules` with plain `node`.
|
|
13
|
+
- **Clean-host install docs call out the 0.12.4 doctor floor check.** The walkthrough now tells operators exactly which doctor lines prove the installed-vs-dev split and flags any `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING` as a pre-0.12.4 or broken-tarball signal.
|
|
14
|
+
|
|
15
|
+
### Verification
|
|
16
|
+
|
|
17
|
+
- `pnpm check` passed on 2026-07-01 after the doctor/install-floor fix.
|
|
18
|
+
- `./run.sh check-pack-install` passed with the new installed store-doctor scan and doctor-dispatch lock assertions.
|
|
19
|
+
- Release-gate prep evidence: `LIVE=1 ./run.sh release-gate /tmp/psa-release-gate-0.12.4.PliLsd` passed on 2026-07-01; log `/tmp/pi-tmux-entwurf-release-gate-0124.log`; summary `MUST: PASS=17 FAIL=0 SKIP=0`, advisory `BEHAVIOR: PASS=0 FAIL=1` (`smoke-resident-garden-guard` post-`/gnew` autonomous `entwurf_self` identity turn; non-blocking).
|
|
20
|
+
- `hejdev6` real floor host reproduced the pre-fix strip-types failure from an installed package and passed after installing the patched tarball: compiled store-doctor scanned `1 record(s)` with plain `node`, and installed `doctor-meta-bridge` reported store-scan ok plus v2-surface deferred.
|
|
21
|
+
|
|
22
|
+
## 0.12.3 — 2026-07-01
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **Claude ACP dependency lane refreshed for Sonnet 5.** The ACP runtime pins now use `@agentclientprotocol/claude-agent-acp@0.54.1` with `@agentclientprotocol/sdk@1.1.0`, while keeping the direct `@anthropic-ai/sdk@0.100.1` peer-resolution pin. The pi adapter floor is now `@earendil-works/pi-* >=0.80.3 <0.81`, matching the runtime catalog that exposes `claude-sonnet-5`.
|
|
27
|
+
- **Curated Claude surface moves from Sonnet 4.6 to Sonnet 5.** `claude-sonnet-5` replaces `claude-sonnet-4-6` across the ACP provider, demo/default smoke targets, pi target registry, and release docs. The Sonnet-specific 200K cap was removed; Sonnet 5 now surfaces the verified 1M context window like the Opus anchor, with a 1M ceiling guard to prevent silent future inflation.
|
|
28
|
+
- **Release and backend docs are version-neutral where the repo shape is stable.** The README now describes the durable repository shape instead of a point-in-time `0.12.x` state, and the clean-host/demo/verification docs reflect the current pi floor and Sonnet 5 defaults.
|
|
29
|
+
- **Cortex and fresh-spawn planning docs realigned to the 0.12 substrate.** The ACP backend rail documentation and NEXT/ROADMAP planning notes now describe the as-built adapter seam and the mux-visible fresh-sibling lane without re-centering old v1/fat-bridge assumptions.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **Live ACP smoke timeout cleanup no longer leaves stale timers after PASS.** Raw-turn, overlay, memory-containment, and session-reuse live smokes now clear their timeout handles when the awaited operation wins, so a successful live check exits promptly instead of lingering until the old timeout expires.
|
|
34
|
+
- **Session-reuse live smoke now preserves its success evidence.** The two-turn reuse smoke no longer calls `process.exit(0)` on success, allowing the turn-2/PASS log and cleanup to drain naturally while the retained ACP child is still handled by the backend exit cleanup.
|
|
35
|
+
- **Claude Code meta-bridge install state also disables workflow surfaces.** `enableWorkflows` and `workflowKeywordTriggerEnabled` are now managed false alongside the existing auto-memory, compaction, prompt-suggestion, progress, and auto-mode settings.
|
|
36
|
+
- **Unsupported ACP Codex targets are not advertised.** The target registry keeps Codex on the native `openai-codex` provider only; `entwurf/gpt-5.4` and `entwurf/gpt-5.5` are removed until an ACP Codex backend exists.
|
|
37
|
+
|
|
38
|
+
### Verification
|
|
39
|
+
|
|
40
|
+
- `pnpm check` passed on 2026-07-01 after the dependency/model/doc updates; prep log `/tmp/pi-tmux-entwurf-prep-check-0123.log` ended with `EXIT=0`.
|
|
41
|
+
- `LIVE=1 ./run.sh smoke-acp-raw-turn-live` passed with `claude-sonnet-5` and exited promptly after PASS.
|
|
42
|
+
- `LIVE=1 ./run.sh smoke-acp-provider-live` passed with `claude-sonnet-5` through the pi provider path.
|
|
43
|
+
- `LIVE=1 ./run.sh smoke-acp-session-reuse-live` passed with a two-turn reused ACP child; turn 2 recalled the turn-1 codeword from delta-only prompt scope.
|
|
44
|
+
- `LIVE=1 ./run.sh release-gate /tmp/psa-release-gate-0.12.3.ZcRc8w` passed on 2026-07-01 with `MUST: PASS=17 FAIL=0 SKIP=0` and `BEHAVIOR: PASS=1 FAIL=0`; log `/tmp/pi-tmux-entwurf-release-gate-0123.log`.
|
|
45
|
+
|
|
7
46
|
## 0.12.2 — 2026-06-29
|
|
8
47
|
|
|
9
48
|
### Fixed
|
package/README.md
CHANGED
|
@@ -10,9 +10,7 @@ npm package: <https://www.npmjs.com/package/@junghanacs/entwurf>
|
|
|
10
10
|
|
|
11
11
|
Legacy package: [`@junghanacs/pi-shell-acp`](https://www.npmjs.com/package/@junghanacs/pi-shell-acp). `entwurf` is its 0.12+ successor line: the same work renamed around the garden-citizen dispatch substrate rather than the pi adapter.
|
|
12
12
|
|
|
13
|
-
> **
|
|
14
|
-
|
|
15
|
-
> **Current state for 0.12.1.** This repo is **entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an ACP plugin**. Pi is one supported harness adapter — important because it supplies control sockets and hosts the ACP plugin today — but it is not the project subject. Claude Code is shipped through the meta-bridge; pi is shipped through the control-socket adapter; Codex and Antigravity (`agy`) reach the garden with verified delivery probes, documented per launch mode in [DELIVERY.md](./DELIVERY.md), with shipped adapter/install lanes landing after the 0.12.0 doc cut. The ACP plugin is Claude-first; Cortex/vendor-governed ACP backends are future lanes.
|
|
13
|
+
> **Repository shape.** This repo is **entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an ACP plugin**. Pi is one supported harness adapter — important because it supplies control sockets and hosts the ACP plugin today — but it is not the project subject. Claude Code is shipped through the meta-bridge; pi is shipped through the control-socket adapter. Codex and Antigravity (`agy`) have verified delivery probes documented per launch mode in [DELIVERY.md](./DELIVERY.md); shipped adapter/install lanes are tracked separately. The ACP plugin is Claude-first; Cortex/vendor-governed ACP backends are future lanes.
|
|
16
14
|
|
|
17
15
|
<details>
|
|
18
16
|
<summary>Watch archived pre-0.12 demo (2131×1142 GIF, click to expand)</summary>
|
|
@@ -55,7 +53,7 @@ native Claude Code
|
|
|
55
53
|
→ entwurf_self | entwurf_v2 | entwurf_inbox_read
|
|
56
54
|
```
|
|
57
55
|
|
|
58
|
-
This meta-bridge installer/doctor is **Claude Code only** in the shipped
|
|
56
|
+
This meta-bridge installer/doctor is **Claude Code only** in the current shipped surface. Codex and Antigravity delivery probes are recorded in [DELIVERY.md](./DELIVERY.md) as verified adapter evidence, not yet shipped install surfaces.
|
|
59
57
|
|
|
60
58
|
> **Direction.** Inverse of [`pi-acp`](https://github.com/svkozak/pi-acp). `pi-acp` lets external ACP clients talk *to* pi; `entwurf` lets garden citizens talk across harness boundaries — with pi as one adapter, not the center.
|
|
61
59
|
|
|
@@ -147,7 +145,7 @@ because Node refuses to strip `.ts` files under `node_modules`.
|
|
|
147
145
|
### Pi adapter / ACP plugin lane
|
|
148
146
|
|
|
149
147
|
To use the `entwurf` provider inside pi, install a compatible pi binary
|
|
150
|
-
separately (`@earendil-works/pi-coding-agent >=0.80.
|
|
148
|
+
separately (`@earendil-works/pi-coding-agent >=0.80.3 <0.81`). Then point pi at
|
|
151
149
|
the npm-installed package or development clone:
|
|
152
150
|
|
|
153
151
|
```bash
|
|
@@ -183,6 +181,12 @@ entwurf install-meta-bridge
|
|
|
183
181
|
entwurf doctor-meta-bridge
|
|
184
182
|
```
|
|
185
183
|
|
|
184
|
+
On npm/pnpm-installed packages, `doctor-meta-bridge` must use prebuilt JS for its
|
|
185
|
+
store scan and defer repo-only source-shape gates; Node refuses strip-types for
|
|
186
|
+
raw `.ts` helpers under `node_modules`. If the doctor reports
|
|
187
|
+
`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`, reinstall a current package before
|
|
188
|
+
trusting the floor result.
|
|
189
|
+
|
|
186
190
|
For manual configuration, [`pi/settings.reference.json`](./pi/settings.reference.json)
|
|
187
191
|
shows the pi adapter settings shape, and the external-host examples below show
|
|
188
192
|
plain MCP registrations.
|
package/VERIFY.md
CHANGED
|
@@ -44,7 +44,7 @@ Verification here is not a benchmark. In production we exchange short turns and
|
|
|
44
44
|
### Verifying the two capabilities a gate cannot fully judge
|
|
45
45
|
|
|
46
46
|
- **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2` with the correct intent — `fire-and-forget` for a live/replyable or meta-session target, `owned-outcome` only to wake a dormant record-backed pi citizen. Picking the wrong intent is rejected, never auto-fixed.
|
|
47
|
-
- **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-
|
|
47
|
+
- **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-5` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
|
|
48
48
|
|
|
49
49
|
### What NOT to do — bypassing the operational path
|
|
50
50
|
|
|
@@ -102,7 +102,7 @@ pi install git:github.com/junghan0611/entwurf # pi auto-clones + instal
|
|
|
102
102
|
cd /path/to/consumer-project
|
|
103
103
|
~/.pi/agent/git/github.com/junghan0611/entwurf/run.sh install . # wire bundled mcpServers
|
|
104
104
|
pi --list-models entwurf # curated model surface
|
|
105
|
-
pi --provider entwurf --model claude-sonnet-
|
|
105
|
+
pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only" # one-turn smoke
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
Expected: the package appears under pi's `User packages`; `install .` logs `added entwurfProvider.mcpServers.entwurf-bridge` + `updated <project>/.pi/settings.json`; the smoke returns a one-word reply (full bootstrap → ACP session → bridge → clean shutdown). Note: `~/.pi/agent/git/.../entwurf` is pi-managed — do not edit it (a `pi update` overwrites). Step 2 is still required after `pi install git:…`.
|
|
@@ -115,7 +115,7 @@ pnpm install # pnpm is the pinned packageManag
|
|
|
115
115
|
pi install ./
|
|
116
116
|
./run.sh install /path/to/consumer-project
|
|
117
117
|
pnpm check # full deterministic floor
|
|
118
|
-
pi --provider entwurf --model claude-sonnet-
|
|
118
|
+
pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only"
|
|
119
119
|
LIVE=1 ./run.sh release-gate /path/to/consumer-project
|
|
120
120
|
```
|
|
121
121
|
|
|
@@ -140,7 +140,7 @@ Compare a fresh self-awareness report across axes: (1) same backend, different i
|
|
|
140
140
|
|
|
141
141
|
## 1A. Main Agent Evaluation — Is `entwurf` Claude strong enough?
|
|
142
142
|
|
|
143
|
-
Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-
|
|
143
|
+
Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-5` via a direct `pi --provider entwurf` turn (or a live ACP session); accumulate turns by re-prompting the same target.
|
|
144
144
|
|
|
145
145
|
### 1A.0 Two carrier surfaces — engraving vs pi-context-augment (load-bearing)
|
|
146
146
|
|
package/demo/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Historical pre-0.12 demo, still linked from the top-level `README.md` as archive
|
|
|
17
17
|
tools, names the carrier surface for each cited piece of
|
|
18
18
|
information, and admits unknowns instead of fabricating.
|
|
19
19
|
2. **Entwurf surface** — the same pane spawns a sibling via the
|
|
20
|
-
`entwurf` tool (`mode=sync`, cross-model — driver `claude-sonnet-
|
|
20
|
+
`entwurf` tool (`mode=sync`, cross-model — driver `claude-sonnet-5`,
|
|
21
21
|
sibling `gpt-5.4`), prints the Session ID, and quotes the sibling's
|
|
22
22
|
one-line reply verbatim.
|
|
23
23
|
|
|
@@ -81,7 +81,7 @@ grep -E '(entwurf|model-switch)' demo/sender-debug.log
|
|
|
81
81
|
| Var | Default | Meaning |
|
|
82
82
|
|---|---|---|
|
|
83
83
|
| `PEER_MODEL` | `entwurf/gpt-5.4` (≡ `piat`) | top pane backend (receives greeting) |
|
|
84
|
-
| `SENDER_MODEL` | `entwurf/claude-sonnet-
|
|
84
|
+
| `SENDER_MODEL` | `entwurf/claude-sonnet-5` (≡ `pias`) | bottom pane backend (drives scenes) |
|
|
85
85
|
| `SCENE_DELAY` | `25` | seconds to wait for each scene's agent work |
|
|
86
86
|
| `WARMUP` | `3` | seconds to wait for both pi banners |
|
|
87
87
|
| `FINAL_PAUSE` | `5` | extra wait after scene 3 (peer reply lag) |
|
|
@@ -93,7 +93,7 @@ grep -E '(entwurf|model-switch)' demo/sender-debug.log
|
|
|
93
93
|
|
|
94
94
|
| Var | Default | Meaning |
|
|
95
95
|
|---|---|---|
|
|
96
|
-
| `DRIVER_MODEL` | `entwurf/claude-sonnet-
|
|
96
|
+
| `DRIVER_MODEL` | `entwurf/claude-sonnet-5` (≡ `pias`) | the driven pane — answers Q-B0 and spawns the sibling |
|
|
97
97
|
| `SIBLING_MODEL` | `entwurf/gpt-5.4` (≡ `piat`) | cross-backend sibling spawned in scene 2 |
|
|
98
98
|
| `SIBLING_CWD` | repo root | cwd passed to the entwurf sibling (drives `<project-context>` injection) |
|
|
99
99
|
| `SCENE1_DELAY` | `60` | seconds for the long English baseline answer |
|
|
@@ -114,7 +114,7 @@ The demo launch lines correspond to your shell aliases:
|
|
|
114
114
|
| Alias | Model id | Use as |
|
|
115
115
|
|---|---|---|
|
|
116
116
|
| `piao` | `entwurf/claude-opus-4-8` | `SENDER_MODEL` (precision scenes) |
|
|
117
|
-
| `pias` | `entwurf/claude-sonnet-
|
|
117
|
+
| `pias` | `entwurf/claude-sonnet-5` | `SENDER_MODEL` (default) |
|
|
118
118
|
| `piat` | `entwurf/gpt-5.4` | `PEER_MODEL` (default) |
|
|
119
119
|
| `piat5` | `entwurf/gpt-5.5` | either |
|
|
120
120
|
| `piag` | `entwurf/gemini-3.1-pro-preview` | either |
|
|
@@ -137,7 +137,7 @@ SCENE_DELAY=30 FINAL_PAUSE=10 bash demo.sh
|
|
|
137
137
|
|
|
138
138
|
## Prerequisites
|
|
139
139
|
|
|
140
|
-
- `pi` on PATH (current floor 0.80.
|
|
140
|
+
- `pi` on PATH (current floor 0.80.3)
|
|
141
141
|
- `entwurf` provider configured + auth ready for the selected sender/peer models
|
|
142
142
|
- `asciinema` installed
|
|
143
143
|
- `agg` installed (optional — only for GIF conversion)
|
package/demo/demo-baseline.sh
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# reply in the same pane (cross-model, mode=sync).
|
|
9
9
|
#
|
|
10
10
|
# Layout (tmux, 220x50):
|
|
11
|
-
# pane 0 (single) — driven pi (claude-sonnet-
|
|
11
|
+
# pane 0 (single) — driven pi (claude-sonnet-5) — receives both prompts.
|
|
12
12
|
#
|
|
13
13
|
# Recording: asciinema → baseline.cast → agg → baseline.gif
|
|
14
14
|
|
|
@@ -30,7 +30,7 @@ GIF="$PUBLISH_DIR/entwurf-demo.gif"
|
|
|
30
30
|
DRIVER_LOG="$OUTDIR/baseline-debug.log"
|
|
31
31
|
|
|
32
32
|
# Driven pi runs the bridge surface and answers both prompts.
|
|
33
|
-
DRIVER_MODEL=${DRIVER_MODEL:-entwurf/claude-sonnet-
|
|
33
|
+
DRIVER_MODEL=${DRIVER_MODEL:-entwurf/claude-sonnet-5} # pias
|
|
34
34
|
# Sibling spawned via entwurf in scene 2 — different backend for contrast.
|
|
35
35
|
SIBLING_MODEL=${SIBLING_MODEL:-entwurf/gpt-5.4} # piat
|
|
36
36
|
SIBLING_CWD=${SIBLING_CWD:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}
|
package/demo/demo.sh
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Layout (tmux, 220x50):
|
|
5
5
|
# pane 0 (top) — peer pi (codex, gpt-5.4) — idle, waits for greeting
|
|
6
|
-
# pane 1 (bottom) — sender pi (claude-sonnet-
|
|
6
|
+
# pane 1 (bottom) — sender pi (claude-sonnet-5) — driven by send-keys
|
|
7
7
|
#
|
|
8
8
|
# Scenes (driven into sender pane):
|
|
9
9
|
# 1. Spawn a sonnet sibling, store one fact.
|
|
@@ -32,7 +32,7 @@ SENDER_LOG="$OUTDIR/sender-debug.log"
|
|
|
32
32
|
|
|
33
33
|
# Models match the user's piat / pias aliases.
|
|
34
34
|
PEER_MODEL=${PEER_MODEL:-entwurf/gpt-5.4} # piat
|
|
35
|
-
SENDER_MODEL=${SENDER_MODEL:-entwurf/claude-sonnet-
|
|
35
|
+
SENDER_MODEL=${SENDER_MODEL:-entwurf/claude-sonnet-5} # pias
|
|
36
36
|
|
|
37
37
|
# Pacing in seconds. Tuned from real runs: each scene's actual agent work
|
|
38
38
|
# completes in ~5–15 s (Scene 1 sibling cold-spawn is the slowest; resume +
|
|
@@ -134,7 +134,7 @@ sleep "$WARMUP"
|
|
|
134
134
|
# window/pane base-index configs.
|
|
135
135
|
drive() {
|
|
136
136
|
# Scene 1 — spawn + memory write
|
|
137
|
-
tmux send-keys -t "$SENDER_PANE" -l 'Demo scene 1. Spawn a claude-sonnet-
|
|
137
|
+
tmux send-keys -t "$SENDER_PANE" -l 'Demo scene 1. Spawn a claude-sonnet-5 sibling via the entwurf tool. provider: entwurf, model: claude-sonnet-5, cwd: /home/junghan/repos/gh/entwurf, mode: sync. Task body: "You are a sibling for a recorded demo. Remember one fact only — my favorite forge color is tempered indigo. Reply with one short sentence acknowledging. No tool calls, no repo exploration." After it returns, print only the Session ID line so I can see it.'
|
|
138
138
|
tmux send-keys -t "$SENDER_PANE" Enter
|
|
139
139
|
sleep "$SCENE_DELAY"
|
|
140
140
|
|
package/docs/setup-clean-host.md
CHANGED
|
@@ -4,9 +4,11 @@ End-to-end install of **entwurf** on a host with only `git` available — no
|
|
|
4
4
|
node, no npm package, no pi binary, no dotfiles. The point is to validate the
|
|
5
5
|
public install surface as an outside user would experience it.
|
|
6
6
|
|
|
7
|
-
> **Scope.** This is the entwurf 0.12.
|
|
7
|
+
> **Scope.** This is the entwurf 0.12.4 install recipe. The base package install
|
|
8
8
|
> is **neutral npm**, not `pi install npm:...`. Pi is an optional adapter lane for
|
|
9
|
-
> the ACP provider / control-socket runtime.
|
|
9
|
+
> the ACP provider / control-socket runtime. The 0.12.4 floor fix is explicitly
|
|
10
|
+
> covered here: installed packages under `node_modules` must not run raw `.ts`
|
|
11
|
+
> doctor helpers through Node strip-types.
|
|
10
12
|
|
|
11
13
|
`entwurf` is a garden-citizen dispatch substrate and meta-bridge. It does not
|
|
12
14
|
provide, copy, or mediate backend credentials — it lets the official backend CLI
|
|
@@ -30,7 +32,7 @@ ssh cleanhost 'uname -a; whoami; which git node npm pi claude 2>/dev/null'
|
|
|
30
32
|
| Node | **24** recommended; `>=22.6.0` minimum | `engines.node` (Node strip-types / ESM runtime) |
|
|
31
33
|
| npm | bundled with Node 24 | public package install path |
|
|
32
34
|
| entwurf | `@junghanacs/entwurf` | neutral npm package; exposes `entwurf` and `entwurf-bridge` bins |
|
|
33
|
-
| pi binary | **optional**, `@earendil-works/pi-coding-agent >=0.80.
|
|
35
|
+
| pi binary | **optional**, `@earendil-works/pi-coding-agent >=0.80.3 <0.81` | needed only for the pi adapter / ACP provider / spawn-bg resume lane |
|
|
34
36
|
|
|
35
37
|
## Stage 0 — Node 24 via nvm
|
|
36
38
|
|
|
@@ -72,9 +74,11 @@ MCP bridge can boot in Claude Code / Codex / Antigravity without pi present.
|
|
|
72
74
|
## Stage 2 — auth-free bridge boot
|
|
73
75
|
|
|
74
76
|
Prove the installed MCP server answers `tools/list` from inside `node_modules`.
|
|
75
|
-
This is the regression
|
|
76
|
-
for `.ts` under `node_modules`, so the
|
|
77
|
-
JS under `mcp/entwurf-bridge/dist/`.
|
|
77
|
+
This is the first `node_modules` strip-types regression fixed in 0.12.0: Node
|
|
78
|
+
refuses `--experimental-strip-types` for `.ts` under `node_modules`, so the
|
|
79
|
+
installed package must boot the prebuilt JS under `mcp/entwurf-bridge/dist/`.
|
|
80
|
+
The 0.12.4 doctor fix below applies the same installed-vs-dev split to
|
|
81
|
+
`doctor-meta-bridge` helper checks.
|
|
78
82
|
|
|
79
83
|
```bash
|
|
80
84
|
node --input-type=module <<'JS'
|
|
@@ -109,7 +113,7 @@ If the host will run pi sessions or the Claude ACP provider through pi, install
|
|
|
109
113
|
a compatible pi binary separately and wire the target project.
|
|
110
114
|
|
|
111
115
|
```bash
|
|
112
|
-
npm install -g @earendil-works/pi-coding-agent@0.80.
|
|
116
|
+
npm install -g @earendil-works/pi-coding-agent@0.80.3
|
|
113
117
|
pi --version
|
|
114
118
|
|
|
115
119
|
mkdir -p ~/entwurf-smoke
|
|
@@ -126,7 +130,7 @@ Drift points:
|
|
|
126
130
|
`entwurf-bridge`, and links `~/.pi/agent/entwurf-targets.json` to the package's
|
|
127
131
|
`pi/entwurf-targets.json`.
|
|
128
132
|
- Older pi versions may silently miss the provider/extension surface. Use the
|
|
129
|
-
pinned floor (`>=0.80.
|
|
133
|
+
pinned floor (`>=0.80.3 <0.81`) for release verification.
|
|
130
134
|
- A host that only uses the external MCP bridge can skip this stage until it
|
|
131
135
|
needs `owned-outcome` spawn-bg resume or pi-native control sockets.
|
|
132
136
|
|
|
@@ -141,6 +145,19 @@ entwurf install-meta-bridge
|
|
|
141
145
|
entwurf doctor-meta-bridge
|
|
142
146
|
```
|
|
143
147
|
|
|
148
|
+
On an installed package (`.../node_modules/@junghanacs/entwurf`), the doctor must
|
|
149
|
+
not try to strip-types-run raw `.ts` helpers. In the output, check for these two
|
|
150
|
+
0.12.4 floor-regression signals:
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
ok full store scan: no corrupt records, duplicate nativeSessionId, body/filename drift, or backend↔wakeMode contradiction
|
|
154
|
+
ok check-entwurf-v2-surface: shipped surface source present; exhaustive source-shape gate is a repo/release invariant (not run under node_modules)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If either section reports `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`, the host
|
|
158
|
+
is still running a pre-0.12.4 package or a broken tarball. Reinstall the current
|
|
159
|
+
package and re-run `entwurf install-meta-bridge && entwurf doctor-meta-bridge`.
|
|
160
|
+
|
|
144
161
|
A plain external MCP host can call tools but is non-replyable. A garden-native
|
|
145
162
|
meta-session has a garden id, a mailbox, and a trusted sender marker; it can call
|
|
146
163
|
`entwurf_self`, receive mailbox wakeups, and be replied to by garden id.
|
|
@@ -157,7 +174,7 @@ source ~/.bashrc
|
|
|
157
174
|
claude login
|
|
158
175
|
|
|
159
176
|
cd ~/entwurf-smoke
|
|
160
|
-
pi --provider entwurf --model claude-sonnet-
|
|
177
|
+
pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only"
|
|
161
178
|
```
|
|
162
179
|
|
|
163
180
|
If the backend CLI fails directly (`claude -p "ping"`), fix that upstream first.
|
|
@@ -171,7 +188,7 @@ a raw pi-assigned uuid hard-exits before any model turn.
|
|
|
171
188
|
|
|
172
189
|
```bash
|
|
173
190
|
pi --session-id "$(entwurf new-session-id)" \
|
|
174
|
-
--entwurf-control --provider entwurf --model claude-sonnet-
|
|
191
|
+
--entwurf-control --provider entwurf --model claude-sonnet-5
|
|
175
192
|
# control socket: ~/.pi/entwurf-control/<garden-id>.sock
|
|
176
193
|
```
|
|
177
194
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* meta-bridge-store-doctor — fail-loud full scan for meta-session records.
|
|
4
|
+
*
|
|
5
|
+
* The store is the authority for native→garden lookup. Doctor must therefore
|
|
6
|
+
* refuse corrupt records, duplicate nativeSessionId authorities, and body ↔
|
|
7
|
+
* filename drift instead of auto-pruning or silently picking one.
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { parseMetaIdentity } from "../pi-extensions/lib/meta-session.js";
|
|
12
|
+
const dir = process.argv[2];
|
|
13
|
+
if (!dir) {
|
|
14
|
+
console.error("usage: node --experimental-strip-types scripts/meta-bridge-store-doctor.ts <meta-sessions-dir>");
|
|
15
|
+
process.exit(2);
|
|
16
|
+
}
|
|
17
|
+
const failures = [];
|
|
18
|
+
const nativeToFiles = new Map();
|
|
19
|
+
let scanned = 0;
|
|
20
|
+
if (!fs.existsSync(dir)) {
|
|
21
|
+
console.log(`meta-store scan ok: ${dir} does not exist yet (0 records)`);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
for (const filename of fs.readdirSync(dir).sort()) {
|
|
25
|
+
if (!filename.endsWith(".meta.json"))
|
|
26
|
+
continue;
|
|
27
|
+
scanned += 1;
|
|
28
|
+
const file = path.join(dir, filename);
|
|
29
|
+
try {
|
|
30
|
+
// dual-read (3D-4 commit1): parseMetaIdentity reads v1 AND v2 and normalizes,
|
|
31
|
+
// so doctor's gardenId/nativeSessionId checks survive the v2 cut.
|
|
32
|
+
const id = parseMetaIdentity(fs.readFileSync(file, "utf8"));
|
|
33
|
+
const expectedFilename = `${id.gardenId}.meta.json`;
|
|
34
|
+
if (filename !== expectedFilename) {
|
|
35
|
+
failures.push(`${filename}: body/filename drift — body gardenId=${id.gardenId}, expected filename ${expectedFilename}`);
|
|
36
|
+
}
|
|
37
|
+
const files = nativeToFiles.get(id.nativeSessionId) ?? [];
|
|
38
|
+
files.push(filename);
|
|
39
|
+
nativeToFiles.set(id.nativeSessionId, files);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
failures.push(`${filename}: ${err instanceof Error ? err.message : String(err)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const [nativeSessionId, files] of nativeToFiles.entries()) {
|
|
46
|
+
if (files.length > 1) {
|
|
47
|
+
failures.push(`duplicate nativeSessionId ${JSON.stringify(nativeSessionId)} in ${files.join(", ")} — authority ambiguity; prune manually`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (failures.length > 0) {
|
|
51
|
+
for (const failure of failures)
|
|
52
|
+
console.error(`FAIL: ${failure}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
console.log(`meta-store scan ok: ${scanned} record(s) scanned, no corrupt/duplicate/drift records`);
|
|
@@ -33,10 +33,18 @@
|
|
|
33
33
|
// Clear the root `exclude` (it filters out every `.ts`-extension lib file the
|
|
34
34
|
// bridge graph needs). Only node_modules must stay excluded.
|
|
35
35
|
"exclude": ["../../node_modules"],
|
|
36
|
-
//
|
|
37
|
-
// explicit `.js` import)
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
// the pi-lane-only acp/*
|
|
41
|
-
|
|
36
|
+
// The bridge boot entry (+ the dependency-free protocol.js it reaches via an
|
|
37
|
+
// explicit `.js` import) PLUS the doctor's store-scan helper. tsc auto-follows
|
|
38
|
+
// the import graph — STATIC imports AND the lazy
|
|
39
|
+
// `await import("./entwurf-preflight.ts")` — and emits exactly that closure,
|
|
40
|
+
// nothing more (the pi-lane-only acp/* stays out of the tarball).
|
|
41
|
+
//
|
|
42
|
+
// WHY store-doctor rides THIS build: meta-bridge-doctor.sh's full store scan
|
|
43
|
+
// must run from an INSTALLED package (under node_modules, where strip-types is
|
|
44
|
+
// refused) — the same node_modules boundary start.sh crosses. Its only repo
|
|
45
|
+
// import is pi-extensions/lib/meta-session.ts, which the bridge graph ALREADY
|
|
46
|
+
// emits here, so it adds ONE leaf JS (dist/scripts/meta-bridge-store-doctor.js)
|
|
47
|
+
// and ZERO new deps. It is NOT in index.ts's boot closure, so
|
|
48
|
+
// check-entwurf-bridge-pi-free (which walks the index eager closure) is unaffected.
|
|
49
|
+
"include": ["./src/index.ts", "../../protocol.js", "../../scripts/meta-bridge-store-doctor.ts"]
|
|
42
50
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junghanacs/entwurf",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4",
|
|
4
4
|
"description": "Garden-citizen dispatch substrate and meta-bridge for Claude Code, Codex, Antigravity, and pi harnesses.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -67,23 +67,23 @@
|
|
|
67
67
|
},
|
|
68
68
|
"packageManager": "pnpm@10.33.0",
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"@agentclientprotocol/claude-agent-acp": "0.
|
|
71
|
-
"@agentclientprotocol/sdk": "
|
|
70
|
+
"@agentclientprotocol/claude-agent-acp": "0.54.1",
|
|
71
|
+
"@agentclientprotocol/sdk": "1.1.0",
|
|
72
72
|
"@anthropic-ai/sdk": "0.100.1",
|
|
73
73
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
74
74
|
"zod": "^3.25.0 || ^4.0.0"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@earendil-works/pi-ai": ">=0.80.
|
|
78
|
-
"@earendil-works/pi-coding-agent": ">=0.80.
|
|
79
|
-
"@earendil-works/pi-tui": ">=0.80.
|
|
77
|
+
"@earendil-works/pi-ai": ">=0.80.3 <0.81",
|
|
78
|
+
"@earendil-works/pi-coding-agent": ">=0.80.3 <0.81",
|
|
79
|
+
"@earendil-works/pi-tui": ">=0.80.3 <0.81",
|
|
80
80
|
"typebox": "*"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@biomejs/biome": "^2.4.13",
|
|
84
|
-
"@earendil-works/pi-ai": "0.80.
|
|
85
|
-
"@earendil-works/pi-coding-agent": "0.80.
|
|
86
|
-
"@earendil-works/pi-tui": "0.80.
|
|
84
|
+
"@earendil-works/pi-ai": "0.80.3",
|
|
85
|
+
"@earendil-works/pi-coding-agent": "0.80.3",
|
|
86
|
+
"@earendil-works/pi-tui": "0.80.3",
|
|
87
87
|
"@types/node": "^24.3.0",
|
|
88
88
|
"husky": "^9.1.7",
|
|
89
89
|
"typescript": "^6.0.2"
|
package/pi/entwurf-targets.json
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "Entwurf Target Registry — exact (provider, model) allowlist. SSOT for what can be spawned via entwurf. See entwurf/AGENTS.md Entwurf Orchestration. Resume path intentionally bypasses this registry per Identity Preservation Rule.",
|
|
3
3
|
"$notes": {
|
|
4
|
-
"gpt-5.5": "High-end frontier target with 400K native codex context. Cost: ~$5 input / $30 output per 1M tokens on this tier — ~6x gpt-5.4. Do not make it the default. Use explicitly for long-context / high-quality work only.
|
|
5
|
-
"bareResolution": "Each bare model id resolves
|
|
4
|
+
"gpt-5.5": "High-end frontier target with 400K native codex context. Cost: ~$5 input / $30 output per 1M tokens on this tier — ~6x gpt-5.4. Do not make it the default. Use explicitly for long-context / high-quality work only.",
|
|
5
|
+
"bareResolution": "Each bare Codex model id resolves through the native openai-codex provider. Bare `gpt-5.5` -> openai-codex/gpt-5.5. ACP Codex is not on this surface until the ACP backend is implemented.",
|
|
6
6
|
"gemini": "Gemini ACP targets are routed exclusively through entwurf's `gemini --acp` backend; the host pi removed its built-in google provider in v0.71.0. ACP entries are `explicitOnly` to keep the entwurf surface honest — there is currently no native pi alternative to disambiguate against, but the flag keeps the policy stable if pi reintroduces a google provider later. 3.1 Pro is the subscription-backed high-quality ACP target. Flash / 2.5 routing through ACP is intentionally not on this surface."
|
|
7
7
|
},
|
|
8
8
|
"entwurfTargets": [
|
|
9
|
-
{ "provider": "entwurf", "model": "claude-sonnet-
|
|
9
|
+
{ "provider": "entwurf", "model": "claude-sonnet-5", "enabled": true },
|
|
10
10
|
{ "provider": "entwurf", "model": "claude-opus-4-8", "enabled": true },
|
|
11
11
|
|
|
12
12
|
{ "provider": "openai-codex", "model": "gpt-5.4", "enabled": true },
|
|
13
13
|
{ "provider": "openai-codex", "model": "gpt-5.5", "enabled": true },
|
|
14
14
|
|
|
15
|
-
{ "provider": "entwurf", "model": "gpt-5.4", "enabled": true, "explicitOnly": true },
|
|
16
|
-
{ "provider": "entwurf", "model": "gpt-5.5", "enabled": true, "explicitOnly": true },
|
|
17
|
-
|
|
18
15
|
{ "provider": "entwurf", "model": "gemini-3.1-pro-preview", "enabled": true, "explicitOnly": true }
|
|
19
16
|
]
|
|
20
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ACP client adapter — the ONE place that touches the @agentclientprotocol/sdk
|
|
2
|
-
//
|
|
2
|
+
// 1.1 fluent surface (`client({ name }).connect(stream)`).
|
|
3
3
|
//
|
|
4
4
|
// The wire SDK deprecated the `new ClientSideConnection(toClient, stream)`
|
|
5
5
|
// constructor in favour of the fluent `client()` builder. The two have
|
|
@@ -52,7 +52,7 @@ export interface AcpClientHandlers {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Production factory — wrap the SDK
|
|
55
|
+
* Production factory — wrap the SDK 1.1 fluent `client()` into the
|
|
56
56
|
* `AcpConnectionLike` seam the backend (and the live smokes) drive.
|
|
57
57
|
*
|
|
58
58
|
* Client-side handlers register by ACP method name; agent-side calls go through
|
|
@@ -50,18 +50,17 @@ export const ENTWURF_ACP_NO_AUTH_SENTINEL = "entwurf-no-auth";
|
|
|
50
50
|
// both axes (protocol smoke + agent interview) — do not extend casually.
|
|
51
51
|
// Exported so the claude backend adapter (backend-adapter.ts) can answer
|
|
52
52
|
// `routeModel` without re-deriving the set from curatedClaudeModels().
|
|
53
|
-
export const SUPPORTED_ANTHROPIC_MODEL_IDS = ["claude-sonnet-
|
|
53
|
+
export const SUPPORTED_ANTHROPIC_MODEL_IDS = ["claude-sonnet-5", "claude-opus-4-8"] as const;
|
|
54
54
|
|
|
55
55
|
/** The anchor model whose absence is a hard registry regression, not a soft skip. */
|
|
56
56
|
export const CURATED_ANCHOR_MODEL_ID = "claude-opus-4-8";
|
|
57
57
|
|
|
58
|
-
// Anthropic's registry reports 1M for
|
|
59
|
-
// entwurf surface
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
58
|
+
// Anthropic's registry reports 1M for both Sonnet 5 and Opus 4.8, and the
|
|
59
|
+
// entwurf surface now exposes the full 1M for BOTH. Sonnet 5's 1M window is the
|
|
60
|
+
// whole point of the 0.12.3 bump — it is the compact-free long-context floor the
|
|
61
|
+
// earlier 200K Sonnet cap could not provide. We still clamp to a 1M ceiling so a
|
|
62
|
+
// future registry value can't silently inflate the surface past what we verify.
|
|
63
63
|
const CLAUDE_CONTEXT_DEFAULT = 1_000_000;
|
|
64
|
-
const CLAUDE_SONNET_DEFAULT = 200_000;
|
|
65
64
|
|
|
66
65
|
// `getModels("anthropic")` reads the static builtin model catalog only — no env
|
|
67
66
|
// read, no credential access, no network — preserving the #26 auth-boundary
|
|
@@ -79,8 +78,7 @@ function requireRegistryModel(models: readonly RegistryModel[], id: string): Reg
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
function claudeContextWindow(model: { id: string; contextWindow: number }): number {
|
|
82
|
-
|
|
83
|
-
return Math.min(model.contextWindow, cap);
|
|
81
|
+
return Math.min(model.contextWindow, CLAUDE_CONTEXT_DEFAULT);
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
/**
|