anchor-ai-sdk 0.1.4 → 0.1.6

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.
Files changed (49) hide show
  1. package/README.md +21 -15
  2. package/dist/agents/coding/index.d.ts +5 -0
  3. package/dist/agents/coding/index.d.ts.map +1 -1
  4. package/dist/agents/coding/index.js +7 -0
  5. package/dist/agents/coding/index.js.map +1 -1
  6. package/dist/agents/coding/prompts/index.js +1 -1
  7. package/dist/agents/coding/prompts/index.js.map +1 -1
  8. package/dist/agents/types.d.ts +5 -0
  9. package/dist/agents/types.d.ts.map +1 -1
  10. package/dist/engine/budgets.d.ts +10 -0
  11. package/dist/engine/budgets.d.ts.map +1 -1
  12. package/dist/engine/budgets.js +11 -1
  13. package/dist/engine/budgets.js.map +1 -1
  14. package/dist/engine/elision.d.ts +55 -0
  15. package/dist/engine/elision.d.ts.map +1 -0
  16. package/dist/engine/elision.js +78 -0
  17. package/dist/engine/elision.js.map +1 -0
  18. package/dist/engine/events.d.ts +5 -1
  19. package/dist/engine/events.d.ts.map +1 -1
  20. package/dist/engine/loop.d.ts.map +1 -1
  21. package/dist/engine/loop.js +222 -18
  22. package/dist/engine/loop.js.map +1 -1
  23. package/dist/engine/phase-discipline.d.ts +15 -0
  24. package/dist/engine/phase-discipline.d.ts.map +1 -0
  25. package/dist/engine/phase-discipline.js +9 -0
  26. package/dist/engine/phase-discipline.js.map +1 -0
  27. package/dist/engine/types.d.ts +54 -0
  28. package/dist/engine/types.d.ts.map +1 -1
  29. package/dist/llm/openai-compatible.d.ts.map +1 -1
  30. package/dist/llm/openai-compatible.js +8 -0
  31. package/dist/llm/openai-compatible.js.map +1 -1
  32. package/dist/llm/types.d.ts +4 -0
  33. package/dist/llm/types.d.ts.map +1 -1
  34. package/dist/sandbox/e2b/exec.d.ts +30 -0
  35. package/dist/sandbox/e2b/exec.d.ts.map +1 -0
  36. package/dist/sandbox/e2b/exec.js +53 -0
  37. package/dist/sandbox/e2b/exec.js.map +1 -0
  38. package/dist/sandbox/e2b/index.d.ts +91 -8
  39. package/dist/sandbox/e2b/index.d.ts.map +1 -1
  40. package/dist/sandbox/e2b/index.js +449 -2
  41. package/dist/sandbox/e2b/index.js.map +1 -1
  42. package/dist/sandbox/index.d.ts +1 -1
  43. package/dist/sandbox/local/index.d.ts.map +1 -1
  44. package/dist/sandbox/local/index.js +4 -3
  45. package/dist/sandbox/local/index.js.map +1 -1
  46. package/dist/sandbox/types.d.ts +5 -4
  47. package/dist/sandbox/types.d.ts.map +1 -1
  48. package/dist/sandbox/types.js.map +1 -1
  49. package/package.json +11 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  <p align="center">
11
11
  <strong>Loop-first, sandbox-first agent harness SDK.</strong><br />
12
- Give it a task and a machine — it reasons, runs tools, checks its own work, and keeps the receipts.
12
+ Give it a task and a machine; it reasons, runs tools, checks its own work, and keeps the receipts.
13
13
  </p>
14
14
 
15
15
  <p align="center">
@@ -29,7 +29,7 @@ trust. Anchor ships the hard parts.
29
29
  `AgentResult.evidence`; `run_tests` stamps the tree hash it ran against and
30
30
  `latestEvidenceForTree` ties a green run to the *exact* bytes (fail-closed
31
31
  when the tree can't be inspected). The engine carries evidence and never
32
- reads success out of a confident sentence — what to gate on it is your
32
+ reads success out of a confident sentence; what to gate on it is your
33
33
  policy, not a hidden wall.
34
34
  - **Durable by construction.** Conversation, workspace, and the agent's own
35
35
  notes survive folds, restarts, and budget deaths; the SDK ships the
@@ -43,16 +43,16 @@ trust. Anchor ships the hard parts.
43
43
 
44
44
  | | |
45
45
  | --- | --- |
46
- | **Agent loop with dials** | Budgets (steps / tokens / USD), repeated-call detection, silent-tool advisories — guardrails on by default, each with an off switch. Phases describe the approach — never a second gated execution engine. |
46
+ | **Agent loop with dials** | Budgets (steps / tokens / USD), repeated-call detection, silent-tool and verbose-turn advisories, a per-call output cap (16k, nudge at 8k; a capped prose turn continues once instead of ending), and assistant-text elision (20k replay, 12k head-only when capped, spilled and pointed at); guardrails on by default, each with an off switch. Phases describe the approach, never a second gated execution engine. |
47
47
  | **Streaming by default** | One wire path: every model call streams. Text and reasoning deltas, tool calls, compaction, checkpoints, and finishes all arrive as typed events. |
48
48
  | **Durable memory** | `ThreadStore` carries conversation across runs; compaction is derived from the model's *real* context window; reasoning is journaled but never re-sent. |
49
49
  | **Notes & spill storage** | A reserved `.anchor/notes.md` (git-excluded, checkpoint-carried) is the agent's durable memory across folds; oversized tool output spills to sandbox files and stays addressable instead of vanishing. |
50
- | **Revival** | A dying run leaves a handoff (`request_revival`); `planRevival` + `ThreadBudget` decide how to fund the next run — **same task, phase, and budget** — and when the thread's caps are spent, a human gets the note, quoting the agent's own words on what remains. |
50
+ | **Revival** | A dying run leaves a handoff (`request_revival`); `planRevival` + `ThreadBudget` decide how to fund the next run; **same task, phase, and budget**, and when the thread's caps are spent, a human gets the note, quoting the agent's own words on what remains. |
51
51
  | **Snapshots & resume** | A pluggable snapshot hook (git-backed by default, push optional), phase-boundary pauses, heartbeats and cross-process cancel polling owned by the engine. |
52
- | **Traces you can replay** | One fanout: one sequence number, redaction applied before *every* sink — NDJSON file, database rows, and a live projector share the same ordering. |
53
- | **Sandbox plugins** | One `SandboxProvider` contract: Heyo microVMs, Docker, local. Capabilities are promises — the conformance suite holds adapters to them. Store-backed sessions give adopt-and-fallback continuity for free. |
52
+ | **Traces you can replay** | One fanout: one sequence number, redaction applied before *every* sink; NDJSON file, database rows, and a live projector share the same ordering. |
53
+ | **Sandbox plugins** | One `SandboxProvider` contract: Heyo microVMs, Docker, local. Capabilities are promises; the conformance suite holds adapters to them. Store-backed sessions give adopt-and-fallback continuity for free. |
54
54
  | **Typed handoffs** | `finish({ handoff })` is shaped by *your* JSON schema; the engine declares the parameter, carries the object, and never interprets it. |
55
- | **Priced & windowed models** | `llmFromCatalog` reads live prices and the genuine context window from the provider catalog — budgets and compaction configure themselves correctly. |
55
+ | **Priced & windowed models** | `llmFromCatalog` reads live prices and the genuine context window from the provider catalog; budgets and compaction configure themselves correctly. |
56
56
 
57
57
  ## Ten lines to a working agent
58
58
 
@@ -98,7 +98,7 @@ try {
98
98
  }
99
99
  ```
100
100
 
101
- Runnable versions of both snippets live in [`examples/`](https://github.com/hrithikkoduri/anchor-ai-sdk/tree/main/examples) — including
101
+ Runnable versions of both snippets live in [`examples/`](https://github.com/hrithikkoduri/anchor-ai-sdk/tree/main/examples), including
102
102
  a non-coding agent (its own strategy and tool, no sandbox).
103
103
 
104
104
  ## Providers
@@ -107,31 +107,37 @@ a non-coding agent (its own strategy and tool, no sandbox).
107
107
  | --- | --- | --- |
108
108
  | `anchor-ai-sdk/sandbox/heyo` | Heyo Cloud microVMs (Firecracker) | production path; conformance + live tests |
109
109
  | `anchor-ai-sdk/sandbox/docker` | containers on the local daemon | conformance-tested in CI |
110
+ | `anchor-ai-sdk/sandbox/e2b` | E2B cloud sandboxes (remote) | conformance-tested live (`base` template); opt-in in CI |
110
111
  | `anchor-ai-sdk/sandbox/local` | this host, **no isolation** | dev / CI only |
111
- | — | E2B, Daytona | planned |
112
+ | n/a | Daytona | planned |
113
+
114
+ E2B boots a **template**, not an arbitrary Docker image at create time: pass
115
+ `template` (or let `SandboxSpec.image` name one) and build it with the tools
116
+ the task needs. Pause/resume powers retain/adopt, and native sandbox forking
117
+ powers `fork()`.
112
118
 
113
119
  A backend is "done" when `runSandboxConformance(provider)` from
114
- `anchor-ai-sdk/testing` passes — exec fidelity, kill deadlines, env secrets,
120
+ `anchor-ai-sdk/testing` passes: exec fidelity, kill deadlines, env secrets,
115
121
  checkpoints, retain/adopt, git identity, pushes, and `fork` where declared.
116
122
  See [`src/sandbox/README.md`](https://github.com/hrithikkoduri/anchor-ai-sdk/blob/main/src/sandbox/README.md) for the provider guide.
117
123
 
118
124
  ## Proof, not promises
119
125
 
120
126
  - **Tests:** the engine, tools, trace layer, and every provider scenario run
121
- in CI — local conformance always, Docker conformance on a purpose-built
127
+ in CI: local conformance always, Docker conformance on a purpose-built
122
128
  image. Live microVM conformance is opt-in with your own Heyo credentials
123
129
  (the suite skips without them).
124
- - **Genericity guards:** executable rules keep the package consumer-neutral —
130
+ - **Genericity guards:** executable rules keep the package consumer-neutral:
125
131
  no product nouns, no env reads, SDKs behind subpaths. They run in the same
126
132
  suite as everything else.
127
- - **Evaluation:** Anchor vs mini-swe-agent on SWE-bench Lite — same
128
- container, same model, same official grader — resolved the same 7/10 at
133
+ - **Evaluation:** Anchor vs mini-swe-agent on SWE-bench Lite (same
134
+ container, same model, same official grader), resolved the same 7/10 at
129
135
  roughly **one-third of the cost**
130
136
  ([`evals/benchmarks/swe-bench/results/comparison.md`](https://github.com/hrithikkoduri/anchor-ai-sdk/blob/main/evals/benchmarks/swe-bench/results/comparison.md)).
131
137
 
132
138
  ## Status
133
139
 
134
- **Early alpha (0.x).** The API will move before 1.0 — pin exact versions. The
140
+ **Early alpha (0.x).** The API will move before 1.0, so pin exact versions. The
135
141
  [`DECISIONS.md`](https://github.com/hrithikkoduri/anchor-ai-sdk/blob/main/DECISIONS.md) is the engineering log: every API has a written
136
142
  reason, and the reasons moved with the code when this repo was extracted from
137
143
  its monorepo.
@@ -8,9 +8,14 @@ export { codingPhases } from "./phases.js";
8
8
  * The coding agent — strategy + toolbox. Pass `testCommand` when the repo's
9
9
  * canonical suite is known (CLI or repo config); otherwise run_tests detects
10
10
  * one; either way run_tests tags the run as the repo's full-suite evidence.
11
+ *
12
+ * `maxOutputTokens` overrides the engine's per-call cap for this bundle (see
13
+ * #75). Left unset, the engine default governs; an explicit
14
+ * `EngineOptions.maxOutputTokens` still wins.
11
15
  */
12
16
  export declare function createCodingAgent(opts?: {
13
17
  testCommand?: string;
18
+ maxOutputTokens?: number | false;
14
19
  }): Agent;
15
20
  /** The zero-config coding agent — detection instead of a configured suite. */
16
21
  export declare const codingAgent: Agent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/coding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,KAAK,CAM5E;AAED,8EAA8E;AAC9E,eAAO,MAAM,WAAW,EAAE,KAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/coding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAAO,GACpE,KAAK,CASP;AAED,8EAA8E;AAC9E,eAAO,MAAM,WAAW,EAAE,KAA2B,CAAC"}
@@ -8,12 +8,19 @@ export { codingPhases } from "./phases.js";
8
8
  * The coding agent — strategy + toolbox. Pass `testCommand` when the repo's
9
9
  * canonical suite is known (CLI or repo config); otherwise run_tests detects
10
10
  * one; either way run_tests tags the run as the repo's full-suite evidence.
11
+ *
12
+ * `maxOutputTokens` overrides the engine's per-call cap for this bundle (see
13
+ * #75). Left unset, the engine default governs; an explicit
14
+ * `EngineOptions.maxOutputTokens` still wins.
11
15
  */
12
16
  export function createCodingAgent(opts = {}) {
13
17
  return {
14
18
  name: "coding",
15
19
  strategy: codingStrategy,
16
20
  tools: createCodingTools(opts),
21
+ ...(opts.maxOutputTokens !== undefined
22
+ ? { maxOutputTokens: opts.maxOutputTokens }
23
+ : {}),
17
24
  };
18
25
  }
19
26
  /** The zero-config coding agent — detection instead of a configured suite. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agents/coding/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAe,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAI,GAA6B,EAAE;IACnE,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAU,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agents/coding/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAe,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAI,GAA+D,EAAE;IAErE,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS;YACpC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE;YAC3C,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,WAAW,GAAU,iBAAiB,EAAE,CAAC"}
@@ -28,7 +28,7 @@ export function buildCodingPrompt(options = {}) {
28
28
  {
29
29
  title: "Approach phases",
30
30
  body: [
31
- "These describe your approach, not prerequisites. Choose the phases that fit, skip or revisit them when appropriate, and conclude from any phase. When your work shifts between kinds of activity — investigating, changing code, verifying, answering — call set_phase once to record the new phase; it labels your approach (it never authorizes or blocks anything) and keeps the thread's timeline honest.",
31
+ "These describe your approach, not prerequisites. Choose the phases that fit, skip or revisit them when appropriate, and conclude from any phase. When your work shifts between kinds of activity — investigating, changing code, verifying, answering — call set_phase to record the new phase and keep the thread's timeline honest.",
32
32
  ...phases.map((phase) => `- ${phase.id}: ${phase.goal}${phase.guidance ? ` ${phase.guidance}` : ""}`),
33
33
  ].join("\n"),
34
34
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/agents/coding/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AActD;+EAC+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,OAAO,GAAwB,EAAE;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC;IAC9C,OAAO;QACL,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS,EAAE;QAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE;QAC7C,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE;QACzD;YACE,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,OAAO,CAAC,cAAc,IAAI,cAAc;SAC/C;QACD;YACE,KAAK,EAAE,yBAAyB;YAChC,IAAI,EAAE,OAAO,CAAC,YAAY,IAAI,YAAY;SAC3C;QACD;YACE,KAAK,EAAE,eAAe;YACtB,IAAI,EACF,0FAA0F;gBAC1F,sFAAsF;gBACtF,sEAAsE;gBACtE,2FAA2F;SAC9F;QACD;YACE,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE;gBACJ,+YAA+Y;gBAC/Y,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9E;aACF,CAAC,IAAI,CAAC,IAAI,CAAC;SACb;QACD,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC;QACrC;YACE,KAAK,EAAE,2CAA2C;YAClD,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC5B;QACD;YACE,KAAK,EAAE,sDAAsD;YAC7D,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC5B;KACF;SACE,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;SACvD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/agents/coding/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AActD;+EAC+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,OAAO,GAAwB,EAAE;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC;IAC9C,OAAO;QACL,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS,EAAE;QAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE;QAC7C,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE;QACzD;YACE,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE,OAAO,CAAC,cAAc,IAAI,cAAc;SAC/C;QACD;YACE,KAAK,EAAE,yBAAyB;YAChC,IAAI,EAAE,OAAO,CAAC,YAAY,IAAI,YAAY;SAC3C;QACD;YACE,KAAK,EAAE,eAAe;YACtB,IAAI,EACF,0FAA0F;gBAC1F,sFAAsF;gBACtF,sEAAsE;gBACtE,2FAA2F;SAC9F;QACD;YACE,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE;gBACJ,uUAAuU;gBACvU,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9E;aACF,CAAC,IAAI,CAAC,IAAI,CAAC;SACb;QACD,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC;QACrC;YACE,KAAK,EAAE,2CAA2C;YAClD,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC5B;QACD;YACE,KAAK,EAAE,sDAAsD;YAC7D,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC5B;KACF;SACE,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACxC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;SACvD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
@@ -19,5 +19,10 @@ export interface Agent {
19
19
  strategy: AgentStrategy;
20
20
  /** Capabilities the run may call — a curated subset of the tool registry. */
21
21
  tools: Tool[];
22
+ /**
23
+ * Per-call output cap this bundle suggests (see `EngineOptions.maxOutputTokens`).
24
+ * An explicit engine option wins; absent, the engine default applies.
25
+ */
26
+ maxOutputTokens?: number | false;
22
27
  }
23
28
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,WAAW,KAAK;IACpB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,QAAQ,EAAE,aAAa,CAAC;IACxB,6EAA6E;IAC7E,KAAK,EAAE,IAAI,EAAE,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,WAAW,KAAK;IACpB,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,QAAQ,EAAE,aAAa,CAAC;IACxB,6EAA6E;IAC7E,KAAK,EAAE,IAAI,EAAE,CAAC;IACd;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAClC"}
@@ -13,6 +13,16 @@ export interface BudgetLimits {
13
13
  maxUsd: number;
14
14
  }
15
15
  export declare const DEFAULT_BUDGET_LIMITS: BudgetLimits;
16
+ /**
17
+ * Per-call cap on one model response — reasoning, text and tool calls
18
+ * together. The per-run budgets below only notice an overspend *after* the
19
+ * call returns, so a single degenerate generation can burn minutes and tens
20
+ * of thousands of tokens before anything reacts. This bounds one call.
21
+ *
22
+ * 16k leaves ample room for normal work (typical turns here run ~1k) while
23
+ * cutting off a runaway. A capped response ends with finishReason "length".
24
+ */
25
+ export declare const DEFAULT_MAX_OUTPUT_TOKENS = 16000;
16
26
  export interface BudgetExceeded {
17
27
  kind: "steps" | "tokens" | "usd";
18
28
  detail: string;
@@ -1 +1 @@
1
- {"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../../src/engine/budgets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,YAAY,SAAK;IACjB,gBAAgB,SAAK;IACrB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,SAAK;IACZ,UAAU,UAAQ;IAElB,YAAY,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,EAE7C;IAED,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAS5B;IAED,WAAW,IAAI,MAAM,CAEpB;IAED,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAc7C;CACF"}
1
+ {"version":3,"file":"budgets.d.ts","sourceRoot":"","sources":["../../src/engine/budgets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,YAAY,SAAK;IACjB,gBAAgB,SAAK;IACrB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,OAAO,SAAK;IACZ,UAAU,UAAQ;IAElB,YAAY,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM,EAE7C;IAED,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAS5B;IAED,WAAW,IAAI,MAAM,CAEpB;IAED,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAc7C;CACF"}
@@ -1,8 +1,18 @@
1
1
  export const DEFAULT_BUDGET_LIMITS = {
2
2
  maxSteps: 40,
3
- maxTokens: 1_500_000,
3
+ maxTokens: 3_000_000,
4
4
  maxUsd: 5,
5
5
  };
6
+ /**
7
+ * Per-call cap on one model response — reasoning, text and tool calls
8
+ * together. The per-run budgets below only notice an overspend *after* the
9
+ * call returns, so a single degenerate generation can burn minutes and tens
10
+ * of thousands of tokens before anything reacts. This bounds one call.
11
+ *
12
+ * 16k leaves ample room for normal work (typical turns here run ~1k) while
13
+ * cutting off a runaway. A capped response ends with finishReason "length".
14
+ */
15
+ export const DEFAULT_MAX_OUTPUT_TOKENS = 16_000;
6
16
  export class BudgetTracker {
7
17
  limits;
8
18
  promptTokens = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"budgets.js","sourceRoot":"","sources":["../../src/engine/budgets.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,CAAC;CACV,CAAC;AAOF,MAAM,OAAO,aAAa;IACf,MAAM,CAAe;IAC9B,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IACrB,eAAe,CAAqB;IACpC,OAAO,GAAG,CAAC,CAAC;IACZ,UAAU,GAAG,IAAI,CAAC;IAElB,YAAY,MAAM,GAA0B,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,qBAAqB,EAAE,GAAG,MAAM,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,KAAe;QACpB,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS;YAAE,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;QACpH,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC;IACnD,CAAC;IAED,6EAA6E;IAC7E,QAAQ,CAAC,KAAa;QACpB,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,0BAA0B,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,SAAS,EAAE,CAAC;QACrG,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAChD,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,2BAA2B,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,UAAU;aACzF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;QACjH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"budgets.js","sourceRoot":"","sources":["../../src/engine/budgets.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,CAAC;CACV,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAOhD,MAAM,OAAO,aAAa;IACf,MAAM,CAAe;IAC9B,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAG,CAAC,CAAC;IACrB,eAAe,CAAqB;IACpC,OAAO,GAAG,CAAC,CAAC;IACZ,UAAU,GAAG,IAAI,CAAC;IAElB,YAAY,MAAM,GAA0B,EAAE;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,qBAAqB,EAAE,GAAG,MAAM,EAAE,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,KAAe;QACpB,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS;YAAE,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;QACpH,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC;IACnD,CAAC;IAED,6EAA6E;IAC7E,QAAQ,CAAC,KAAa;QACpB,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,0BAA0B,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,SAAS,EAAE,CAAC;QACrG,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAChD,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,2BAA2B,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,UAAU;aACzF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YAC1D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;QACjH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Assistant-text elision — the history boundary for the model's own words.
3
+ *
4
+ * Tool output has had a boundary since the spill work: `truncate.ts` keeps a
5
+ * head and a tail, and saves the full text so the clipped middle stays
6
+ * addressable. The assistant's own replies had none, so one runaway turn
7
+ * (108,578 chars in the GLM run behind #75) was replayed verbatim on every
8
+ * later call: the model re-reading its own essay, and paying for it each
9
+ * time. At ~27k tokens a replay across ~29 remaining calls, that single turn
10
+ * supplied roughly half the run's billed tokens.
11
+ *
12
+ * Same shape here, with three differences:
13
+ *
14
+ * 1. It bounds the MODEL'S VIEW, not the stored transcript. The loop keeps
15
+ * `messages` intact (persistence, replay, audit) and sends this
16
+ * projection to the provider.
17
+ * 2. A capped turn (finishReason "length") keeps only its head. Its tail is
18
+ * mid-token by construction, so the intent at the start is the only
19
+ * signal worth replaying.
20
+ * 3. The full reply is spilled to scratch and pointed at, so the omission is
21
+ * recoverable rather than final (#77).
22
+ */
23
+ import { type Sandbox } from "../sandbox/types.js";
24
+ /** Replay budget for one assistant reply, in chars (≈ 5k tokens at 4 chars/token). */
25
+ export declare const DEFAULT_MAX_ASSISTANT_CHARS = 20000;
26
+ /**
27
+ * A capped turn is incomplete: its tail stops mid-token, so only its head is
28
+ * worth replaying. This is the dial for that tighter budget — deliberately
29
+ * below `DEFAULT_MAX_ASSISTANT_CHARS`. 12k CHARS, not tokens: about 3k tokens,
30
+ * a fraction of a capped turn, so a chopped essay is not replayed in full.
31
+ */
32
+ export declare const DEFAULT_TRUNCATED_REPLY_CHARS = 12000;
33
+ export interface ElidedReply {
34
+ text: string;
35
+ omittedChars: number;
36
+ }
37
+ export interface ElideOptions {
38
+ /** Keep a tail. False for a capped turn, whose tail is mid-token. */
39
+ tail?: boolean;
40
+ /** Appended to the marker — e.g. where the full reply was spilled. */
41
+ note?: string;
42
+ }
43
+ /**
44
+ * Head + marker + tail, sized to `budget`. Under budget → the text unchanged.
45
+ * The split mirrors tool output (60/40): openings carry intent, endings carry
46
+ * the conclusion, and the middle of a ramble is repetition.
47
+ */
48
+ export declare function elideReply(text: string, budget: number, opts?: ElideOptions): ElidedReply;
49
+ /**
50
+ * Best-effort: save the full reply to the sandbox's scratch dir and return its
51
+ * path, so an elided middle can be read back. Any failure returns undefined
52
+ * and leaves the caller with plain elision — never breaks the turn.
53
+ */
54
+ export declare function spillReply(sandbox: Sandbox | undefined, text: string): Promise<string | undefined>;
55
+ //# sourceMappingURL=elision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elision.d.ts","sourceRoot":"","sources":["../../src/engine/elision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAO,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAExD,sFAAsF;AACtF,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAKpD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,YAAiB,GACtB,WAAW,CAgBb;AAID;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe7B"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Assistant-text elision — the history boundary for the model's own words.
3
+ *
4
+ * Tool output has had a boundary since the spill work: `truncate.ts` keeps a
5
+ * head and a tail, and saves the full text so the clipped middle stays
6
+ * addressable. The assistant's own replies had none, so one runaway turn
7
+ * (108,578 chars in the GLM run behind #75) was replayed verbatim on every
8
+ * later call: the model re-reading its own essay, and paying for it each
9
+ * time. At ~27k tokens a replay across ~29 remaining calls, that single turn
10
+ * supplied roughly half the run's billed tokens.
11
+ *
12
+ * Same shape here, with three differences:
13
+ *
14
+ * 1. It bounds the MODEL'S VIEW, not the stored transcript. The loop keeps
15
+ * `messages` intact (persistence, replay, audit) and sends this
16
+ * projection to the provider.
17
+ * 2. A capped turn (finishReason "length") keeps only its head. Its tail is
18
+ * mid-token by construction, so the intent at the start is the only
19
+ * signal worth replaying.
20
+ * 3. The full reply is spilled to scratch and pointed at, so the omission is
21
+ * recoverable rather than final (#77).
22
+ */
23
+ import { shq } from "../sandbox/types.js";
24
+ /** Replay budget for one assistant reply, in chars (≈ 5k tokens at 4 chars/token). */
25
+ export const DEFAULT_MAX_ASSISTANT_CHARS = 20_000;
26
+ /**
27
+ * A capped turn is incomplete: its tail stops mid-token, so only its head is
28
+ * worth replaying. This is the dial for that tighter budget — deliberately
29
+ * below `DEFAULT_MAX_ASSISTANT_CHARS`. 12k CHARS, not tokens: about 3k tokens,
30
+ * a fraction of a capped turn, so a chopped essay is not replayed in full.
31
+ */
32
+ export const DEFAULT_TRUNCATED_REPLY_CHARS = 12_000;
33
+ /** Absurd payloads are not worth a write; elide without a pointer. */
34
+ const SPILL_MAX_CHARS = 4_000_000;
35
+ /**
36
+ * Head + marker + tail, sized to `budget`. Under budget → the text unchanged.
37
+ * The split mirrors tool output (60/40): openings carry intent, endings carry
38
+ * the conclusion, and the middle of a ramble is repetition.
39
+ */
40
+ export function elideReply(text, budget, opts = {}) {
41
+ if (text.length <= budget)
42
+ return { text, omittedChars: 0 };
43
+ const keepTail = opts.tail ?? true;
44
+ const headChars = keepTail ? Math.floor(budget * 0.6) : budget;
45
+ const tailChars = keepTail ? budget - headChars : 0;
46
+ const omittedChars = text.length - headChars - tailChars;
47
+ const marker = `\n[... ${omittedChars} chars of this reply were omitted from the replayed history` +
48
+ `${opts.note ? `; ${opts.note}` : ""} ...]\n`;
49
+ return {
50
+ text: text.slice(0, headChars) +
51
+ marker +
52
+ (tailChars > 0 ? text.slice(text.length - tailChars) : ""),
53
+ omittedChars,
54
+ };
55
+ }
56
+ let spillSeq = 0;
57
+ /**
58
+ * Best-effort: save the full reply to the sandbox's scratch dir and return its
59
+ * path, so an elided middle can be read back. Any failure returns undefined
60
+ * and leaves the caller with plain elision — never breaks the turn.
61
+ */
62
+ export async function spillReply(sandbox, text) {
63
+ if (!sandbox || text.length > SPILL_MAX_CHARS)
64
+ return undefined;
65
+ const file = `${sandbox.scratch}/out/reply-${Date.now().toString(36)}${(spillSeq++).toString(36)}.txt`;
66
+ const dir = file.slice(0, file.lastIndexOf("/"));
67
+ try {
68
+ const b64 = Buffer.from(text, "utf8").toString("base64");
69
+ const write = await sandbox.exec(`mkdir -p ${shq(dir)} && printf %s ${shq(b64)} | base64 -d > ${shq(file)}`, { timeoutSecs: 120 });
70
+ if (write.exitCode !== 0)
71
+ return undefined;
72
+ }
73
+ catch {
74
+ return undefined;
75
+ }
76
+ return file;
77
+ }
78
+ //# sourceMappingURL=elision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elision.js","sourceRoot":"","sources":["../../src/engine/elision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,GAAG,EAAgB,MAAM,qBAAqB,CAAC;AAExD,sFAAsF;AACtF,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,MAAM,CAAC;AAEpD,sEAAsE;AACtE,MAAM,eAAe,GAAG,SAAS,CAAC;AAclC;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,MAAc,EACd,IAAI,GAAiB,EAAE;IAEvB,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IACnC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACzD,MAAM,MAAM,GACV,UAAU,YAAY,6DAA6D;QACnF,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;IAChD,OAAO;QACL,IAAI,EACF,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;YACxB,MAAM;YACN,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,YAAY;KACb,CAAC;AACJ,CAAC;AAED,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEjB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAA4B,EAC5B,IAAY;IAEZ,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,cAAc,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC;IACvG,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAC9B,YAAY,GAAG,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,IAAI,CAAC,EAAE,EAC1E,EAAE,WAAW,EAAE,GAAG,EAAE,CACrB,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -46,6 +46,10 @@ export type AgentEvent = {
46
46
  toolCallsCount: number;
47
47
  usage: LLMUsage;
48
48
  latencyMs: number;
49
+ /** Model id the provider said it served, when the response carried one. */
50
+ model?: string;
51
+ /** Upstream name, when a gateway reported one. */
52
+ provider?: string;
49
53
  } | {
50
54
  type: "tool_call";
51
55
  phase: string;
@@ -85,7 +89,7 @@ export type AgentEvent = {
85
89
  /** Non-blocking runtime guidance (e.g. the materialization advisory).
86
90
  * Advisory events never gate actions or end runs. */
87
91
  type: "advisory";
88
- kind: "materialization_nudge" | "budget_warning" | "snapshot_failed";
92
+ kind: "materialization_nudge" | "budget_warning" | "snapshot_failed" | "output_truncated" | "output_cap_continue" | "verbose_turn" | "assistant_text_elided" | "prose_checkpoint" | "repeated_call" | "empty_turn";
89
93
  detail: string;
90
94
  } | {
91
95
  /** The dying run's handoff: what it still needs, for a consumer that may
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/engine/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/engine/events.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,WAAW,EAEZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAqwBtB"}
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,WAAW,EAEZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAy/BtB"}