zidane 5.14.4 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/{acp-24uU2WDs.js → acp-Irby04Us.js} +7 -8
  2. package/dist/{acp-24uU2WDs.js.map → acp-Irby04Us.js.map} +1 -1
  3. package/dist/acp-cli.js +7 -7
  4. package/dist/acp.d.ts +2 -3
  5. package/dist/acp.d.ts.map +1 -1
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-Cch2ayTt.js → agent-DkSmGkDM.js} +10871 -5411
  8. package/dist/agent-DkSmGkDM.js.map +1 -0
  9. package/dist/agent.d.ts +1 -2
  10. package/dist/agent.js +2 -2
  11. package/dist/{anthropic-RGqsJlC8.js → anthropic-CTHsdFG9.js} +46 -6
  12. package/dist/anthropic-CTHsdFG9.js.map +1 -0
  13. package/dist/{auth-C-ms5N2x.js → auth-BDSu_0t3.js} +13 -86
  14. package/dist/auth-BDSu_0t3.js.map +1 -0
  15. package/dist/chat/pure.d.ts +4 -4
  16. package/dist/chat/pure.js +4 -3
  17. package/dist/chat.d.ts +45 -8
  18. package/dist/chat.d.ts.map +1 -1
  19. package/dist/chat.js +9 -6
  20. package/dist/chat.js.map +1 -1
  21. package/dist/completion-core-CXYSVhZo.js +147 -0
  22. package/dist/completion-core-CXYSVhZo.js.map +1 -0
  23. package/dist/{context-breakdown-kO-pDsay.js → context-breakdown-Dzo25N45.js} +2 -23
  24. package/dist/context-breakdown-Dzo25N45.js.map +1 -0
  25. package/dist/contexts/daytona.d.ts +3 -3
  26. package/dist/contexts/daytona.js +1 -1
  27. package/dist/contexts/docker.d.ts +10 -2
  28. package/dist/contexts/docker.d.ts.map +1 -1
  29. package/dist/contexts/docker.js +142 -103
  30. package/dist/contexts/docker.js.map +1 -1
  31. package/dist/contexts/e2b.d.ts +2 -2
  32. package/dist/contexts/e2b.js +1 -1
  33. package/dist/contexts/sandbox.d.ts +1 -1
  34. package/dist/contexts/sandbox.js +4 -1
  35. package/dist/contexts/sandbox.js.map +1 -1
  36. package/dist/{contexts-Lzf5huID.js → contexts-Vone3qQQ.js} +26 -37
  37. package/dist/contexts-Vone3qQQ.js.map +1 -0
  38. package/dist/contexts.d.ts +3 -3
  39. package/dist/contexts.js +1 -1
  40. package/dist/errors.d.ts +1 -2
  41. package/dist/errors.js +1 -1
  42. package/dist/eval.d.ts +1 -1
  43. package/dist/eval.js +3 -3
  44. package/dist/exec-file-size-PXkr-MGA.js +63 -0
  45. package/dist/exec-file-size-PXkr-MGA.js.map +1 -0
  46. package/dist/extensions.d.ts +2 -0
  47. package/dist/extensions.js +2 -0
  48. package/dist/generate-data-WL_yGVL6.js +324 -0
  49. package/dist/generate-data-WL_yGVL6.js.map +1 -0
  50. package/dist/headless.d.ts +1 -1
  51. package/dist/headless.js +15 -10
  52. package/dist/headless.js.map +1 -1
  53. package/dist/index-B8UtiZy7.d.ts +14967 -0
  54. package/dist/index-B8UtiZy7.d.ts.map +1 -0
  55. package/dist/{index-B3ciFUZx.d.ts → index-DsPQbyUn.d.ts} +2 -2
  56. package/dist/index-DsPQbyUn.d.ts.map +1 -0
  57. package/dist/index.d.ts +6 -12
  58. package/dist/index.js +20 -43
  59. package/dist/index.js.map +1 -1
  60. package/dist/{logger-Ktm-lj1s.js → logger-DBX9uYOw.js} +108 -5
  61. package/dist/logger-DBX9uYOw.js.map +1 -0
  62. package/dist/login-DOF8pMVM.js +539 -0
  63. package/dist/login-DOF8pMVM.js.map +1 -0
  64. package/dist/{mcp-Dn5W65Lv.js → mcp-CcvuVXB9.js} +2 -2
  65. package/dist/{mcp-Dn5W65Lv.js.map → mcp-CcvuVXB9.js.map} +1 -1
  66. package/dist/mcp.d.ts +1 -1
  67. package/dist/mcp.js +1 -1
  68. package/dist/{messages-YZQLKaz2.js → messages-CwujiS74.js} +4 -4
  69. package/dist/messages-CwujiS74.js.map +1 -0
  70. package/dist/{openai-compat-0Y7jcncn.js → openai-compat-BvgYGSR1.js} +7 -6
  71. package/dist/{openai-compat-0Y7jcncn.js.map → openai-compat-BvgYGSR1.js.map} +1 -1
  72. package/dist/output/stream-json.d.ts +1 -2
  73. package/dist/output/stream-json.d.ts.map +1 -1
  74. package/dist/output/terminal.d.ts +1 -2
  75. package/dist/output/terminal.d.ts.map +1 -1
  76. package/dist/{glob-DluQFSw1.js → output-cap-kBUHBlnq.js} +50 -2
  77. package/dist/output-cap-kBUHBlnq.js.map +1 -0
  78. package/dist/presets.d.ts +1 -2
  79. package/dist/presets.js +1 -1
  80. package/dist/providers/anthropic.d.ts +2 -2
  81. package/dist/providers/anthropic.js +2 -2
  82. package/dist/providers/arcee.d.ts +1 -1
  83. package/dist/providers/arcee.js +1 -1
  84. package/dist/providers/baseten.d.ts +1 -1
  85. package/dist/providers/baseten.js +1 -1
  86. package/dist/providers/cerebras.d.ts +1 -1
  87. package/dist/providers/cerebras.js +1 -1
  88. package/dist/providers/local.d.ts +1 -1
  89. package/dist/providers/local.js +1 -1
  90. package/dist/providers/openai-compat.d.ts +1 -1
  91. package/dist/providers/openai-compat.js +1 -1
  92. package/dist/providers/openai.d.ts +1 -1
  93. package/dist/providers/openai.js +4 -4
  94. package/dist/providers/openai.js.map +1 -1
  95. package/dist/providers/openrouter.d.ts +1 -1
  96. package/dist/providers/openrouter.js +1 -1
  97. package/dist/providers/xai.d.ts +1 -1
  98. package/dist/providers/xai.js +1 -1
  99. package/dist/{providers-DgmdYGKm.js → providers-z6LDMAr3.js} +3 -3
  100. package/dist/{providers-DgmdYGKm.js.map → providers-z6LDMAr3.js.map} +1 -1
  101. package/dist/providers.d.ts +1 -1
  102. package/dist/providers.js +4 -4
  103. package/dist/{read-state-BymF41Jb.js → read-state-Dq_TXUX1.js} +2 -2
  104. package/dist/{read-state-BymF41Jb.js.map → read-state-Dq_TXUX1.js.map} +1 -1
  105. package/dist/{interpolate-BtIgcCuz.js → resolve-Cr8JSL_O.js} +562 -136
  106. package/dist/resolve-Cr8JSL_O.js.map +1 -0
  107. package/dist/restate.d.ts +2 -2
  108. package/dist/restate.js +2 -2
  109. package/dist/{sandbox-Dgy-m6UF.d.ts → sandbox-CgjG2VvQ.d.ts} +2 -2
  110. package/dist/{sandbox-Dgy-m6UF.d.ts.map → sandbox-CgjG2VvQ.d.ts.map} +1 -1
  111. package/dist/session/sqlite.d.ts +1 -1
  112. package/dist/{session-CqrAFAKJ.js → session-CsdDIPY8.js} +108 -3
  113. package/dist/session-CsdDIPY8.js.map +1 -0
  114. package/dist/session.d.ts +2 -2
  115. package/dist/session.js +3 -3
  116. package/dist/skills-Bsb0rvWI.js +295 -0
  117. package/dist/skills-Bsb0rvWI.js.map +1 -0
  118. package/dist/skills.d.ts +2 -3
  119. package/dist/skills.js +3 -24
  120. package/dist/{errors-CkTvg97v.d.ts → timeout-8vSIRjzl.d.ts} +10 -2
  121. package/dist/timeout-8vSIRjzl.d.ts.map +1 -0
  122. package/dist/{timeout-kGGSXagK.js → timeout-BDetbuN6.js} +59 -2
  123. package/dist/timeout-BDetbuN6.js.map +1 -0
  124. package/dist/tool-formatters-DY0TDb1r.d.ts +378 -0
  125. package/dist/tool-formatters-DY0TDb1r.d.ts.map +1 -0
  126. package/dist/tools/fetch-url.d.ts +1 -1
  127. package/dist/tools/web-search.d.ts +1 -1
  128. package/dist/tools.d.ts +2 -3
  129. package/dist/tools.js +3 -4
  130. package/dist/{transcript-anchors-BHIgMlPq.d.ts → transcript-anchors-Cb-bDbNH.d.ts} +233 -640
  131. package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +1 -0
  132. package/dist/{transcript-anchors-DsoBHg43.js → transcript-anchors-DSRPWjiH.js} +391 -961
  133. package/dist/transcript-anchors-DSRPWjiH.js.map +1 -0
  134. package/dist/tui.d.ts +335 -11
  135. package/dist/tui.d.ts.map +1 -1
  136. package/dist/tui.js +6375 -1892
  137. package/dist/tui.js.map +1 -1
  138. package/dist/{turn-operations-Dw02ZoSQ.d.ts → turn-operations-CgMROLsr.d.ts} +29 -4
  139. package/dist/turn-operations-CgMROLsr.d.ts.map +1 -0
  140. package/dist/{turn-operations-tG0vuBNc.js → turn-operations-Dq9Kx7m2.js} +321 -81
  141. package/dist/turn-operations-Dq9Kx7m2.js.map +1 -0
  142. package/dist/{types-BqdTeBaC.d.ts → types-BDccavwj.d.ts} +42 -1
  143. package/dist/types-BDccavwj.d.ts.map +1 -0
  144. package/dist/{types-CyVGdbia.js → types-BIarq1qE.js} +90 -2
  145. package/dist/types-BIarq1qE.js.map +1 -0
  146. package/dist/types.d.ts +5 -6
  147. package/dist/types.js +1 -1
  148. package/dist/{xai-tPdbAGkq.js → xai-B_e6TOA8.js} +2 -2
  149. package/dist/{xai-tPdbAGkq.js.map → xai-B_e6TOA8.js.map} +1 -1
  150. package/docs/ARCHITECTURE.md +1 -1
  151. package/docs/CHAT.md +7 -6
  152. package/docs/EXECUTION_CONTEXT.md +16 -0
  153. package/docs/EXTENSIONS.md +1063 -0
  154. package/docs/SKILL.md +16 -0
  155. package/docs/TUI.md +10 -3
  156. package/package.json +12 -3
  157. package/dist/agent-Cch2ayTt.js.map +0 -1
  158. package/dist/agent-EFWt6uQ_.d.ts +0 -6914
  159. package/dist/agent-EFWt6uQ_.d.ts.map +0 -1
  160. package/dist/anthropic-RGqsJlC8.js.map +0 -1
  161. package/dist/auth-C-ms5N2x.js.map +0 -1
  162. package/dist/context-breakdown-kO-pDsay.js.map +0 -1
  163. package/dist/contexts-Lzf5huID.js.map +0 -1
  164. package/dist/errors-CkTvg97v.d.ts.map +0 -1
  165. package/dist/glob-DluQFSw1.js.map +0 -1
  166. package/dist/glob-shell-rJMoCIGb.js +0 -21
  167. package/dist/glob-shell-rJMoCIGb.js.map +0 -1
  168. package/dist/index-B3ciFUZx.d.ts.map +0 -1
  169. package/dist/index-BtzE3Uaq.d.ts +0 -2738
  170. package/dist/index-BtzE3Uaq.d.ts.map +0 -1
  171. package/dist/index-tSzOaWNt.d.ts +0 -316
  172. package/dist/index-tSzOaWNt.d.ts.map +0 -1
  173. package/dist/interpolate-BtIgcCuz.js.map +0 -1
  174. package/dist/logger-DGiGf7DW.d.ts +0 -102
  175. package/dist/logger-DGiGf7DW.d.ts.map +0 -1
  176. package/dist/logger-Ktm-lj1s.js.map +0 -1
  177. package/dist/login-CCA-1lgK.js +0 -267
  178. package/dist/login-CCA-1lgK.js.map +0 -1
  179. package/dist/messages-YZQLKaz2.js.map +0 -1
  180. package/dist/policy-DcGlpaNs.d.ts +0 -129
  181. package/dist/policy-DcGlpaNs.d.ts.map +0 -1
  182. package/dist/presets-BQWYMHdd.js +0 -114
  183. package/dist/presets-BQWYMHdd.js.map +0 -1
  184. package/dist/run-summary-DkN8KsHM.d.ts +0 -249
  185. package/dist/run-summary-DkN8KsHM.d.ts.map +0 -1
  186. package/dist/session-CqrAFAKJ.js.map +0 -1
  187. package/dist/shell-quote-BmnhZmdM.js +0 -33
  188. package/dist/shell-quote-BmnhZmdM.js.map +0 -1
  189. package/dist/skills.js.map +0 -1
  190. package/dist/timeout-CpFm0jJ6.d.ts +0 -10
  191. package/dist/timeout-CpFm0jJ6.d.ts.map +0 -1
  192. package/dist/timeout-kGGSXagK.js.map +0 -1
  193. package/dist/tool-formatters-C6iLgc9f.d.ts +0 -1454
  194. package/dist/tool-formatters-C6iLgc9f.d.ts.map +0 -1
  195. package/dist/tools-CCd8e-HT.js +0 -1739
  196. package/dist/tools-CCd8e-HT.js.map +0 -1
  197. package/dist/transcript-anchors-BHIgMlPq.d.ts.map +0 -1
  198. package/dist/transcript-anchors-DsoBHg43.js.map +0 -1
  199. package/dist/turn-operations-Dw02ZoSQ.d.ts.map +0 -1
  200. package/dist/turn-operations-tG0vuBNc.js.map +0 -1
  201. package/dist/types-BqdTeBaC.d.ts.map +0 -1
  202. package/dist/types-CyVGdbia.js.map +0 -1
@@ -1,2738 +0,0 @@
1
- import { Ar as TurnUsage, Fn as AgentStats, I as ShellInterpolationApproval, K as SessionStore, Kn as McpServerConfig, L as SkillConfig, Mn as AgentBehavior, Nn as AgentClock, Rn as ChildRunStats, Sr as ToolResultContent, St as Provider, T as ToolDef, U as Session, _r as ThinkingLevel, br as ToolOutcome, f as SkillActivationState, i as AgentOptions, kr as TurnFinishReason, mr as SessionTurn, n as AgentHookMap, r as AgentHooks, tr as PromptPart, u as ActiveSkill, w as ToolContext } from "./agent-EFWt6uQ_.js";
2
- import { c as ExecutionContext, l as ExecutionHandle } from "./types-BqdTeBaC.js";
3
- import { t as RunSummary } from "./run-summary-DkN8KsHM.js";
4
- import { Hookable } from "hookable";
5
- import { OAuthClientProvider, OAuthDiscoveryState } from "@modelcontextprotocol/sdk/client/auth.js";
6
- import { OAuthClientInformationMixed, OAuthClientMetadata, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
7
-
8
- //#region src/behaviors/local-reliability.d.ts
9
- /**
10
- * Opt-in behavior overlay for brittle/local OpenAI-compatible endpoints.
11
- * Returns plain `AgentBehavior` so hosts can spread it before or after their
12
- * own overrides; no built-in profile uses this helper by default.
13
- */
14
- declare function localReliabilityBehavior(overrides?: AgentBehavior): AgentBehavior;
15
- //#endregion
16
- //#region src/behaviors/repeat-guard.d.ts
17
- /**
18
- * Default tracked-tool predicate: the built-in `shell` and `read_file` tools.
19
- * `shell` is an auto-approved, side-effect-light retry magnet; `read_file` is
20
- * the re-read loop magnet. Both are the loop shapes the abort escalation exists
21
- * for. Consumers that want to track additional tools (e.g. an MCP query runner)
22
- * pass them via
23
- * {@link RepeatGuardConfig.tools}.
24
- */
25
- declare function defaultRepeatGuardTracked(name: string): boolean;
26
- /**
27
- * Canonicalize a shell command so semantically-identical invocations collapse
28
- * to one streak key:
29
- *
30
- * - strip a leading `cd <path> &&` (or `cd <path>;`) prefix — the model often
31
- * re-prefixes the same command with a `cd` into the project root.
32
- * - strip a trailing verify-tail of the shape `& sleep N ; <anything>` or
33
- * `; sleep N && <anything>` that the model appends to poll a just-started
34
- * process (`… & sleep 2 ; curl localhost`).
35
- * - collapse runs of whitespace to single spaces and trim.
36
- *
37
- * Conservative on purpose: it does NOT reorder flags or parse the command —
38
- * it only removes the two wrappers we actually saw inflate distinct-looking
39
- * retries of the same core command, plus whitespace noise.
40
- */
41
- declare function normalizeShellCommand(command: string): string;
42
- /**
43
- * Built-in normalizer used when the consumer doesn't supply one. Shell-shaped
44
- * tools get {@link normalizeShellCommand}; everything else falls back to a
45
- * stable JSON encoding. Returns `undefined` when there's no meaningful payload
46
- * to key on (so the call is excluded from streak tracking rather than keyed on
47
- * `'{}'`). Consumers needing semantic keying for their own tools (e.g.
48
- * collapsing a query's whitespace) supply a normalizer via
49
- * {@link RepeatGuardConfig.normalize}.
50
- */
51
- declare function defaultRepeatGuardNormalize(name: string, input: Record<string, unknown>): string | undefined;
52
- /** Deterministic JSON with sorted keys so key order doesn't split a streak. */
53
- declare function stableStringify(value: unknown): string;
54
- //#endregion
55
- //#region src/compact/messages.d.ts
56
- /**
57
- * What to summarize and what to preserve verbatim.
58
- *
59
- * - `'full'` — summarize everything, no preserved tail.
60
- * - `'tail'` — summarize everything before the last `keepTurns` turns.
61
- * - `{ kind: 'from', turnId }` — summarize from the anchor turn onward.
62
- * - `{ kind: 'up_to', turnId }` — summarize up to (and including) the anchor.
63
- */
64
- type CompactScope = 'full' | 'tail' | {
65
- kind: 'from';
66
- turnId: string;
67
- } | {
68
- kind: 'up_to';
69
- turnId: string;
70
- };
71
- interface CompactionSlice {
72
- /** The portion of the conversation that will be summarized. */
73
- toSummarize: readonly SessionTurn[];
74
- /** The portion that stays verbatim in the post-compact history. */
75
- preserved: readonly SessionTurn[];
76
- }
77
- /**
78
- * Partition `turns` into `(toSummarize, preserved)` according to `scope`.
79
- *
80
- * Throws {@link CompactInvalidInputError} on degenerate inputs so the
81
- * caller doesn't pay for a doomed provider call:
82
- * - empty `turns`
83
- * - `scope: 'tail'` with `keepTurns >= turns.length` (nothing to summarize)
84
- * - `scope: { from | up_to }` with an anchor id that isn't in `turns`
85
- * - the resulting `toSummarize` slice contains no text-bearing content
86
- * (only system turns or empty content)
87
- *
88
- * Pure. Returns references to the original `SessionTurn` objects — the
89
- * caller can compare by identity (=== Object.is) to confirm.
90
- */
91
- declare function sliceForCompaction(turns: readonly SessionTurn[], scope: CompactScope, keepTurns: number): CompactionSlice;
92
- /**
93
- * Replace every attachment block in `turns` with a short text marker.
94
- *
95
- * Covers two shapes:
96
- * - Top-level `{ type: 'image', ... }` content blocks on user turns.
97
- * - Image entries inside `tool_result.output` array form (multimodal
98
- * tool results — e.g. an MCP browser screenshot).
99
- *
100
- * Unconditional by design: even on vision-capable models, the summary
101
- * call doesn't benefit from raw image bytes (the model can't refer to
102
- * them after the summary lands), and stripping uniformly avoids
103
- * `prompt_too_long` on image-heavy sessions.
104
- *
105
- * Returns a fresh array; input turns / blocks are never mutated.
106
- */
107
- declare function stripImagesFromTurns(turns: readonly SessionTurn[]): SessionTurn[];
108
- /**
109
- * Drop the oldest "round" from `turns` and return a fresh array. Used by
110
- * the PTL retry path to shrink the prompt one round at a time.
111
- *
112
- * A round is a contiguous `[user, assistant?, tool_results?]` group. The
113
- * function walks forward from index 0, advances through the user turn
114
- * and any trailing assistant + tool-result turns belonging to the same
115
- * exchange, and returns the remainder.
116
- *
117
- * Adjacency-safe: when the oldest user turn carries `tool_result` blocks
118
- * answering an assistant turn ahead of it (rare — happens during
119
- * resume), the function keeps walking until the next clean boundary so
120
- * the resulting array still respects every provider's `tool_use ↔
121
- * tool_result` adjacency rule.
122
- *
123
- * Returns `turns` unchanged when only one round (or less) remains — the
124
- * caller is expected to interpret that as "cannot shrink further" and
125
- * give up the retry loop.
126
- */
127
- declare function truncateHeadForPtlRetry(turns: readonly SessionTurn[]): SessionTurn[];
128
- /**
129
- * Maximum length of an anchor turn's textual preview, in characters. Long
130
- * enough to give the model recognizable context (the first paragraph of
131
- * a typical user message), short enough that it doesn't blow the
132
- * cache-stability invariant for the prompt prefix.
133
- */
134
- declare const ANCHOR_PREVIEW_MAX_CHARS = 200;
135
- /**
136
- * Extract the first ~200 chars of text-bearing content from a turn — the
137
- * preview surfaced in `from` / `up_to` direction prompts so the model
138
- * knows where the slice begins.
139
- */
140
- declare function anchorPreviewFor(turn: SessionTurn): string;
141
- /**
142
- * Input shape for {@link summaryToTurn}. Designed to align with the
143
- * fields of `CompactResult` so a caller can spread the runner's output
144
- * with a single `replacesTurnIds` rename — no field-by-field unpacking
145
- * required.
146
- *
147
- * Primitive shape (no `CompactResult` import) keeps this module free of
148
- * dependencies on the runner — `compact.ts` imports from here, not the
149
- * other way around.
150
- */
151
- interface SummaryToTurnInput {
152
- /** Summary text — typically `CompactResult.summary`. */
153
- summary: string;
154
- /** Turn ids being replaced — typically `CompactResult.summarizedTurnIds`. */
155
- replacesTurnIds: readonly string[];
156
- /** Model id that produced the summary. */
157
- model: string;
158
- /** Token usage from the summary call. */
159
- usage: TurnUsage;
160
- /** Defaults to `Date.now()` when omitted. */
161
- compactedAt?: number;
162
- /**
163
- * Turn id. Defaults to `crypto.randomUUID()`. Durable-execution callers
164
- * (Restate) pass a journaled id (`clock.randomUUID()`) so the marker turn
165
- * is byte-identical on replay; pair it with a journaled {@link compactedAt}.
166
- */
167
- id?: string;
168
- }
169
- /**
170
- * Build a synthetic `SessionTurn` carrying a single `compact-summary`
171
- * block, ready to append to a session.
172
- *
173
- * The turn's role is `'user'` so it sits at a conversational boundary
174
- * the way the model expects. The caller is responsible for
175
- * `session.appendTurns([turn])`. The id defaults to `crypto.randomUUID()`
176
- * (override via `input.id` for durable-execution replay stability).
177
- *
178
- * Typical use after running `compactConversation`:
179
- *
180
- * ```ts
181
- * const result = await compactConversation({ provider, turns })
182
- * const turn = summaryToTurn({
183
- * summary: result.summary,
184
- * replacesTurnIds: result.summarizedTurnIds,
185
- * model: result.model,
186
- * usage: result.usage,
187
- * })
188
- * await session.appendTurns([turn])
189
- * ```
190
- */
191
- declare function summaryToTurn(input: SummaryToTurnInput): SessionTurn;
192
- //#endregion
193
- //#region src/compact/prompt.d.ts
194
- /**
195
- * Pure prompt builders for conversation compaction.
196
- *
197
- * The builders produce the **system prompt** for a no-tools summary call.
198
- * They are total functions of `(direction, anchorPreview?)` and produce
199
- * byte-stable output for the same inputs — that's load-bearing for the
200
- * provider's prompt cache: repeated compactions in the same host process
201
- * share the same prefix and read cache instead of writing it.
202
- *
203
- * Inspired by Claude Code's `services/compact/prompt.ts` — same 9-section
204
- * scaffold, same `<analysis> + <summary>` envelope, same no-tools
205
- * preamble. Adapted to zidane-specific wording (no "Claude" references)
206
- * and trimmed of the bits that don't apply (no `marble_origami`-style
207
- * query sources, no compaction-fingerprint header).
208
- */
209
- /** Identifier for the section of the conversation being summarized. */
210
- type CompactDirection = 'full' | 'tail' | 'from' | 'up_to';
211
- interface CompactPromptOptions {
212
- direction: CompactDirection;
213
- /**
214
- * Short preview of the anchor turn's text — only used by `'from'` and
215
- * `'up_to'`. Pass the last ~200 chars of the anchor turn so the model
216
- * has a recognizable handle on where the slice begins / ends. Empty /
217
- * undefined for `'full'` and `'tail'`.
218
- */
219
- anchorPreview?: string;
220
- }
221
- /**
222
- * Function shape for callers that want to swap in a domain-specific
223
- * summary prompt (security review handoff, support-ticket continuation,
224
- * etc.) without touching the runner. Default: {@link buildCompactPrompt}.
225
- */
226
- type CompactPromptBuilder = (opts: CompactPromptOptions) => string;
227
- /**
228
- * No-tools guard. The runner sends `tools: []` to the provider already,
229
- * but some models still hallucinate tool-call intent on a long
230
- * conversation. The prose guard is cheap insurance.
231
- */
232
- declare const NO_TOOLS_PREAMBLE = "CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.\n\n- Do NOT use Read, Bash, Grep, Glob, Edit, Write, or ANY other tool.\n- You already have all the context you need in the conversation above.\n- Tool calls will be REJECTED and will waste your only turn \u2014 you will fail the task.\n- Your entire response must be plain text: an <analysis> block followed by a <summary> block.";
233
- /**
234
- * Body shared by every direction. Lays out the 9-section scaffold,
235
- * mirrors Claude Code's `BASE_COMPACT_PROMPT` so a model already trained
236
- * on the layout produces the same shape.
237
- */
238
- declare const BASE_INSTRUCTIONS = "Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.\n\nThis summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing development work without losing context.\n\nBefore providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points. In your analysis process:\n\n1. Chronologically analyze each message and section of the conversation. For each section thoroughly identify:\n - The user's explicit requests and intents\n - Your approach to addressing the user's requests\n - Key decisions, technical concepts and code patterns\n - Specific details like file names, full code snippets, function signatures, file edits\n - Errors that you ran into and how you fixed them\n - Pay special attention to specific user feedback that you received, especially if the user told you to do something differently.\n2. Double-check for technical accuracy and completeness.\n\nYour summary, wrapped in <summary> tags, must include the following sections:\n\n1. Primary Request and Intent\n2. Key Technical Concepts\n3. Files and Code Sections (with paths; include code snippets only when load-bearing)\n4. Errors and fixes\n5. Problem Solving\n6. All user messages (list ALL non-tool user messages, verbatim)\n7. Pending Tasks\n8. Current Work\n9. Optional Next Step (include direct quotes from the most recent conversation when relevant)";
239
- /** Trailer prompting the model to begin. Same on every direction. */
240
- declare const TRAILER = "Provide your <analysis> and <summary> now.";
241
- declare function buildFullCompactPrompt(): string;
242
- declare function buildTailCompactPrompt(): string;
243
- declare function buildFromCompactPrompt(anchorPreview: string): string;
244
- declare function buildUpToCompactPrompt(anchorPreview: string): string;
245
- /**
246
- * Default public builder. Dispatches by direction to the four named
247
- * builders. Throws when `from` / `up_to` are passed without an
248
- * `anchorPreview` — those scopes only make sense with an anchor and a
249
- * silent fallback would produce a prompt that doesn't tell the model
250
- * where the slice begins.
251
- */
252
- declare const buildCompactPrompt: CompactPromptBuilder;
253
- //#endregion
254
- //#region src/compact/errors.d.ts
255
- /**
256
- * Typed errors thrown by the compaction helper.
257
- *
258
- * Lives in its own file so both the runner and the pure messages module
259
- * can import without circular dependencies.
260
- */
261
- /**
262
- * Raised when the caller's inputs make compaction meaningless before any
263
- * API call is attempted. Common cases:
264
- * - empty `turns`
265
- * - `keepTurns >= turns.length` (no older content to summarize)
266
- * - `'from'` / `'up_to'` anchor id not found in `turns`
267
- * - the resolved `toSummarize` slice has no text-bearing content
268
- *
269
- * Synchronous — thrown from `compactConversation()` before the provider
270
- * call so the caller can recover without a network round-trip.
271
- */
272
- declare class CompactInvalidInputError extends Error {
273
- constructor(message: string);
274
- }
275
- /**
276
- * Raised when the provider rejects the compaction request with
277
- * `prompt_too_long` (or an equivalent) and the head-truncation retry
278
- * budget has been exhausted. Callers can inspect `ptlRetries` to log
279
- * how far the retry loop got before giving up.
280
- */
281
- declare class CompactPromptTooLongError extends Error {
282
- readonly ptlRetries: number;
283
- constructor(message: string, ptlRetries: number);
284
- }
285
- //#endregion
286
- //#region src/compact/compact.d.ts
287
- interface CompactOptions {
288
- /** Provider used for the summary call. Called with empty tools list. */
289
- provider: Provider;
290
- /** Conversation to compact, in chronological order. */
291
- turns: readonly SessionTurn[];
292
- /**
293
- * What to summarize. Default: `'tail'` — summarize everything before
294
- * the last `keepTurns` turns. See {@link CompactScope}.
295
- */
296
- scope?: CompactScope;
297
- /**
298
- * Trailing turns left untouched when `scope: 'tail'`. Default: 4.
299
- * Matches `AgentBehavior.compactKeepTurns` so a host that uses both
300
- * mechanisms shares one knob.
301
- */
302
- keepTurns?: number;
303
- /** Model id used for the summary call. Default: `provider.meta.defaultModel`. */
304
- model?: string;
305
- /**
306
- * Maximum tokens the summary itself can occupy. Default: 20_000 — the
307
- * p99.99 of summary output size in Claude Code's `COMPACT_MAX_OUTPUT`.
308
- * Reasonable for any model with a 200k+ window.
309
- */
310
- maxOutputTokens?: number;
311
- /** Optional reasoning level. Default: `'off'` — summarization rarely benefits from thinking. */
312
- thinking?: ThinkingLevel;
313
- /** Optional cancellation signal forwarded to `provider.stream()`. */
314
- signal?: AbortSignal;
315
- /**
316
- * Watchdog for the provider summary call in milliseconds. If the provider
317
- * stream never settles, compaction aborts its request signal and fails
318
- * instead of leaving callers queued forever. Set `0` to disable.
319
- * Default: 120000 (2 minutes).
320
- */
321
- providerStreamTimeoutMs?: number;
322
- /**
323
- * Retries with head-truncation when the provider reports
324
- * `prompt_too_long`. Each retry drops the oldest conversational round
325
- * before re-issuing the call. Default: 3. Set 0 to fail-fast.
326
- */
327
- maxPtlRetries?: number;
328
- /**
329
- * Optional builder override. The default builder dispatches by
330
- * direction to the named builders in `./prompt.ts`; pass a custom
331
- * function to swap in a domain-specific summary prompt.
332
- */
333
- prompt?: CompactPromptBuilder;
334
- /**
335
- * Lifecycle hook for observability. Fires once per provider call,
336
- * including retries. The `kind` field tells you whether the call is
337
- * the initial attempt, a head-truncated retry, or a transient-error
338
- * retry — useful for surfacing progress in a UI spinner.
339
- */
340
- onAttempt?: (event: {
341
- attempt: number;
342
- kind: 'initial' | 'ptl-retry' | 'transient-retry';
343
- }) => void;
344
- /**
345
- * Lifecycle hook fired after preflight succeeds and before the first
346
- * provider call starts. Useful for UI state ("Compacting...") and telemetry.
347
- * Synchronous by design so observability cannot hang compaction.
348
- */
349
- onStart?: (event: CompactStartEvent) => void;
350
- /**
351
- * Lifecycle hook fired exactly once after {@link onStart}, on both success
352
- * and failure. Synchronous by design so observability cannot hang compaction.
353
- */
354
- onEnd?: (event: CompactEndEvent) => void;
355
- }
356
- interface CompactStartEvent {
357
- model: string;
358
- scope: CompactScope;
359
- summarizedTurnIds: readonly string[];
360
- preservedTurnIds: readonly string[];
361
- }
362
- type CompactEndEvent = {
363
- status: 'success';
364
- durationMs: number;
365
- result: CompactResult;
366
- } | {
367
- status: 'error';
368
- durationMs: number;
369
- error: unknown;
370
- };
371
- interface CompactResult {
372
- /** The summary text, with any `<analysis>` block stripped. */
373
- summary: string;
374
- /** Token usage from the (last successful) summary call. */
375
- usage: TurnUsage;
376
- /** Model id used to produce the summary. */
377
- model: string;
378
- /** Number of `prompt_too_long` retries that fired before success. 0 on first-try success. */
379
- ptlRetries: number;
380
- /**
381
- * Turn ids actually covered by the summary — i.e., the ids of turns
382
- * that made it to the provider. **PTL-retry safe**: when head-truncation
383
- * shrank the scope, only the surviving (post-truncation) turn ids
384
- * appear here. Drives `summaryToTurn`'s `replacesTurnIds`; the wire-
385
- * level cutoff in `applyCompactSummaryCutoff` reads the same field
386
- * from the persisted marker.
387
- */
388
- summarizedTurnIds: readonly string[];
389
- /**
390
- * Turn ids dropped by PTL head-truncation before reaching the
391
- * provider. **Empty on first-try success.** These turns are NOT
392
- * covered by the summary — callers should either leave them in the
393
- * conversation history (they stay visible to the model verbatim,
394
- * since the id-based cutoff only elides ids the marker explicitly
395
- * claims) or surface a "compaction lost N turns of context" warning.
396
- *
397
- * The harness keeps these in the wire-level conversation by default;
398
- * the safety contract is "the summary describes exactly what's in
399
- * `summarizedTurnIds` — nothing more, nothing less".
400
- */
401
- droppedDueToPtl: readonly string[];
402
- /** Turns left untouched (the preserved tail / verbatim slice). */
403
- preservedTurns: readonly SessionTurn[];
404
- /** Byte length of turns actually summarized (post-PTL-truncation). */
405
- beforeBytes: number;
406
- /** UTF-8 byte length of the summary text (rough "after" measure). */
407
- afterBytes: number;
408
- }
409
- declare function compactConversation(opts: CompactOptions): Promise<CompactResult>;
410
- //#endregion
411
- //#region src/compact/restore.d.ts
412
- /** One file selected for restoration, with its last-read timestamp for ranking. */
413
- interface RecentFile {
414
- /** Path relative to the execution context's `handle.cwd`. */
415
- path: string;
416
- /** Wall-clock when the file was last read, in ms. Drives recency ranking. */
417
- mtimeMs: number;
418
- }
419
- interface PostCompactRestoreOptions {
420
- /**
421
- * Files to consider for restoration, ranked by recency. Typically derived
422
- * via {@link selectFilesFromReadState} from `getReadState(session)`.
423
- * The helper takes the top {@link PostCompactRestoreOptions.maxFilesToRestore}
424
- * by `mtimeMs` descending, fetches their current content, and synthesizes
425
- * `read_file` tool_call/tool_result pairs.
426
- */
427
- recentFiles?: readonly RecentFile[];
428
- /**
429
- * Active skills to re-inject. Typically `agent.activeSkills`. Each entry
430
- * yields a synthetic `skills_use` tool_call/tool_result pair carrying the
431
- * skill's instructions (possibly truncated to the per-skill budget).
432
- */
433
- activeSkills?: readonly ActiveSkill[];
434
- /**
435
- * Execution context used to fetch file content. **Required for file
436
- * restoration.** Skills come pre-loaded (instructions live on the
437
- * `SkillConfig`), so they don't need the context.
438
- */
439
- execution?: ExecutionContext;
440
- handle?: ExecutionHandle;
441
- /**
442
- * Optional abort signal. Checked before each file read so a caller that
443
- * bounds restoration (e.g. a host capping its compaction barrier) can stop
444
- * the FS round-trips promptly instead of reading every candidate. File
445
- * restoration already isolates per-file failures, so an abort mid-loop just
446
- * returns whatever was gathered so far.
447
- */
448
- signal?: AbortSignal;
449
- /**
450
- * Canonical name of the file-read tool. Defaults to `read_file`. Aliases
451
- * (e.g. `Read`) are NOT specified here — the agent loop's
452
- * `rewriteMessagesToWire` handles wire conversion automatically.
453
- *
454
- * Override only when a host registered file-read under a different
455
- * canonical name (not just an alias).
456
- */
457
- readFileToolName?: string;
458
- /**
459
- * Canonical name of the skill-activation tool. Defaults to `skills_use`.
460
- * Same aliasing semantics as `readFileToolName`.
461
- */
462
- skillsUseToolName?: string;
463
- /** Total token budget for file restoration. Default: 50_000. */
464
- fileTokenBudget?: number;
465
- /** Per-file token cap. Default: 5_000. */
466
- fileTokenPerFileCap?: number;
467
- /** Maximum file count. Default: 5. */
468
- maxFilesToRestore?: number;
469
- /** Total token budget for skill restoration. Default: 25_000. */
470
- skillTokenBudget?: number;
471
- /** Per-skill token cap. Default: 5_000. */
472
- skillTokenPerSkillCap?: number;
473
- /**
474
- * Paths to skip — typically the file paths already covered by the
475
- * compaction result's `preservedTurns`. Avoids double-injection when the
476
- * recent reads sit in the preserved tail.
477
- */
478
- excludePaths?: readonly string[];
479
- /**
480
- * Optional `runId` to tag the synthetic turns with — useful for hosts
481
- * that want the restoration turns to roll up under the same run as the
482
- * compaction marker. Defaults to undefined (orphan turns).
483
- */
484
- runId?: string;
485
- /**
486
- * Time + UUID source for the synthesized turns' `id` / `createdAt`.
487
- * Defaults to {@link DEFAULT_AGENT_CLOCK} (`Date.now()` /
488
- * `crypto.randomUUID()`). Durable-execution callers (Restate) pass the
489
- * loop's journaled clock so the restoration turns are byte-identical on
490
- * replay. The synthetic `tool_call`/`tool_result` `callId`s are already
491
- * deterministic (`compact-restore-file-${i}`), so only the turn envelope
492
- * needs the clock.
493
- */
494
- clock?: AgentClock;
495
- }
496
- /**
497
- * Envelope returned by {@link buildPostCompactAttachments}. The caller
498
- * spreads `turns` into `session.appendTurns([summaryTurn, ...turns])`.
499
- * Count fields drive UI banners ("restored 5 files + 2 skills").
500
- */
501
- interface PostCompactAttachments {
502
- /**
503
- * Two synthetic turns when at least one item was restored, otherwise
504
- * an empty array. The pair is `[assistant_with_tool_calls,
505
- * user_with_tool_results]` — adjacent and well-formed for every
506
- * provider's `tool_use ↔ tool_result` invariant.
507
- */
508
- turns: readonly SessionTurn[];
509
- /** Count of files actually restored (post-budget). */
510
- restoredFiles: number;
511
- /** Count of skills actually restored (post-budget). */
512
- restoredSkills: number;
513
- /** Rough total token cost of the restoration payload (sum of all content). */
514
- estimatedTokens: number;
515
- }
516
- /**
517
- * Convert a raw read-state map into a deduped, path-ranked list ready for
518
- * restoration. Multiple entries for the same path (different
519
- * `(offset, limit, maxBytes)` slices) collapse to one — keeping the most
520
- * recent `mtimeMs`.
521
- *
522
- * Filters out entries whose key doesn't share the given `cwd` prefix:
523
- * those came from a different execution context and can't be read back
524
- * through this agent's handle.
525
- *
526
- * Pure. Most callers want {@link selectFilesFromSession}, which wraps
527
- * `getReadState(session)` + this function in one call so the host
528
- * doesn't have to reach into the tools layer.
529
- */
530
- declare function selectFilesFromReadState(readState: ReadonlyMap<string, {
531
- mtimeMs: number;
532
- }>, cwd: string): RecentFile[];
533
- /**
534
- * Session-aware convenience: extract recently-read files directly from
535
- * a {@link Session} via its per-session read-state map.
536
- *
537
- * Hosts (TUI / SDK consumers) typically have a `Session` and a `cwd`
538
- * (the active agent's `handle.cwd`) on hand — this wrapper saves them
539
- * from reaching into `src/tools/read-state.ts` directly. Returns an
540
- * empty list when no read state has been recorded yet (fresh session,
541
- * or `behavior.dedupReads === false`).
542
- *
543
- * Equivalent to:
544
- *
545
- * ```ts
546
- * const state = getReadState(session)
547
- * return state ? selectFilesFromReadState(state, cwd) : []
548
- * ```
549
- */
550
- declare function selectFilesFromSession(session: Session, cwd: string): RecentFile[];
551
- /**
552
- * Pick the top `maxFiles` from `files` (descending by `mtimeMs`),
553
- * dropping any whose path appears in `excludePaths`.
554
- *
555
- * Stable for equal mtimes — files with the same timestamp retain their
556
- * input order. Pure.
557
- */
558
- declare function selectRecentFiles(files: readonly RecentFile[], opts: {
559
- maxFiles: number;
560
- excludePaths?: readonly string[];
561
- }): RecentFile[];
562
- /**
563
- * Build the synthetic turns to append after a `compact-summary` marker.
564
- *
565
- * Returns a `PostCompactAttachments` envelope; the caller is responsible
566
- * for `session.appendTurns([summaryTurn, ...result.turns])`. The two
567
- * synthetic turns are always emitted together (or both omitted when
568
- * nothing was restored) so the `tool_use ↔ tool_result` adjacency
569
- * invariant holds regardless of caller code path.
570
- *
571
- * Failure isolation: a single file's read failure never blocks the rest
572
- * of restoration — that file is skipped silently and processing
573
- * continues. The returned `restoredFiles` count reflects what actually
574
- * landed in the synthesized turns.
575
- */
576
- declare function buildPostCompactAttachments(opts: PostCompactRestoreOptions): Promise<PostCompactAttachments>;
577
- //#endregion
578
- //#region src/compact/utils.d.ts
579
- /**
580
- * Shared utilities for the compact module — extracted so the runner
581
- * (`compact.ts`) and the restoration helper (`restore.ts`) don't carry
582
- * redundant copies of the same low-level math.
583
- *
584
- * Kept zero-dependency by design: no Node/Bun imports, no zidane types
585
- * either. Both `utf8ByteLength` and `estimateTokens` are total
586
- * functions of a single `string` argument, so they're trivially
587
- * portable to a worker/browser context if the compact module ever
588
- * needs to render outside Node.
589
- */
590
- /**
591
- * UTF-8 byte length, matching `Buffer.byteLength(text, 'utf-8')` but
592
- * without pulling `node:buffer` for a one-liner. Stable for surrogate
593
- * pairs — a high+low surrogate pair counts as a single 4-byte sequence
594
- * (not 2 × 3-byte). Cheap to call in hot loops.
595
- *
596
- * Pure. Identical bytes for identical input across every JS runtime.
597
- */
598
- declare function utf8ByteLength(text: string): number;
599
- /** Same constant Claude Code's `CONTEXT_MANAGEMENT.md` documents. */
600
- declare const BYTES_PER_TOKEN = 4;
601
- /**
602
- * Approximate token count for `text`. Mirrors Claude Code's
603
- * `BYTES_PER_TOKEN = 4` heuristic — acceptable for budget arithmetic
604
- * (sizing summarization scopes, enforcing per-file caps in restoration).
605
- *
606
- * Accurate to ~10% on English + code. Use a real tokenizer when exact
607
- * counts matter (cost reporting, hard caps); this is for budget gates
608
- * where being off by 10% is fine.
609
- *
610
- * Pure. Exported so callers (TUI, SDK consumers) can do their own
611
- * pre-budgeting against the same heuristic the harness uses internally.
612
- */
613
- declare function estimateTokens(text: string): number;
614
- //#endregion
615
- //#region src/tools/edit.d.ts
616
- /**
617
- * Surgical edit — replace `old_string` with `new_string` in a single file.
618
- *
619
- * Mirrors Claude Code's `Edit` semantics so models post-trained on Anthropic's
620
- * tool surface need no relearning. Fails clearly when `old_string` isn't unique
621
- * (unless `replace_all: true`) and when not found, with a nearest-match preview
622
- * so the model can recover without a separate `read_file` round-trip.
623
- */
624
- declare const edit: ToolDef;
625
- //#endregion
626
- //#region src/tools/glob.d.ts
627
- declare const glob: ToolDef;
628
- //#endregion
629
- //#region src/tools/grep.d.ts
630
- declare const grep: ToolDef;
631
- //#endregion
632
- //#region src/tools/interaction.d.ts
633
- interface InteractionToolOptions {
634
- /** JSON Schema for the request payload the model sends */
635
- schema: Record<string, unknown>;
636
- /** Tool name (default: 'interaction') */
637
- name?: string;
638
- /** Tool description shown to the model */
639
- description?: string;
640
- /** Called when the model invokes this tool. Receives the validated payload and tool context, returns data for the model. */
641
- onRequest: (payload: Record<string, unknown>, ctx: ToolContext) => Promise<Record<string, unknown> | string>;
642
- }
643
- /**
644
- * Create an interaction tool that lets the agent request structured input.
645
- *
646
- * The model calls this tool with a payload matching the schema.
647
- * `onRequest` is called with the payload and should return the response
648
- * (string or object) that gets sent back to the model as the tool result.
649
- */
650
- declare function createInteractionTool(options: InteractionToolOptions): ToolDef;
651
- //#endregion
652
- //#region src/tools/list-files.d.ts
653
- declare const listFiles: ToolDef;
654
- //#endregion
655
- //#region src/tools/multi-edit.d.ts
656
- declare const multiEdit: ToolDef;
657
- //#endregion
658
- //#region src/tools/read-file.d.ts
659
- declare const readFile: ToolDef;
660
- //#endregion
661
- //#region src/tools/shell.d.ts
662
- interface CreateShellToolOptions {
663
- /**
664
- * Whether to expose the `run_in_background` flag in the input schema +
665
- * the background-mode paragraphs in the description. When `false`, the
666
- * model never sees the flag and won't try to use it. The execute path
667
- * still has a defensive fallback: an explicit `run_in_background: true`
668
- * call (e.g. from a hand-crafted message) returns a clean error rather
669
- * than silently running foreground.
670
- *
671
- * Default: `true`.
672
- */
673
- allowBackground?: boolean;
674
- /**
675
- * Canonical names of tools registered alongside `shell` on the same
676
- * agent. When non-empty, the description gains a "prefer the dedicated
677
- * tool" block for each known sibling (`read_file`, `glob`, `grep`,
678
- * `list_files`, `edit`, `write_file`) — useful against the
679
- * `ls`/`cat`-to-re-verify loop some models fall into when both a
680
- * dedicated tool AND `shell` are visible. Unknown / unrecognized names
681
- * are ignored.
682
- *
683
- * Set by `createAgent` per-run from the tool registry; hosts that
684
- * construct a `shell` directly can pass it explicitly. Omit to suppress
685
- * the block entirely (no nudge for shell-only agents, no nudge for
686
- * hosts that prefer to author their own anti-loop prose).
687
- */
688
- registeredCanonicals?: ReadonlySet<string>;
689
- /**
690
- * The agent's `toolAliases` map, used to render the wire-level name of
691
- * each sibling in the swap block. Without this, the block always prints
692
- * canonical names — fine for the default preset, wrong for hosts that
693
- * alias-rename (the model would be told to call a name it doesn't see
694
- * in the tool spec).
695
- */
696
- toolAliases?: Record<string, string>;
697
- }
698
- /**
699
- * Factory for the `shell` tool. The default exported `shell` is
700
- * equivalent to `createShellTool({ allowBackground: true })`. The
701
- * factory is the entry point hosts use when they want to override the
702
- * default — e.g. to ship a preset that always disables background mode
703
- * regardless of `behavior.tasksDir`.
704
- *
705
- * Hosts that use the framework's `createAgent` typically don't need to
706
- * call this directly: when `behavior.tasksDir` is unset or
707
- * `behavior.disableBackgroundTasks: true` is set, the agent
708
- * automatically rewrites the registered `shell` (if it's the
709
- * framework's built-in) using this factory.
710
- */
711
- declare function createShellTool(opts?: CreateShellToolOptions): ToolDef;
712
- /**
713
- * Default `shell` tool with background mode enabled.
714
- *
715
- * Most hosts use this directly via `basicTools`. When the agent's
716
- * `behavior.tasksDir` is unset OR `behavior.disableBackgroundTasks:
717
- * true` is set, `createAgent` auto-rewrites this identity to a
718
- * `createShellTool({ allowBackground: false })` variant so the model
719
- * never sees a flag it can't use. Hosts who want to bypass that
720
- * auto-rewrite can register a `createShellTool({ allowBackground })`
721
- * directly — the rewrite only fires on identity-equal references to
722
- * this constant.
723
- */
724
- declare const shell: ToolDef;
725
- //#endregion
726
- //#region src/tools/shell-kill.d.ts
727
- declare const shellKill: ToolDef;
728
- //#endregion
729
- //#region src/tools/skills-read.d.ts
730
- interface SkillsReadToolOptions {
731
- catalog: readonly SkillConfig[];
732
- state: SkillActivationState;
733
- }
734
- declare function createSkillsReadTool(options: SkillsReadToolOptions): ToolDef;
735
- //#endregion
736
- //#region src/tools/skills-run-script.d.ts
737
- interface SkillsRunScriptToolOptions {
738
- catalog: readonly SkillConfig[];
739
- state: SkillActivationState;
740
- /** Script timeout in milliseconds. Default 60000. */
741
- scriptTimeoutMs?: number;
742
- }
743
- declare function createSkillsRunScriptTool(options: SkillsRunScriptToolOptions): ToolDef;
744
- //#endregion
745
- //#region src/tools/skills-use.d.ts
746
- interface SkillsUseToolOptions {
747
- /** Resolved skills catalog for this run. */
748
- catalog: readonly SkillConfig[];
749
- /** Per-agent activation state the tool mutates. */
750
- state: SkillActivationState;
751
- /** Agent hooks — used to fire `skills:activate` on first activation. */
752
- hooks: Hookable<AgentHooks>;
753
- /**
754
- * Execute `!\`cmd\`` shell interpolation on activation. Mirrors
755
- * `SkillsConfig.allowShellInterpolation`. Default `true`. Interpolation
756
- * runs arbitrary shell from (possibly third-party) skill content, outside
757
- * the allowed-tools gate — set `false` for locked-down hosts. When off,
758
- * patterns are replaced with a `[shell interpolation disabled]`
759
- * placeholder.
760
- */
761
- allowShellInterpolation?: boolean;
762
- /**
763
- * Optional approval gate for `!\`cmd\`` shell interpolation. Invoked once
764
- * per (skill, command) the first time a skill with embedded shell is
765
- * activated, BEFORE the command runs. Return `false` to skip that command
766
- * (it is replaced with a `[shell interpolation not approved]` placeholder).
767
- * When omitted, interpolation runs without prompting (back-compat). Hosts
768
- * (TUI/GUI) can wire this to an interactive confirmation.
769
- */
770
- approveShellInterpolation?: (request: ShellInterpolationApproval) => boolean | Promise<boolean>;
771
- }
772
- /**
773
- * Factory for `skills_use`. Auto-injected into the agent's tool set by the
774
- * agent runtime when a non-empty skills catalog is available (unless
775
- * `SkillsConfig.tool === false`).
776
- *
777
- * The tool schema's `name` property is `enum`-constrained to the resolved
778
- * catalog so the LLM cannot hallucinate a skill that doesn't exist.
779
- */
780
- declare function createSkillsUseTool(options: SkillsUseToolOptions): ToolDef;
781
- //#endregion
782
- //#region src/tools/spawn.d.ts
783
- interface ChildAgent {
784
- id: string;
785
- task: string;
786
- startedAt: number;
787
- /** Subagent depth — 1 for a direct child of a top-level agent. */
788
- depth: number;
789
- }
790
- interface SpawnToolState {
791
- /** Currently running children. */
792
- readonly children: ReadonlyMap<string, ChildAgent>;
793
- /**
794
- * Cumulative stats across every completed direct child of this spawn-tool
795
- * instance (returns a copy). Each child's contribution is the cumulative
796
- * `AgentStats` returned by its `agent.run()` — so
797
- * `totalIn`/`totalOut`/`totalCacheRead`/`totalCacheCreation` cover the
798
- * entire subtree (children + grandchildren + …), while `turns` and
799
- * `elapsed` stay parent-loop-only per child and are summed across direct
800
- * children. `elapsed` over-counts when children ran in parallel.
801
- *
802
- * Lives across multiple parent runs that share this instance.
803
- */
804
- readonly totalChildStats: Readonly<AgentStats>;
805
- }
806
- interface SpawnToolOptions {
807
- /** Maximum concurrent sub-agents (default: 3). */
808
- maxConcurrent?: number;
809
- /**
810
- * Maximum subagent depth. 0 disables spawning entirely; 1 allows top-level
811
- * spawns but forbids grandchildren; 3 (default) allows three levels of
812
- * recursion — enough for most orchestration patterns, a sharp ceiling
813
- * against runaway loops.
814
- */
815
- maxDepth?: number;
816
- /**
817
- * Child model override. When unset, the child inherits the parent run's
818
- * resolved model (`ToolContext.model`), falling back to
819
- * `provider.meta.defaultModel` only when the parent didn't expose one.
820
- */
821
- model?: string;
822
- /** Child system prompt override. Per-spawn `input.system` takes precedence. */
823
- system?: string;
824
- /** Child thinking level. */
825
- thinking?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
826
- /** Preset override for children. Shallow-merged over the parent's preset (parent fields still win for anything left unset). */
827
- preset?: Preset;
828
- /**
829
- * Per-child timeout, in milliseconds. When the child exceeds it the spawn
830
- * tool returns a timeout marker, fires `spawn:error`, and destroys the
831
- * child agent. Default: none.
832
- */
833
- timeoutMs?: number;
834
- /**
835
- * When `true` and the parent has a session, the child reuses the parent's
836
- * session — child turns are appended with the child's own `runId`, and the
837
- * resulting `SessionRun` carries `parentRunId` so the tree is
838
- * reconstructible. Default: `false` (child is in-memory only).
839
- *
840
- * **Read-state isolation.** Sharing the session also shares the
841
- * `read_file` / `requireReadBeforeEdit` tracking map (it's keyed
842
- * by `Session`). With `persist: false` the child gets no session,
843
- * so reads inside the subagent populate nothing the parent can see —
844
- * a follow-up `edit` / `multi_edit` in the parent will trip the
845
- * gate with `"has not been read"` even though the model just
846
- * read the file in the child. Use {@link shareReadState} when
847
- * you want the parent's gate to honor the child's reads WITHOUT
848
- * also persisting child turns to the parent's session.
849
- */
850
- persist?: boolean;
851
- /**
852
- * Forward the parent's read-state map to the child agent so the
853
- * `requireReadBeforeEdit` gate and `dedupReads` cache see reads
854
- * across the parent/child boundary. Orthogonal to {@link persist} —
855
- * use this when you want shared read tracking without sharing the
856
- * session's turn history. Default: `false`.
857
- *
858
- * Has no effect when the parent has no read-state to share (no
859
- * session and no explicit `readState` on the parent agent's
860
- * options). Implementation: passes the parent's resolved
861
- * `ReadStateMap` to the child via `AgentOptions.readState`, which
862
- * tools resolve via `ctx.readState ?? getReadState(ctx.session)`.
863
- */
864
- shareReadState?: boolean;
865
- /**
866
- * Forward a curated subset of child hook events (`stream:*`, `tool:*`,
867
- * `turn:after`) onto the parent's hook bus as `child:*` events. Default:
868
- * `true`. Grandchildren bubble through their child transparently.
869
- */
870
- forwardHooks?: boolean;
871
- /** Called when a child agent starts. */
872
- onSpawn?: (child: ChildAgent) => void;
873
- /** Called when a child agent completes (success, abort, timeout, or error). */
874
- onComplete?: (child: ChildAgent, stats: AgentStats, status: NonNullable<ChildRunStats['status']>) => void;
875
- /**
876
- * Named subagent presets the model can select via the `subagent_type`
877
- * input field. Mirrors the Claude Code SDK's surface — models trained
878
- * on it routinely emit `subagent_type: 'Explore' | 'Plan' |
879
- * 'Verification' | 'general-purpose'`, and without a registry the
880
- * field is silently dropped, so hosts wanting type-specialized
881
- * subagents have to invent their own dispatch layer.
882
- *
883
- * Each entry overlays the base spawn config for that particular
884
- * dispatch. Per-call `input.system` still wins over `subagents[type].system`
885
- * so the model can always specialize further.
886
- *
887
- * When the registry is non-empty:
888
- * - `subagent_type` appears in the spawn input schema as a `string`
889
- * enum of the registered keys (plus the always-available
890
- * `'general-purpose'` fallback).
891
- * - Models that pass an unregistered type are routed to
892
- * `'general-purpose'` (no error — degrade gracefully so trained
893
- * models keep working even on hosts that haven't wired every
894
- * type Claude Code uses).
895
- *
896
- * When the registry is empty / unset, the field is omitted entirely
897
- * (preserves the historical schema for hosts that never use this).
898
- *
899
- * Default: `undefined` (no subagent types; `subagent_type` schema
900
- * field hidden).
901
- */
902
- subagents?: SubagentRegistry;
903
- }
904
- /**
905
- * Per-type subagent override applied when the model calls
906
- * `spawn({ subagent_type: '…' })`. All fields are optional; absent
907
- * fields fall back to the parent's resolved configuration (see
908
- * {@link SpawnToolOptions} comments for the merge order).
909
- */
910
- interface SubagentDef {
911
- /**
912
- * System prompt override for this subagent type. Per-call
913
- * `input.system` still wins — model-supplied specialization beats
914
- * preset defaults.
915
- */
916
- system?: string;
917
- /**
918
- * Restrict the child agent's tool registry to this list of canonical
919
- * tool names. Operates as a filter over the parent's tools (the
920
- * parent's selection is the upper bound — a subagent can never gain
921
- * tools the parent doesn't have). When unset, the child inherits the
922
- * parent's full tool list.
923
- *
924
- * Tool names are canonical (registry-key) not wire/alias names — the
925
- * filter runs before aliases are applied. Names that don't match a
926
- * parent tool are silently dropped (matches the lenient behaviour of
927
- * `enabledTools` on MCP configs).
928
- */
929
- tools?: readonly string[];
930
- /**
931
- * Mark this subagent as read-only — equivalent to listing only
932
- * obviously-non-mutating tools (`read_file`, `grep`, `glob`,
933
- * `list_files`) in {@link SubagentDef.tools}. Convenience for the
934
- * common "Plan" / "Explore" subagent shape Claude Code ships.
935
- *
936
- * When both `readonly: true` and `tools` are set, `tools` wins
937
- * (explicit beats implicit).
938
- */
939
- readonly?: boolean;
940
- /**
941
- * Short description rendered into the spawn tool's schema (the
942
- * `subagent_type` field's description) so the model can pick a type
943
- * that matches the task without round-tripping through docs.
944
- */
945
- description?: string;
946
- }
947
- /**
948
- * Map of subagent-type key → preset. Keys are case-sensitive and
949
- * appear verbatim in the spawn input schema's enum so the model emits
950
- * them with the same casing. Common conventions: `'Explore'`,
951
- * `'Plan'`, `'Verification'`, `'general-purpose'` (Claude Code SDK's
952
- * built-in set).
953
- */
954
- type SubagentRegistry = Record<string, SubagentDef>;
955
- /**
956
- * Create a configured spawn tool.
957
- *
958
- * State (`children`, `totalChildStats`, counters, active count) is scoped to
959
- * the returned instance. Multiple parent agents using the same instance will
960
- * share counters + stats + concurrency slots — call `createSpawnTool()` per
961
- * agent (or use the stateless default `spawn`) to keep them isolated.
962
- */
963
- declare function createSpawnTool(options?: SpawnToolOptions): ToolDef & SpawnToolState;
964
- //#endregion
965
- //#region src/tools/tool-search.d.ts
966
- interface LazyToolEntry {
967
- /**
968
- * Wire name (after `toolAliases` rewrite). What the model sees in the
969
- * catalog, what `tool_search` matches against, and what the provider's
970
- * tool list will carry once the entry is unlocked.
971
- */
972
- name: string;
973
- /**
974
- * Canonical (registry-key) name used for unlock-set membership and for the
975
- * loop's `ctx.tools[name]` dispatch lookup. Equal to `name` when no alias
976
- * is configured for this tool.
977
- */
978
- canonicalName: string;
979
- description: string;
980
- inputSchema: Record<string, unknown>;
981
- /** Source MCP server, when applicable. Used for `server`-bulk unlock. */
982
- server?: string;
983
- }
984
- interface ToolSearchToolOptions {
985
- /**
986
- * Snapshot of every lazy tool the model can discover. Built once per run by
987
- * the agent — the tool closes over this array and never mutates it.
988
- */
989
- catalog: readonly LazyToolEntry[];
990
- /**
991
- * Mutable per-run set of unlocked **canonical** tool names. The tool adds
992
- * matches in place; the loop reads the set when rebuilding the wire-level
993
- * tool list. Keyed by canonical (not wire) so dispatch lookups stay
994
- * alias-stable.
995
- *
996
- * Prefer `addUnlock` for cache-stable wire-tool ordering: writes through a
997
- * Set lose unlock order, so the wire-level rebuild that filters by `unlocked`
998
- * has to fall back to registry iteration order — which moves entries every
999
- * time a lazy tool earlier in the registry is unlocked, breaking provider
1000
- * prompt-cache breakpoints. The agent passes both when it owns the unlock
1001
- * tracker, with `addUnlock` mirroring writes into an ordered log.
1002
- */
1003
- unlocked: Set<string>;
1004
- /**
1005
- * Optional callback fired for every canonical name the tool unlocks. When
1006
- * set, the agent uses this to maintain an append-only `dynamicUnlockOrder`
1007
- * so the wire-level tool list emits new unlocks at the tail and keeps the
1008
- * provider prefix cache warm. Idempotent on repeat unlocks of the same
1009
- * name — callers may dedupe internally.
1010
- *
1011
- * Invoked **in addition to** the `unlocked.add` (which still happens for
1012
- * back-compat with callers that only watch the Set).
1013
- */
1014
- addUnlock?: (canonical: string) => void;
1015
- /** Default cap on returned matches when the model omits `limit`. */
1016
- defaultLimit?: number;
1017
- }
1018
- /**
1019
- * Factory for `tool_search`. Auto-injected by the agent when
1020
- * `behavior.toolDisclosure === 'lazy'` and at least one MCP tool is in the
1021
- * registry. Opt out via `behavior.toolSearch.tool === false`.
1022
- */
1023
- declare function createToolSearchTool(options: ToolSearchToolOptions): ToolDef;
1024
- //#endregion
1025
- //#region src/tools/truncate.d.ts
1026
- /**
1027
- * Tail-priority, byte-budgeted truncation shared across tools.
1028
- *
1029
- * "Tail-priority" because the most useful signal in command / job output
1030
- * (errors, exit summaries, the last thing that happened) lives at the END.
1031
- * When `text` exceeds the byte budget the HEAD is dropped and replaced with a
1032
- * marker, keeping as much of the tail as fits.
1033
- *
1034
- * The budget is a UTF-8 *byte* count, not a character count — wire/output
1035
- * accounting is bytes, and a naive `String.prototype.slice` (UTF-16 code
1036
- * units) under-counts multibyte text badly. The cut always lands on a whole
1037
- * code point: the walk steps by code point (surrogate pairs included), so an
1038
- * emoji or CJK glyph is never split into a lone surrogate. As a final safety
1039
- * net against callers that hand us text already sliced mid-codepoint at a raw
1040
- * byte boundary (the classic `Buffer.subarray(...).toString()` pattern, which
1041
- * decodes a partial lead/continuation byte to U+FFFD), a leading run of
1042
- * replacement characters is stripped from the kept tail.
1043
- */
1044
- interface TailTruncateOptions {
1045
- /**
1046
- * Build the marker inserted before the kept tail, given the number of
1047
- * UTF-8 bytes dropped from the head. Defaults to
1048
- * `…(<n> bytes truncated from head)…\n`. Return an empty string to keep
1049
- * the tail with no marker at all.
1050
- */
1051
- marker?: (droppedBytes: number) => string;
1052
- }
1053
- /**
1054
- * Keep the last `maxBytes` UTF-8 bytes of `text`, dropping the head and
1055
- * prefixing a marker. A non-positive `maxBytes` disables truncation and
1056
- * returns `text` unchanged.
1057
- *
1058
- * `maxBytes` budgets the kept tail only; the marker is added on top and may
1059
- * push the returned string slightly past `maxBytes`. That tradeoff is
1060
- * intentional — folding the marker into the budget would shrink the content
1061
- * actually shown.
1062
- */
1063
- declare function tailTruncate(text: string, maxBytes: number, options?: TailTruncateOptions): string;
1064
- //#endregion
1065
- //#region src/tools/validation.d.ts
1066
- /**
1067
- * Tool argument validation against JSON Schema-style inputSchema.
1068
- *
1069
- * Two passes:
1070
- * 1. Required-field presence. Missing or null/undefined required fields fail.
1071
- * 2. Per-property type checks with **best-effort coercion**. Small/OSS models
1072
- * routinely send `"true"` for a `boolean` field or `"42"` for a `number`,
1073
- * and rejecting outright forces a confusing retry. Instead, we auto-heal
1074
- * coerce when the conversion is unambiguous, fail only when the value
1075
- * cannot be reasonably normalized to any of the declared types.
1076
- *
1077
- * Recursion: when a property declares `type: 'array'` with an `items` schema,
1078
- * each item is validated against `items`. Object items are walked one level
1079
- * deep (their declared `properties` get the same coercion + enum checks the
1080
- * top level does). Items that can't be coerced are dropped rather than
1081
- * rejecting the whole call — the model rarely benefits from an
1082
- * all-or-nothing failure on a 20-item list because one entry was malformed.
1083
- * Dropped items are reported back via `droppedItems` so the tool's `execute`
1084
- * can surface a hint to the model if it wants to.
1085
- */
1086
- interface ValidationResult {
1087
- valid: boolean;
1088
- /** Human-readable reason. Present on failure only. */
1089
- error?: string;
1090
- /**
1091
- * Possibly-coerced input. Present iff `valid: true`. Tools should call
1092
- * `execute(coercedInput, ctx)` so auto-healed values reach the tool body.
1093
- * When no coercion was applied, this is reference-equal to the input.
1094
- */
1095
- coercedInput?: Record<string, unknown>;
1096
- /**
1097
- * Names of fields whose values were coerced. Empty when nothing changed.
1098
- * Useful for telemetry (`validation:reject` on failure already carries the
1099
- * reason; this is the success-path equivalent).
1100
- */
1101
- coercions?: readonly string[];
1102
- /**
1103
- * Indexes of array items dropped during recursive validation, keyed by
1104
- * the property name. Empty / absent when nothing was dropped. Tools that
1105
- * care about the discrepancy (e.g. `todowrite` wanting to surface
1106
- * "ignored 2 malformed items") can inspect this.
1107
- */
1108
- droppedItems?: Readonly<Record<string, readonly number[]>>;
1109
- }
1110
- declare function validateToolArgs(input: Record<string, unknown>, schema: Record<string, unknown>): ValidationResult;
1111
- //#endregion
1112
- //#region src/tools/wait-task.d.ts
1113
- /**
1114
- * Stable prefix on the timed-out result. The agent's notification
1115
- * suppression keys on it: results carrying this prefix mean the task is
1116
- * still running, so the pending `<task-notification>` must survive.
1117
- */
1118
- declare const WAIT_TASK_TIMED_OUT_PREFIX = "wait_task: timed out";
1119
- declare const waitTask: ToolDef;
1120
- //#endregion
1121
- //#region src/tools/write-file.d.ts
1122
- /**
1123
- * Write a file, with an idempotency signal when the content is unchanged.
1124
- *
1125
- * Three return shapes — chosen so the model can recognize a no-op without a
1126
- * separate read:
1127
- * - `Created path (N bytes)` — file did not exist
1128
- * - `Updated path (N bytes)` — content differed from on-disk
1129
- * - `No change needed: path already at target state (N bytes)` — equal
1130
- *
1131
- * Race window: in non-process execution contexts (docker, sandbox) shared by
1132
- * multiple agents, another writer can mutate the file between our read and
1133
- * our write. Local process context is single-writer per agent so the race is
1134
- * a non-issue there. Documented rather than locked because the cost of
1135
- * cross-context locking outweighs the cost of a stale "No change" message.
1136
- */
1137
- declare const writeFile: ToolDef;
1138
- //#endregion
1139
- //#region src/headless.d.ts
1140
- type HeadlessStatus = 'completed' | 'aborted' | 'error' | 'timeout';
1141
- interface HeadlessUsage {
1142
- input: number;
1143
- output: number;
1144
- cacheRead: number;
1145
- cacheCreation: number;
1146
- /** Cumulative USD cost when the provider/registry could price the run. */
1147
- cost?: number;
1148
- }
1149
- interface HeadlessErrorInfo {
1150
- message: string;
1151
- /** Typed-error class name (`AgentAbortedError`, `AgentContextExceededError`, …). */
1152
- type: string;
1153
- }
1154
- /**
1155
- * Strictly JSON-serializable postmortem of one headless run. Everything an RL
1156
- * reward function needs: the final answer (`finalText`), the verifiable
1157
- * structured output (`output`, present iff a `schema` was set), usage/turns,
1158
- * and the lossless `transcript` (the SFT training data).
1159
- */
1160
- interface HeadlessResult {
1161
- status: HeadlessStatus;
1162
- /** Concatenated text of the last assistant turn that produced any text. */
1163
- finalText: string;
1164
- /** Schema-enforced structured output (only when `opts.schema` is set). */
1165
- output?: Record<string, unknown>;
1166
- usage: HeadlessUsage;
1167
- turns: number;
1168
- durationMs: number;
1169
- /** Total `tool_call` blocks across the whole transcript. */
1170
- numToolCalls: number;
1171
- /** Finish reason of the final turn that reported one. */
1172
- finishReason?: TurnFinishReason;
1173
- error?: HeadlessErrorInfo;
1174
- sessionId: string;
1175
- /** Incident postmortem (errors, gate blocks, budget events) via run-summary. */
1176
- summary?: RunSummary;
1177
- /** Lossless transcript — raw `session.turns`. Thinking stripped when `includeThinking: false`. */
1178
- transcript: SessionTurn[];
1179
- }
1180
- type HeadlessOutputFormat = 'zidane' | 'provider';
1181
- type ProviderTranscriptFormat = 'anthropic' | 'openai';
1182
- type FormattedHeadlessResult = HeadlessResult | unknown[];
1183
- type FormattedHeadlessTurnEvent = Extract<HeadlessEvent, {
1184
- type: 'turn';
1185
- }> | unknown[];
1186
- declare function exitCodeForHeadlessResult(result: HeadlessResult): number;
1187
- /**
1188
- * Live event union — the in-process equivalent of a `stream-json` line. Every
1189
- * member is JSON-serializable; render to JSONL with {@link headlessEventToJsonl}.
1190
- */
1191
- type HeadlessEvent = {
1192
- type: 'start';
1193
- runId: string;
1194
- provider?: string;
1195
- } | {
1196
- type: 'text';
1197
- delta: string;
1198
- } | {
1199
- type: 'thinking';
1200
- delta: string;
1201
- } | {
1202
- type: 'tool_call';
1203
- callId: string;
1204
- name: string;
1205
- input: Record<string, unknown>;
1206
- } | {
1207
- type: 'tool_result';
1208
- callId: string;
1209
- name: string;
1210
- output: string;
1211
- isError: boolean;
1212
- } | {
1213
- type: 'turn';
1214
- index: number;
1215
- turn: SessionTurn;
1216
- } | {
1217
- type: 'spawn';
1218
- event: 'before' | 'complete' | 'error';
1219
- id: string;
1220
- info?: Record<string, unknown>;
1221
- } | {
1222
- type: 'error';
1223
- message: string;
1224
- errorType?: string;
1225
- } | {
1226
- type: 'result';
1227
- result: HeadlessResult;
1228
- };
1229
- /** Serialize one event as a newline-terminated JSON line (stream-json). */
1230
- declare function headlessEventToJsonl(event: HeadlessEvent): string;
1231
- declare function formattedHeadlessTurnEventToJsonl(event: FormattedHeadlessTurnEvent): string;
1232
- declare function providerTranscriptFormatForProvider(providerName: string): ProviderTranscriptFormat;
1233
- declare function transcriptToProviderMessages(turns: SessionTurn[], providerName: string): unknown[];
1234
- declare function formatHeadlessResult(result: HeadlessResult, options: {
1235
- format: HeadlessOutputFormat;
1236
- providerName: string;
1237
- }): FormattedHeadlessResult;
1238
- declare function formatHeadlessTurnEvent(event: Extract<HeadlessEvent, {
1239
- type: 'turn';
1240
- }>, options: {
1241
- format: HeadlessOutputFormat;
1242
- providerName: string;
1243
- }): FormattedHeadlessTurnEvent;
1244
- interface HeadlessOptions {
1245
- /** User prompt — plain string or multimodal `PromptPart[]`. */
1246
- prompt: string | PromptPart[];
1247
- /** Built provider (e.g. `local()`, `openaiCompat(...)`, `anthropic(...)`). */
1248
- provider: Provider;
1249
- model?: string;
1250
- /** Override the preset system prompt for this run. */
1251
- system?: string;
1252
- thinking?: ThinkingLevel;
1253
- maxTurns?: number;
1254
- maxTokens?: number;
1255
- /** Wall-clock cap; on expiry the run is aborted and `status` becomes `'timeout'`. */
1256
- timeoutMs?: number;
1257
- /** External abort signal — chained with the internal timeout controller. */
1258
- signal?: AbortSignal;
1259
- /** JSON Schema for structured-output enforcement → populates `result.output`. */
1260
- schema?: Record<string, unknown>;
1261
- /** Agent behavior defaults for this headless run. Top-level shortcuts below override matching fields. */
1262
- behavior?: AgentOptions['behavior'];
1263
- /** Tool overrides. Omit to use the basic preset's tools. */
1264
- tools?: Record<string, ToolDef>;
1265
- mcpServers?: McpServerConfig[];
1266
- skills?: AgentOptions['skills'];
1267
- /** Execution context. Defaults to a process context rooted at `cwd`. */
1268
- execution?: ExecutionContext;
1269
- /** Working directory for the default process context (ignored if `execution` is set). */
1270
- cwd?: string;
1271
- /** Reuse / resume an existing session. */
1272
- session?: Session;
1273
- /** Session store for a fresh session (defaults to an in-memory store). */
1274
- store?: SessionStore;
1275
- /** Keep `thinking` blocks in `result.transcript` (default true). */
1276
- includeThinking?: boolean;
1277
- /** Live event callback — the in-process stream-json equivalent. */
1278
- onEvent?: (event: HeadlessEvent) => void;
1279
- }
1280
- /**
1281
- * Run a prompt to completion, headless, and return a single serializable
1282
- * {@link HeadlessResult}. Safe to call concurrently for parallel rollouts —
1283
- * each call builds its own agent + session and tears them down in `finally`.
1284
- */
1285
- declare function runHeadless(opts: HeadlessOptions): Promise<HeadlessResult>;
1286
- interface OpenAIChatMessage {
1287
- role: 'system' | 'user' | 'assistant' | 'tool';
1288
- content: string | null | OpenAIChatContentPart[];
1289
- tool_calls?: Array<{
1290
- id: string;
1291
- type: 'function';
1292
- function: {
1293
- name: string;
1294
- arguments: string;
1295
- };
1296
- }>;
1297
- tool_call_id?: string;
1298
- }
1299
- type OpenAIChatContentPart = {
1300
- type: 'text';
1301
- text: string;
1302
- } | {
1303
- type: 'image_url';
1304
- image_url: {
1305
- url: string;
1306
- };
1307
- } | {
1308
- type: 'input_audio';
1309
- input_audio: {
1310
- data: string;
1311
- format: string;
1312
- };
1313
- } | {
1314
- type: 'video_url';
1315
- video_url: {
1316
- url: string;
1317
- };
1318
- };
1319
- /**
1320
- * Convert raw `session.turns` into standard OpenAI chat-completion messages:
1321
- * assistant turns carry `tool_calls`, and each `tool_result` becomes its own
1322
- * `role: 'tool'` message. This is the drop-in shape for an SFT renderer —
1323
- * unlike `toOpenAI` (session/messages.ts), which emits an internal `_tag`
1324
- * envelope meant for re-sending to a provider, not for training data.
1325
- *
1326
- * Fails closed on corrupt raw turns instead of fabricating tool results; silent
1327
- * placeholders would create structurally-valid but semantically-poisoned SFT
1328
- * examples.
1329
- */
1330
- declare function transcriptToOpenAIMessages(turns: SessionTurn[], options?: {
1331
- strictToolPairing?: boolean;
1332
- }): OpenAIChatMessage[];
1333
- declare function installHeadlessEventAdapter(hooks: Hookable<AgentHooks>, onEvent: (event: HeadlessEvent) => void): () => void;
1334
- //#endregion
1335
- //#region src/eval.d.ts
1336
- interface EvalWorkspaceOptions {
1337
- /**
1338
- * Working directory inside the execution context. When omitted, process-based
1339
- * evals get a fresh host temp dir; Docker evals use the context default.
1340
- *
1341
- * Note: under the shared-Docker harness (`withDocker`), per-case working dirs
1342
- * are assigned by the container (`/workspace/case-N`) and a custom `cwd` is
1343
- * ignored — `withDocker` strips it so cases stay isolated.
1344
- */
1345
- cwd?: string;
1346
- /**
1347
- * Directory visible inside the execution context, copied into the workspace
1348
- * before the agent runs. For Docker, mount local fixtures read-only and point
1349
- * this at the container path, e.g. `/fixtures/react-empty`.
1350
- */
1351
- seedDir?: string;
1352
- /** Relative destination inside the workspace. Defaults to `.`. */
1353
- seedTarget?: string;
1354
- /** Relative files/directories to capture after the run. Defaults to `.`. */
1355
- capture?: string[];
1356
- /** Max text chars retained per captured file. Defaults to 256 KiB. */
1357
- maxFileChars?: number;
1358
- /** Keep a temp process workspace on disk after the eval completes. */
1359
- retain?: boolean;
1360
- }
1361
- interface EvalWorkspaceFile {
1362
- path: string;
1363
- size: number;
1364
- content?: string;
1365
- truncated?: boolean;
1366
- binary?: boolean;
1367
- }
1368
- interface EvalWorkspaceSnapshot {
1369
- cwd: string;
1370
- files: EvalWorkspaceFile[];
1371
- }
1372
- interface EvalScore {
1373
- name: string;
1374
- passed: boolean;
1375
- score?: number;
1376
- details?: string | Record<string, unknown>;
1377
- }
1378
- type MetricDirection = 'higher-is-better' | 'lower-is-better';
1379
- /** Declared metric: a raw signal plus how to normalize it to a `0..1` score. */
1380
- interface MetricSpec {
1381
- min: number;
1382
- max: number;
1383
- direction: MetricDirection;
1384
- /** Grouping tags, e.g. `@efficiency`, `@functionality`, `@quality`. */
1385
- tags?: string[];
1386
- description?: string;
1387
- }
1388
- type MetricSpecMap = Record<string, MetricSpec>;
1389
- /** A normalized metric value attached to one eval case. */
1390
- interface EvalMetric {
1391
- id: string;
1392
- raw: number;
1393
- normalized: number;
1394
- direction: MetricDirection;
1395
- min: number;
1396
- max: number;
1397
- tags: string[];
1398
- description?: string;
1399
- /**
1400
- * True when the metric was declared but never emitted (e.g. its scorer threw
1401
- * before calling `ctx.metric`). Recorded as `normalized: 0` so the run still
1402
- * produces results instead of crashing.
1403
- */
1404
- missing?: boolean;
1405
- }
1406
- /** Emit a raw metric value during a run. */
1407
- type MetricEmitter = (id: string, raw: number) => void;
1408
- interface EvalScorerContext {
1409
- id: string;
1410
- suite?: string;
1411
- tags: string[];
1412
- result: HeadlessResult;
1413
- events: readonly HeadlessEvent[];
1414
- workspace?: EvalWorkspaceSnapshot;
1415
- artifactDir?: string;
1416
- /** Emit a declared metric's raw value. Unknown ids throw at run end. */
1417
- metric: MetricEmitter;
1418
- }
1419
- type EvalScorer = (ctx: EvalScorerContext) => EvalScore | Promise<EvalScore>;
1420
- /**
1421
- * Declare an eval's metric set. Returns the same map, typed; pass it to
1422
- * `EvalCaseOptions.metrics`. Declared metrics that are not emitted are recorded
1423
- * as missing with a normalized score of 0; emitting an undeclared metric is an
1424
- * authoring error and throws.
1425
- */
1426
- declare function defineMetrics<T extends MetricSpecMap>(spec: T): T;
1427
- /** Always-available efficiency metrics derived from `HeadlessResult`. */
1428
- declare const EFFICIENCY_METRICS: {
1429
- 'execution-time': {
1430
- min: number;
1431
- max: number;
1432
- direction: "lower-is-better";
1433
- tags: string[];
1434
- description: string;
1435
- };
1436
- 'provider-tokens': {
1437
- min: number;
1438
- max: number;
1439
- direction: "lower-is-better";
1440
- tags: string[];
1441
- description: string;
1442
- };
1443
- 'cache-read-rate': {
1444
- min: number;
1445
- max: number;
1446
- direction: "higher-is-better";
1447
- tags: string[];
1448
- description: string;
1449
- };
1450
- };
1451
- declare function normalizeMetric(raw: number, spec: MetricSpec): number;
1452
- interface LlmJudgeOptions {
1453
- name?: string;
1454
- provider: Provider;
1455
- model?: string;
1456
- system?: string;
1457
- rubric: string;
1458
- maxTokens?: number;
1459
- /** Wall-clock cap for the judge provider call. Defaults to 60s. */
1460
- timeoutMs?: number;
1461
- /** Select what the judge sees. Defaults to final text plus captured workspace files. */
1462
- input?: (ctx: EvalScorerContext) => string;
1463
- /** Declared metric id to emit the judge's `0..1` score into. */
1464
- metric?: string;
1465
- }
1466
- /**
1467
- * Thrown by `runEvalCase` when a scorer emits a metric id that was not declared
1468
- * in `defineMetrics`. This is an authoring error (a typo'd or stale metric id),
1469
- * not a low score — it fails the eval test rather than being recorded as a
1470
- * failed scorer. Exported so downstream harnesses can type-narrow on it.
1471
- */
1472
- declare class EvalMetricError extends Error {
1473
- constructor(message: string);
1474
- }
1475
- interface ReusableExecutionContext {
1476
- /**
1477
- * Execution context facade that reuses one underlying handle. Its
1478
- * `destroy()` is intentionally a no-op; call `dispose()` when the surrounding
1479
- * fixture/run owns teardown.
1480
- */
1481
- execution: ExecutionContext;
1482
- /** Destroy the underlying handle if it was spawned. Idempotent. */
1483
- dispose: () => Promise<void>;
1484
- /** Current underlying handle, if the agent has spawned one. */
1485
- handle: () => ExecutionHandle | undefined;
1486
- }
1487
- /**
1488
- * Wrap an execution context so repeated agent runs share one handle until the
1489
- * caller disposes it. This is useful for eval fixtures that want per-test
1490
- * Docker/process lifetime while still using `runHeadless()` per turn.
1491
- */
1492
- declare function createReusableExecutionContext(base: ExecutionContext): ReusableExecutionContext;
1493
- interface EvalAgentRunStats extends EvalRunUsage {
1494
- durationMs: number;
1495
- turns: number;
1496
- toolCalls: number;
1497
- }
1498
- interface EvalAgentStats extends EvalRunUsage {
1499
- /** Number of completed `run()` calls. */
1500
- runs: number;
1501
- /** Sum of per-run agent turns. */
1502
- turns: number;
1503
- /** Sum of per-run tool calls. */
1504
- toolCalls: number;
1505
- /** Sum of per-run wall-clock durations. */
1506
- durationMs: number;
1507
- }
1508
- interface EvalAgentRunResult {
1509
- /** Full headless result. Its transcript is scoped to this run. */
1510
- result: HeadlessResult;
1511
- /** Per-run usage and trajectory counters. */
1512
- stats: EvalAgentRunStats;
1513
- /** Transcript turns added by this run (same view as `result.transcript`). */
1514
- newTranscript: SessionTurn[];
1515
- }
1516
- type EvalAgentMcpServers = readonly McpServerConfig[] | (() => readonly McpServerConfig[] | Promise<readonly McpServerConfig[]>);
1517
- interface CreateEvalAgentOptions extends Omit<HeadlessOptions, 'prompt' | 'provider' | 'execution' | 'cwd' | 'session' | 'store' | 'mcpServers' | 'onEvent' | 'signal'> {
1518
- provider: Provider;
1519
- /**
1520
- * Working directory for the default process context. Ignored when
1521
- * `execution` is supplied.
1522
- */
1523
- cwd?: string;
1524
- /**
1525
- * Execution context for agent tools. Wrapped with
1526
- * `createReusableExecutionContext` so runs share one handle until `dispose`.
1527
- */
1528
- execution?: ExecutionContext;
1529
- /** Session to reuse across runs. When omitted, one in-memory session is created. */
1530
- session?: Session;
1531
- /** Store used for the auto-created session. Defaults to an in-memory store. */
1532
- store?: SessionStore;
1533
- /** Static or lazily resolved MCP servers. Resolved fresh before each run. */
1534
- mcpServers?: EvalAgentMcpServers;
1535
- /** Live event callback for every run. */
1536
- onEvent?: (event: HeadlessEvent) => void;
1537
- }
1538
- interface EvalAgentRunOptions extends Omit<HeadlessOptions, 'provider' | 'execution' | 'cwd' | 'session' | 'store'> {
1539
- prompt: HeadlessOptions['prompt'];
1540
- }
1541
- interface EvalAgent {
1542
- run: (options: EvalAgentRunOptions) => Promise<EvalAgentRunResult>;
1543
- readonly stats: EvalAgentStats;
1544
- session: () => Promise<Session>;
1545
- dispose: () => Promise<void>;
1546
- [Symbol.asyncDispose]: () => Promise<void>;
1547
- }
1548
- /**
1549
- * Multi-turn eval agent over the low-level headless runner. It keeps session
1550
- * and execution lifetime outside any Playwright-specific fixture layer,
1551
- * so downstream platforms can wrap it with their own `agent.run(...)` shape.
1552
- */
1553
- declare function createEvalAgent(options: CreateEvalAgentOptions): EvalAgent;
1554
- type TrajectoryStepKind = 'think' | 'text' | 'tool';
1555
- /**
1556
- * One grouped step in an eval trajectory. Consecutive blocks of the same kind
1557
- * (and, for tools, the same tool name) collapse into a single step with a
1558
- * `count`. A different kind interrupting the run breaks the group.
1559
- *
1560
- * Serializable by design so trajectories round-trip to disk and can be diffed
1561
- * or replayed by other tooling.
1562
- */
1563
- interface TrajectoryStep {
1564
- kind: TrajectoryStepKind;
1565
- /** Tool name for `kind: 'tool'` steps (canonical, e.g. `read_file`). */
1566
- name?: string;
1567
- /** Number of consecutive occurrences grouped into this step. */
1568
- count: number;
1569
- /** Approx wall-clock ms attributed to this step's turns, when derivable. */
1570
- durationMs?: number;
1571
- }
1572
- interface Trajectory {
1573
- steps: TrajectoryStep[];
1574
- /** Total blocks across all steps (sum of `count`). */
1575
- totalBlocks: number;
1576
- }
1577
- /**
1578
- * Build an ordered, grouped trajectory from a transcript. Walks assistant
1579
- * turns in order, emitting `think` / `text` / `tool:<name>` steps, grouping
1580
- * only consecutive identical kinds. Per-step duration is approximated from the
1581
- * owning turn's `createdAt` delta to the next turn.
1582
- */
1583
- declare function buildTrajectory(transcript: SessionTurn[]): Trajectory;
1584
- /** Render a trajectory as a one-line timeline string (no color). */
1585
- declare function formatTrajectoryLine(trajectory: Trajectory): string;
1586
- interface EvalArtifacts {
1587
- dir: string;
1588
- result?: string;
1589
- events?: string;
1590
- transcript?: string;
1591
- workspace?: string;
1592
- }
1593
- interface EvalCaseResult {
1594
- id: string;
1595
- suite?: string;
1596
- /** Run variant this result belongs to (e.g. `baseten:zai-org/GLM-5.1`). */
1597
- variant?: string;
1598
- tags: string[];
1599
- result: HeadlessResult;
1600
- /** Mean normalized metric score in [0, 1] when metrics are declared; otherwise mean scorer score. */
1601
- score: number;
1602
- /** True when every scorer passed. */
1603
- passed: boolean;
1604
- scores: EvalScore[];
1605
- /** Normalized metrics for this case (empty when no metrics declared). */
1606
- metrics: EvalMetric[];
1607
- /** Mean normalized score per tag, e.g. `{ '@efficiency': 0.8 }`. */
1608
- tagScores: Record<string, number>;
1609
- /** Ordered, grouped step timeline derived from the transcript. */
1610
- trajectory: Trajectory;
1611
- events: HeadlessEvent[];
1612
- artifacts?: EvalArtifacts;
1613
- workspace?: EvalWorkspaceSnapshot;
1614
- workspaceError?: string;
1615
- /** Absolute path to the eval definition file, for editor links. */
1616
- sourceFile?: string;
1617
- }
1618
- interface EvalCaseOptions extends Omit<HeadlessOptions, 'onEvent'> {
1619
- id: string;
1620
- suite?: string;
1621
- /**
1622
- * Run variant label when the same eval runs against several provider/model
1623
- * targets in one run (e.g. `baseten:zai-org/GLM-5.1`). Flows into
1624
- * {@link EvalCaseResult.variant}, namespaces artifacts, and drives the
1625
- * reporter's per-variant tables + comparison matrix.
1626
- */
1627
- variant?: string;
1628
- tags?: string[];
1629
- artifactDir?: string;
1630
- workspace?: EvalWorkspaceOptions;
1631
- scorers?: EvalScorer[];
1632
- /**
1633
- * Declared metric set. Auto-merged with {@link EFFICIENCY_METRICS} so every
1634
- * eval gets comparable efficiency metrics for free. All declared metrics must
1635
- * be emitted (via auto-emit or `ctx.metric`) or the run throws.
1636
- */
1637
- metrics?: MetricSpecMap;
1638
- onEvent?: (event: HeadlessEvent) => void;
1639
- /** Absolute path to the eval definition file. Set via `import.meta.url`. */
1640
- sourceFile?: string;
1641
- }
1642
- interface EvalRunUsage {
1643
- input: number;
1644
- output: number;
1645
- cacheRead: number;
1646
- cacheCreation: number;
1647
- cost: number;
1648
- }
1649
- interface EvalRunSummaryCase {
1650
- id: string;
1651
- suite?: string;
1652
- variant?: string;
1653
- passed: boolean;
1654
- score: number;
1655
- status: HeadlessResult['status'];
1656
- durationMs: number;
1657
- scores: EvalScore[];
1658
- metrics: EvalMetric[];
1659
- tagScores: Record<string, number>;
1660
- trajectory: Trajectory;
1661
- }
1662
- interface MetricStats {
1663
- mean: number;
1664
- min: number;
1665
- max: number;
1666
- p50: number;
1667
- p90: number;
1668
- zeroCount: number;
1669
- values: number[];
1670
- }
1671
- interface EvalRunMetricAggregate {
1672
- id: string;
1673
- direction: MetricDirection;
1674
- tags: string[];
1675
- raw: MetricStats;
1676
- normalized: MetricStats;
1677
- }
1678
- /** Aggregate rollup for one run variant (provider/model target). */
1679
- interface EvalVariantSummary {
1680
- variant: string;
1681
- count: number;
1682
- passed: number;
1683
- score: number;
1684
- durationMs: number;
1685
- usage: EvalRunUsage;
1686
- }
1687
- interface EvalRunSummary {
1688
- count: number;
1689
- passed: number;
1690
- score: number;
1691
- durationMs: number;
1692
- usage: EvalRunUsage;
1693
- cases: EvalRunSummaryCase[];
1694
- /** Per-metric stats across every case that emitted the metric. */
1695
- metrics: EvalRunMetricAggregate[];
1696
- /** Mean normalized score per tag across all cases. */
1697
- tagScores: Record<string, number>;
1698
- /** Per-variant rollups, present when any case carries a variant label. */
1699
- variants?: EvalVariantSummary[];
1700
- }
1701
- interface EvalRunReporterOptions {
1702
- /** Directory where per-case results and `run-summary.json` are written. */
1703
- outputDir?: string;
1704
- /** Enable ANSI colors. Defaults to TTY-aware auto color. */
1705
- color?: boolean;
1706
- }
1707
- interface EvalRunReporter {
1708
- readonly results: readonly EvalCaseResult[];
1709
- record: (result: EvalCaseResult) => Promise<void>;
1710
- flush: () => Promise<EvalRunSummary>;
1711
- format: () => string;
1712
- }
1713
- /** Context handed to an eval definition factory at registration time. */
1714
- interface EvalDefinitionContext {
1715
- /** Agent-under-test provider. */
1716
- provider: Provider;
1717
- /** Provider used by `llmJudge` scorers. Defaults to `provider`. */
1718
- judge: Provider;
1719
- /** Optional agent model override; evals should pass it to `EvalCaseOptions.model`. */
1720
- model?: string;
1721
- /** Optional judge model override; evals should pass it to `llmJudge({ model })`. */
1722
- judgeModel?: string;
1723
- }
1724
- type EvalDefinition = (ctx: EvalDefinitionContext) => EvalCaseOptions;
1725
- /**
1726
- * Register an eval definition. Eval files call this at module load; the harness
1727
- * (`buildRegisteredEvals`) materializes them with a provider at run time. The
1728
- * factory keeps definitions lazy so a single registry serves any provider/judge
1729
- * pairing without re-importing eval files.
1730
- *
1731
- * Returns the same factory so a file can also `export default` it for direct,
1732
- * registry-free use (e.g. hermetic unit tests).
1733
- */
1734
- declare function defineEval(define: EvalDefinition): EvalDefinition;
1735
- /** Snapshot of every registered eval, materialized for one provider/judge pair. */
1736
- declare function buildRegisteredEvals(ctx: EvalDefinitionContext): EvalCaseOptions[];
1737
- /** Drop every registered eval — test isolation helper. */
1738
- declare function clearRegisteredEvals(): void;
1739
- declare function runEvalCase(options: EvalCaseOptions): Promise<EvalCaseResult>;
1740
- declare function statusCompleted(name?: string): EvalScorer;
1741
- declare function fileExists(path: string, name?: string): EvalScorer;
1742
- declare function fileExistsOneOf(paths: string[], name?: string): EvalScorer;
1743
- declare function fileContains(path: string, expected: string | RegExp, name?: string): EvalScorer;
1744
- declare function fileContentQuality(path: string, expected: string, name?: string): EvalScorer;
1745
- declare function llmJudge(options: LlmJudgeOptions): EvalScorer;
1746
- /**
1747
- * Aggregate a group of boolean scorers into a single `0..1` functionality
1748
- * metric (fraction passed) and emit it. Useful for "N of M files present".
1749
- */
1750
- declare function functionalityMetric(metricId: string, scorers: EvalScorer[], name?: string): EvalScorer;
1751
- declare function formatEvalCaseSummary(result: EvalCaseResult): string;
1752
- declare function formatEvalRunSummary(results: readonly EvalCaseResult[]): string;
1753
- /** Minimal subset of a test runner's API the eval harness needs. */
1754
- interface EvalTestRunner {
1755
- it: (name: string, fn: () => Promise<void> | void) => void;
1756
- afterAll: (fn: () => Promise<void> | void) => void;
1757
- }
1758
- interface RegisterEvalTestsOptions {
1759
- cases: EvalCaseOptions[];
1760
- runner: EvalTestRunner;
1761
- reporter?: EvalRunReporter;
1762
- artifactDir?: string;
1763
- /**
1764
- * When true (default), each case asserts only that the agent run reached a
1765
- * terminal `completed` status — scores are recorded but never fail the test.
1766
- * Evals are scoring tools, not deterministic assertions.
1767
- */
1768
- failOnIncomplete?: boolean;
1769
- /** Print the aggregated run summary after all cases. Default true. */
1770
- printSummary?: boolean;
1771
- /** Repeat each case N times (each repetition is its own test). Default 1. */
1772
- repeat?: number;
1773
- /** Teardown run once after all cases (e.g. dispose a shared container). */
1774
- dispose?: () => Promise<void> | void;
1775
- /**
1776
- * Max eval cases to run concurrently. Each case keeps its own workspace dir,
1777
- * so a shared container runs them in parallel safely. Default 1 (sequential).
1778
- */
1779
- concurrency?: number;
1780
- }
1781
- /**
1782
- * Register one test per eval case against a test runner, funnel every result
1783
- * into a shared reporter, and print the aggregated summary once after all cases.
1784
- *
1785
- * A failing test means the agent run itself broke (provider/tool/timeout). Low
1786
- * scores are reported, not asserted — see {@link RegisterEvalTestsOptions.failOnIncomplete}.
1787
- */
1788
- declare function registerEvalTests(options: RegisterEvalTestsOptions): EvalRunReporter;
1789
- declare function createEvalRunReporter(options?: EvalRunReporterOptions): EvalRunReporter;
1790
- declare function buildEvalRunSummary(input: readonly EvalCaseResult[]): EvalRunSummary;
1791
- declare function efficiencyMetricValues(result: HeadlessResult): Record<keyof typeof EFFICIENCY_METRICS, number>;
1792
- declare function emitEfficiencyMetrics(emit: MetricEmitter, result: HeadlessResult): void;
1793
- declare function finalizeEvalMetrics(specs: MetricSpecMap, raw: Map<string, number>): EvalMetric[];
1794
- declare function computeEvalTagScores(metrics: EvalMetric[]): Record<string, number>;
1795
- declare function artifactPath(root: string, result: EvalCaseResult): string;
1796
- declare function relativeArtifactPath(root: string, path: string): string;
1797
- //#endregion
1798
- //#region src/loop.d.ts
1799
- /**
1800
- * Canonical tool_result text emitted when a tool call is interrupted by the
1801
- * user mid-flight (Esc / Ctrl-C / external `AbortSignal`). Mirrors Claude
1802
- * Code's `INTERRUPT_MESSAGE_FOR_TOOL_USE` so downstream consumers can pattern
1803
- * match a single string across both harnesses. Always paired with
1804
- * `isError: true` on the wire — the model treats it as a failed call rather
1805
- * than a successful tool response.
1806
- */
1807
- declare const INTERRUPT_MESSAGE_FOR_TOOL_USE = "[Request interrupted by user for tool use]";
1808
- /**
1809
- * Canonical tool_result text emitted when a tool call is skipped because a
1810
- * steering message arrived between dispatches inside
1811
- * {@link executeToolBatch}. Distinguished from
1812
- * {@link INTERRUPT_MESSAGE_FOR_TOOL_USE} so consumers can split "user
1813
- * cancelled" from "framework superseded".
1814
- */
1815
- declare const TOOL_USE_SKIPPED_MESSAGE = "[Tool use skipped \u2014 superseded by user message]";
1816
- /**
1817
- * Canonical tool_result text emitted when a single tool call is cancelled
1818
- * mid-flight via `agent.cancelTool(callId)` (typically the TUI's
1819
- * "cancel this tool" affordance). Distinguished from
1820
- * {@link INTERRUPT_MESSAGE_FOR_TOOL_USE} (run-wide user abort) and
1821
- * {@link TOOL_USE_SKIPPED_MESSAGE} (steered) so the model — and downstream
1822
- * consumers — can tell the three apart by string match.
1823
- *
1824
- * Always paired with `isError: true` on the wire so the model treats the
1825
- * call as failed rather than as a successful response. The remaining tool
1826
- * calls in the batch continue running, in contrast with a full-run abort.
1827
- */
1828
- declare const TOOL_USE_CANCELLED_MESSAGE = "[Tool call cancelled by user]";
1829
- /**
1830
- * Canonical `tool_result.content` text emitted to siblings that were
1831
- * cancelled by a `shell` error in the same batch. Distinct from
1832
- * {@link INTERRUPT_MESSAGE_FOR_TOOL_USE} (user-issued abort) and
1833
- * {@link TOOL_USE_SKIPPED_MESSAGE} (steered) so consumers can split
1834
- * the three causes by string-match.
1835
- */
1836
- declare const SHELL_CASCADE_CANCEL_MESSAGE = "Cancelled: a sibling `shell` call in the same batch errored; re-run independently if still needed.";
1837
- //#endregion
1838
- //#region src/loop-persistence.d.ts
1839
- /**
1840
- * Bytes of head content included in the inline preview block. 2 KiB matches
1841
- * Claude Code's `PREVIEW_SIZE_BYTES` — enough for the model to identify the
1842
- * content class (error output / structured data / log shape) and decide
1843
- * whether to call `read_file` on the persisted path for the full payload.
1844
- *
1845
- * Tail-priority preview (matching `shell`'s truncation strategy) was
1846
- * considered but rejected: most "what is this?" decisions get made from
1847
- * the head, and the path is in the stub for the rare case where the tail
1848
- * matters.
1849
- */
1850
- declare const PERSISTENCE_PREVIEW_BYTES: number;
1851
- /**
1852
- * Byte-stable prefix every {@link buildPersistedStub} output starts with.
1853
- * Exported so wire-level passes (tail compaction, future stale-output
1854
- * elision) can recognize a persisted stub and preserve its path attribute
1855
- * rather than replacing the stub with their own — losing the pointer to
1856
- * the on-disk blob.
1857
- *
1858
- * Bound to the literal opening of the XML tag; changing the stub format
1859
- * requires updating this constant in lockstep (and shipping a migration
1860
- * for in-flight sessions).
1861
- */
1862
- declare const PERSISTED_STUB_PREFIX = "<persisted-output tool=\"";
1863
- /**
1864
- * Resolve the per-session persistence directory under `<userDir>/tool-results/<sessionId>/`.
1865
- *
1866
- * The chat layer calls this at session activation and forwards the result
1867
- * via `behavior.persistDir`. Exposed as a public helper so SDK consumers
1868
- * pick the same layout — single source of truth for "where do blobs live".
1869
- */
1870
- declare function resolvePersistDir(opts: {
1871
- userDir: string;
1872
- sessionId: string;
1873
- }): string;
1874
- /**
1875
- * Resolve the per-session background-tasks directory under
1876
- * `<userDir>/<sessionId>/tasks/`.
1877
- *
1878
- * The chat layer calls this at session activation and forwards the result
1879
- * via `behavior.tasksDir`. Same shape as {@link resolvePersistDir}: hosts
1880
- * get a single source of truth for "where do task log files live".
1881
- * Created on first write; cleanup is the session-delete path's job.
1882
- */
1883
- declare function resolveTasksDir(opts: {
1884
- userDir: string;
1885
- sessionId: string;
1886
- }): string;
1887
- /**
1888
- * Inputs to {@link maybePersistToolResult}. Kept as a struct so the loop's
1889
- * call site stays readable and additional optional knobs (compression,
1890
- * mime detection, …) land without re-threading every call site.
1891
- */
1892
- interface PersistInput {
1893
- /** Canonical tool name — checked against `excludeTools`. */
1894
- toolName: string;
1895
- /** `tool_use` id from the assistant turn. Used as the filename. */
1896
- callId: string;
1897
- /** Result returned by the tool (post-`tool:transform`). */
1898
- output: string | ToolResultContent[];
1899
- /** Byte threshold; outputs at or below stay inline. */
1900
- threshold: number;
1901
- /** Canonical tool names that bypass persistence. */
1902
- excludeTools?: readonly string[];
1903
- /** Persistence root directory. Created on first write. */
1904
- persistDir: string;
1905
- /**
1906
- * Optional cap on the total bytes of persisted blobs under `persistDir`.
1907
- * When set (and > 0), after a successful write the helper sweeps the
1908
- * directory and removes the oldest `*.txt` blobs (by mtime) until the
1909
- * sum of remaining sizes is at or below the cap.
1910
- *
1911
- * Bound to the **current session** because `persistDir` is per-session
1912
- * (see {@link resolvePersistDir}); eviction never crosses session
1913
- * boundaries. The new blob is always preserved — its mtime is the
1914
- * latest, so the LRU sort guarantees older blobs go first.
1915
- *
1916
- * Skipped when the value isn't a positive finite number. Also skipped when
1917
- * {@link writeBlob} is supplied: without remote stat/delete primitives, a
1918
- * local host sweep would inspect the wrong filesystem. Remote contexts rely
1919
- * on their own ephemeral teardown / storage quotas instead. Eviction failures
1920
- * (permissions, races) are surfaced through `ZIDANE_DEBUG` but never block
1921
- * the calling tool result; an over-cap dir is a housekeeping concern, not a
1922
- * correctness one.
1923
- */
1924
- maxBytes?: number;
1925
- /**
1926
- * Optional writer that routes the blob through a specific filesystem. The
1927
- * agent loop passes `(path, content) => ctx.execution.writeFile(handle, …)`
1928
- * so the persisted blob lands on the SAME filesystem the model reads it back
1929
- * from (`read_file` → `ctx.execution.readFile`) — correct for docker /
1930
- * sandbox / remote / edge contexts, not only the host process.
1931
- *
1932
- * Omitted → falls back to a local atomic write (`<path>.tmp` + rename) on the
1933
- * host `fs`, the historical behavior. A routed write is not atomic, which is
1934
- * immaterial here: the blob is written once and fully awaited BEFORE the stub
1935
- * that references it is emitted, so a crash mid-write loses both halves
1936
- * consistently — there is no torn-read window for a subsequent turn.
1937
- */
1938
- writeBlob?: (path: string, content: string) => Promise<void>;
1939
- }
1940
- type PersistOutcome = {
1941
- kind: 'skip';
1942
- reason: 'disabled' | 'excluded' | 'under-threshold' | 'unsupported-shape' | 'unsafe-call-id' | 'invalid-persist-dir';
1943
- } | {
1944
- kind: 'persisted';
1945
- output: string;
1946
- originalBytes: number;
1947
- persistedPath: string;
1948
- evicted?: {
1949
- files: number;
1950
- bytes: number;
1951
- };
1952
- } | {
1953
- kind: 'error';
1954
- reason: 'write-failed';
1955
- error: Error;
1956
- output: string;
1957
- originalBytes: number;
1958
- };
1959
- /**
1960
- * Decide-and-persist for a single tool result. Pure decision + filesystem
1961
- * side-effect; returns the new wire-level `output` string when substitution
1962
- * happened, otherwise tells the caller to leave the result alone.
1963
- *
1964
- * Atomicity: the local fallback writes through `<path>.tmp` + `rename` so a
1965
- * concurrent read (or a crash mid-write) never sees a half-written blob. A
1966
- * routed write (`input.writeBlob`, e.g. a sandbox `writeFile`) is not atomic;
1967
- * see the field doc for why that's safe here.
1968
- *
1969
- * Text-only `ToolResultContent[]` results are flattened and persisted as
1970
- * text. Mixed structured content still bypasses persistence because the inline
1971
- * image/document bytes are the point of the call and a mixed result is not
1972
- * representable as a single `.txt` file without dropping media.
1973
- */
1974
- declare function maybePersistToolResult(input: PersistInput): Promise<PersistOutcome>;
1975
- interface BuildStubInput {
1976
- toolName: string;
1977
- originalBytes: number;
1978
- persistedPath: string;
1979
- output: string;
1980
- /** Preview cap in bytes. Default {@link PERSISTENCE_PREVIEW_BYTES}. */
1981
- previewBytes?: number;
1982
- }
1983
- /**
1984
- * Render the byte-stable `<persisted-output>` stub the model sees in place
1985
- * of the original `tool_result`.
1986
- *
1987
- * Format choices:
1988
- * - XML wrapper because models reliably parse it as structural.
1989
- * - Byte count + path in attributes so the model can decide whether to
1990
- * `read_file` the persisted blob without scanning the preview.
1991
- * - Preview always shows the head — `shell`'s tail-priority truncation is
1992
- * irrelevant here because the model has the full path if it needs the
1993
- * tail.
1994
- * - No timestamps, no random UUIDs inside the stub: every byte must be
1995
- * reproducible from the inputs, otherwise re-emission on subsequent
1996
- * turns would bust the prompt cache.
1997
- *
1998
- * Exported for tests (asserting the byte-stable contract) and for SDK
1999
- * consumers wiring their own persistence middleware against the same
2000
- * surface.
2001
- */
2002
- declare function buildPersistedStub(input: BuildStubInput): string;
2003
- /**
2004
- * Remove every persisted blob belonging to a session. Called by the chat
2005
- * layer from its session-delete path so closing a session frees the disk
2006
- * footprint alongside the SQLite row.
2007
- *
2008
- * Idempotent — missing directory (session never persisted anything) is a
2009
- * no-op, not an error. Wraps the `rm -rf` so a permissions blip on one
2010
- * blob doesn't propagate to the caller; the chat layer can't usefully
2011
- * recover from "couldn't unlink a result file" mid-delete.
2012
- */
2013
- declare function cleanupPersistedSession(persistRoot: string): Promise<void>;
2014
- //#endregion
2015
- //#region src/mcp/oauth-provider.d.ts
2016
- /**
2017
- * Per-server persisted state. Subfields are optional so a partial save
2018
- * (e.g. `saveCodeVerifier` arriving before `saveTokens`) doesn't blow away
2019
- * earlier subfields — the provider always patches, never replaces.
2020
- */
2021
- interface McpCredentialEntry {
2022
- tokens?: OAuthTokens;
2023
- clientInformation?: OAuthClientInformationMixed;
2024
- discoveryState?: OAuthDiscoveryState;
2025
- }
2026
- interface McpCredentialStore {
2027
- load: (name: string) => McpCredentialEntry | undefined;
2028
- save: (name: string, entry: McpCredentialEntry) => void;
2029
- delete: (name: string) => void;
2030
- }
2031
- /**
2032
- * In-memory store — primarily for tests, but valid as a no-persistence option
2033
- * (tokens evaporate on process exit, the user re-auths every cold start).
2034
- */
2035
- declare function createMemoryMcpCredentialStore(seed?: Record<string, McpCredentialEntry>): McpCredentialStore;
2036
- interface McpOAuthProviderOptions {
2037
- /** Server name — used as the storage key. */
2038
- name: string;
2039
- /** Persistence backend. */
2040
- store: McpCredentialStore;
2041
- /**
2042
- * Loopback callback URI. Pass `undefined` for bootstrap (non-interactive
2043
- * mode — stored tokens + refresh only, never opens a browser).
2044
- */
2045
- redirectUri?: string;
2046
- /**
2047
- * Invoked when the SDK wants the user agent to navigate to the authorization
2048
- * URL. Typically the host opens the browser AND emits a hook so the TUI can
2049
- * render the URL in a status row. No-op in non-interactive mode (the SDK
2050
- * still calls this before throwing `UnauthorizedError` from connect).
2051
- */
2052
- onAuthorizationUrl?: (url: URL) => void | Promise<void>;
2053
- /**
2054
- * `client_name` used in dynamic client registration. Defaults to `'zidane'`.
2055
- * Some servers display this string to the user on the consent screen.
2056
- */
2057
- clientName?: string;
2058
- /**
2059
- * Override the requested OAuth scope. Default: unset (the SDK negotiates
2060
- * via the server's metadata).
2061
- */
2062
- scope?: string;
2063
- }
2064
- declare class McpOAuthProvider implements OAuthClientProvider {
2065
- private readonly name;
2066
- private readonly store;
2067
- private readonly _redirectUri?;
2068
- private readonly onAuthorizationUrl?;
2069
- private readonly clientName;
2070
- private readonly _scope?;
2071
- private codeVerifierValue;
2072
- constructor(opts: McpOAuthProviderOptions);
2073
- get redirectUrl(): string | URL | undefined;
2074
- get clientMetadata(): OAuthClientMetadata;
2075
- tokens(): OAuthTokens | undefined;
2076
- saveTokens(tokens: OAuthTokens): void;
2077
- clientInformation(): OAuthClientInformationMixed | undefined;
2078
- saveClientInformation(info: OAuthClientInformationMixed): void;
2079
- discoveryState(): OAuthDiscoveryState | undefined;
2080
- saveDiscoveryState(state: OAuthDiscoveryState): void;
2081
- saveCodeVerifier(verifier: string): void;
2082
- codeVerifier(): string;
2083
- redirectToAuthorization(url: URL): Promise<void>;
2084
- /**
2085
- * Wipe stored credentials when the server reports the cached state is no
2086
- * longer valid. The SDK calls this with a scope hint:
2087
- * - `'tokens'` → access/refresh revoked, keep client registration
2088
- * - `'client'` → client registration invalidated, reset everything
2089
- * - `'verifier'`→ PKCE state stale (e.g. mismatched state param)
2090
- * - `'discovery'` → discovery metadata stale (servers re-keyed)
2091
- * - `'all'` → full reset
2092
- */
2093
- invalidateCredentials(scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'): Promise<void>;
2094
- private patch;
2095
- }
2096
- /**
2097
- * True when an HTTP transport's auth headers already include an explicit
2098
- * Authorization. Used by the bootstrap escape-hatch: a user who provided
2099
- * their own bearer token shouldn't be auto-promoted to OAuth on a 401.
2100
- *
2101
- * Case-insensitive — Node normalizes outgoing headers to lowercase but
2102
- * users hand-write `Authorization` in configs.
2103
- */
2104
- declare function hasAuthorizationHeader(headers: Record<string, string> | undefined): boolean;
2105
- //#endregion
2106
- //#region src/mcp/login.d.ts
2107
- interface LoginMcpServerOptions {
2108
- /** Persistence — same store the bootstrap path reads from. */
2109
- store: McpCredentialStore;
2110
- /**
2111
- * Invoked with the authorization URL once it's ready. Hosts typically
2112
- * (a) emit `mcp:auth:url` for the TUI, and (b) call `tryOpenBrowser`.
2113
- * The URL is identical to the one passed to the `mcp:auth:url` hook
2114
- * fired automatically — this callback is a synchronous hook for callers
2115
- * that don't want to wire the agent hook machinery.
2116
- */
2117
- onAuthorizationUrl?: (url: URL) => void | Promise<void>;
2118
- /** Cancels the flow (esc / close modal / SIGINT). */
2119
- signal?: AbortSignal;
2120
- /** Agent hooks. The flow emits `mcp:auth:url`/`success`/`error` when wired. */
2121
- hooks?: Hookable<AgentHooks>;
2122
- /** Override `client_name` shown on consent screens. Default: 'zidane'. */
2123
- clientName?: string;
2124
- /** Override the requested OAuth scope. */
2125
- scope?: string;
2126
- /**
2127
- * Override the loopback callback path. Default: `/callback`. Useful only
2128
- * for servers that pinned a different path during registration.
2129
- */
2130
- callbackPath?: string;
2131
- /**
2132
- * Maximum time to wait for the user to complete the browser flow, in ms.
2133
- * The user can also cancel via `signal`. Default: 5 minutes.
2134
- */
2135
- timeoutMs?: number;
2136
- }
2137
- interface LoginMcpServerResult {
2138
- /** Stored OAuth tokens after a successful exchange. */
2139
- tokens: NonNullable<ReturnType<McpOAuthProvider['tokens']>>;
2140
- /**
2141
- * Upstream tool descriptors discovered after re-connecting with the new
2142
- * tokens. Already filtered by the server's `enabledTools` / `disabledTools`
2143
- * is NOT applied here — that's a bootstrap concern. Hosts that want filtering
2144
- * should pass the result through `connectMcpServers` rebuild on the next
2145
- * session activation rather than reusing this list verbatim.
2146
- */
2147
- tools: Array<{
2148
- name: string;
2149
- description?: string | null;
2150
- inputSchema?: unknown;
2151
- }>;
2152
- }
2153
- /**
2154
- * Run the full interactive OAuth flow for `config`. Only supports `sse` and
2155
- * `streamable-http` transports — `stdio` MCP servers don't speak OAuth.
2156
- *
2157
- * Throws on:
2158
- * - Wrong transport.
2159
- * - Abort signal.
2160
- * - Browser-side error (user denied, server rejected, etc.).
2161
- * - Code exchange failure.
2162
- * - Post-exchange connect failure.
2163
- *
2164
- * Always closes the loopback callback server before returning, success or
2165
- * failure.
2166
- */
2167
- declare function loginMcpServer(config: McpServerConfig, options: LoginMcpServerOptions): Promise<LoginMcpServerResult>;
2168
- //#endregion
2169
- //#region src/mcp/oauth-callback.d.ts
2170
- /**
2171
- * Local loopback HTTP callback for OAuth 2.0 authorization code flows.
2172
- *
2173
- * Stands up a one-shot server on `127.0.0.1:<random>` that captures the
2174
- * `?code=...` redirect from a browser-driven OAuth flow and resolves a
2175
- * promise with the code. Used as the `redirectUrl` half of the MCP SDK's
2176
- * `OAuthClientProvider` (the persistence half lives separately).
2177
- *
2178
- * Design:
2179
- * - Loopback-only (`127.0.0.1`) — the OAuth spec treats `http://127.0.0.1:<port>`
2180
- * as a public-client redirect URI per RFC 8252 §7.3. Browsers do NOT block it,
2181
- * and Anthropic / OpenAI / Linear / GitHub all accept it.
2182
- * - Random port (`port = 0`) — the OS picks an unused one. We read the actual
2183
- * port back from `server.address()` after `listen()`.
2184
- * - Single-shot — the first GET to `path` with a `code` (or `error`) wins;
2185
- * subsequent requests get 404. The server keeps listening (in case the user
2186
- * hits "back" and re-authorizes), so callers must `close()` once they have
2187
- * the code or have given up.
2188
- * - Abort-aware — wiring an external `AbortSignal` rejects the promise and
2189
- * closes the server immediately. Required for the TUI's "esc cancels login"
2190
- * UX.
2191
- * - No HTML framework — a single inline `<html>` string keeps this isolated
2192
- * from any UI dependency.
2193
- */
2194
- /**
2195
- * Result of a successful callback. `state` is forwarded verbatim from the
2196
- * query string — callers verify it against their pre-flight value to defend
2197
- * against CSRF (the MCP SDK does this internally when it controls `state`).
2198
- */
2199
- interface OAuthCallbackResult {
2200
- code: string;
2201
- state?: string;
2202
- }
2203
- interface OAuthCallbackHandle {
2204
- /**
2205
- * Full URI to register with the authorization server, e.g.
2206
- * `http://127.0.0.1:51823/callback`. Stable for the lifetime of the
2207
- * handle.
2208
- */
2209
- redirectUri: string;
2210
- /**
2211
- * Resolves with `{ code, state }` on a successful callback. Rejects with:
2212
- * - The OAuth-spec `error` field (`access_denied`, `server_error`, ...)
2213
- * when the authorization server redirects with `?error=...`.
2214
- * - `'OAuth callback aborted'` when the external `AbortSignal` fires.
2215
- * - `'OAuth callback server closed'` when `close()` is called before any
2216
- * callback arrives.
2217
- *
2218
- * Single-shot — only the first matching request resolves the promise.
2219
- */
2220
- promise: Promise<OAuthCallbackResult>;
2221
- /**
2222
- * Idempotent shutdown. Safe to call from a `finally` block whether the
2223
- * flow succeeded, failed, or was aborted. Resolves once the server stops
2224
- * accepting connections.
2225
- */
2226
- close: () => Promise<void>;
2227
- }
2228
- interface OAuthCallbackOptions {
2229
- /** Cancels the flow — rejects `promise` and closes the server. */
2230
- signal?: AbortSignal;
2231
- /**
2232
- * Path component the authorization server should redirect to. Defaults
2233
- * to `/callback`. Useful when matching a pre-registered URI that uses a
2234
- * different path.
2235
- */
2236
- path?: string;
2237
- /**
2238
- * Override the loopback host. Defaults to `127.0.0.1`. Don't bind to
2239
- * `0.0.0.0` here — the OAuth code is a one-time secret and the server
2240
- * would otherwise accept it from any host on the LAN.
2241
- */
2242
- host?: string;
2243
- /**
2244
- * Override the port. Defaults to `0` (OS-assigned). Pin to a fixed port
2245
- * only when the authorization server requires a pre-registered redirect
2246
- * URI; the random-port path is preferred so concurrent flows don't clash.
2247
- */
2248
- port?: number;
2249
- }
2250
- /**
2251
- * Start a one-shot OAuth callback server. The returned handle's `redirectUri`
2252
- * should be passed to the authorization server as the `redirect_uri` query
2253
- * parameter; `promise` resolves once the user finishes the browser flow.
2254
- *
2255
- * Always `await handle.close()` in a `finally` block — even on success, the
2256
- * server stays open until told to shut down (so it can serve the
2257
- * "you can close this tab" page).
2258
- */
2259
- declare function startOAuthCallback(opts?: OAuthCallbackOptions): Promise<OAuthCallbackHandle>;
2260
- //#endregion
2261
- //#region src/metrics.d.ts
2262
- type MetricAttributes = Record<string, string | number | boolean | undefined>;
2263
- interface Counter {
2264
- add: (value: number, attributes?: MetricAttributes) => void;
2265
- }
2266
- interface Histogram {
2267
- record: (value: number, attributes?: MetricAttributes) => void;
2268
- }
2269
- interface UpDownCounter {
2270
- add: (value: number, attributes?: MetricAttributes) => void;
2271
- }
2272
- interface InstrumentOptions {
2273
- description?: string;
2274
- unit?: string;
2275
- }
2276
- /**
2277
- * Minimal Meter interface — structurally identical to OTel's `Meter`.
2278
- * Hosts passing `metrics.getMeter(name)` (from `@opentelemetry/api`)
2279
- * satisfy this without adaptation.
2280
- */
2281
- interface Meter {
2282
- createCounter: (name: string, options?: InstrumentOptions) => Counter;
2283
- createHistogram: (name: string, options?: InstrumentOptions) => Histogram;
2284
- createUpDownCounter: (name: string, options?: InstrumentOptions) => UpDownCounter;
2285
- }
2286
- interface MetricsHooksOptions {
2287
- meter: Meter;
2288
- /**
2289
- * Optional prefix prepended to every instrument name. Default: no prefix
2290
- * (instrument names follow OTel Gen AI semantic conventions verbatim,
2291
- * which is the most-portable shape). Set to e.g. `'zidane.'` to
2292
- * namespace inside a shared meter registry.
2293
- */
2294
- namespace?: string;
2295
- /**
2296
- * Optional baseline attributes applied to every measurement. Typical
2297
- * use: `{ service: 'tui', env: 'prod' }`. Per-event attributes win on
2298
- * key collision.
2299
- */
2300
- baseAttributes?: MetricAttributes;
2301
- /**
2302
- * Error sink for meter failures. The helper still swallows the throw
2303
- * so a broken backend can't crash a run; this callback surfaces the
2304
- * failure for ops dashboards.
2305
- */
2306
- onError?: (kind: string, err: unknown) => void;
2307
- }
2308
- interface MetricsHookSet {
2309
- install: (hooks: Hookable<AgentHooks>) => () => void;
2310
- }
2311
- /**
2312
- * Build a set of metrics hook handlers that can be installed on an agent.
2313
- *
2314
- * @example OpenTelemetry
2315
- * ```ts
2316
- * import { metrics } from '@opentelemetry/api'
2317
- * const meter = metrics.getMeter('zidane')
2318
- * const m = createMetricsHooks({ meter, baseAttributes: { service: 'tui' } })
2319
- * const uninstall = m.install(agent.hooks)
2320
- * try { await agent.run({ prompt }) }
2321
- * finally { uninstall() }
2322
- * ```
2323
- */
2324
- declare function createMetricsHooks(options: MetricsHooksOptions): MetricsHookSet;
2325
- //#endregion
2326
- //#region src/mutation-validation.d.ts
2327
- type MaybePromise<T> = T | Promise<T>;
2328
- type SuccessfulMutationOutcome = Extract<ToolOutcome, 'created' | 'updated' | 'edited'>;
2329
- interface MutationValidationMutation {
2330
- turnId: string;
2331
- callId: string;
2332
- tool: string;
2333
- displayName: string;
2334
- input: Record<string, unknown>;
2335
- outcome: SuccessfulMutationOutcome;
2336
- result: string | ToolResultContent[];
2337
- }
2338
- interface MutationValidationBatch {
2339
- turnId: string;
2340
- mutations: readonly MutationValidationMutation[];
2341
- }
2342
- type MutationValidationResult = {
2343
- ok: true;
2344
- } | {
2345
- ok: false;
2346
- message?: string;
2347
- errors?: readonly string[];
2348
- };
2349
- interface MutationValidationFailure {
2350
- batch: MutationValidationBatch;
2351
- result: Extract<MutationValidationResult, {
2352
- ok: false;
2353
- }>;
2354
- message: string;
2355
- failureCount: number;
2356
- }
2357
- interface MutationValidationHooksOptions {
2358
- validate: (batch: MutationValidationBatch) => MaybePromise<MutationValidationResult | void>;
2359
- /**
2360
- * Called when validation fails and the run has not crossed
2361
- * `maxFailuresPerRun`. Hosts typically call `agent.followUp(message)` here.
2362
- */
2363
- onFailure?: (failure: MutationValidationFailure) => MaybePromise<void>;
2364
- buildFailureMessage?: (failure: Omit<MutationValidationFailure, 'message'>) => string;
2365
- onError?: (error: unknown, batch: MutationValidationBatch) => MaybePromise<void>;
2366
- maxFailuresPerRun?: number;
2367
- }
2368
- /**
2369
- * Build host-side hooks for post-mutation validation without changing the
2370
- * built-in edit/write tools. The helper only observes successful mutations
2371
- * reported through `tool:after.outcome`; validation commands and recovery
2372
- * prompts remain host policy.
2373
- */
2374
- declare function createMutationValidationHooks(options: MutationValidationHooksOptions): AgentHookMap;
2375
- //#endregion
2376
- //#region src/stats.d.ts
2377
- /**
2378
- * Per-model usage rollup produced by {@link statsByModel}.
2379
- *
2380
- * `turns` counts the number of `TurnUsage` entries attributed to the model
2381
- * across the whole tree (parent loop + every recursively-spawned child).
2382
- * Cache and cost numbers are summed from the same set of turns.
2383
- */
2384
- interface ModelUsage {
2385
- input: number;
2386
- output: number;
2387
- cost: number;
2388
- cacheRead: number;
2389
- cacheCreation: number;
2390
- turns: number;
2391
- }
2392
- /**
2393
- * Depth-first walk over the stats tree, returning every `TurnUsage` entry
2394
- * — parent loop first, then each child subtree in completion order.
2395
- *
2396
- * Closes the cache-token aggregation gap: `TurnUsage.cacheRead` /
2397
- * `cacheCreation` live only on per-turn entries, and the top-level
2398
- * `AgentStats` deliberately doesn't carry cumulative forms (one source of
2399
- * truth, no risk of drift). Anything that needs a tree-wide sum walks
2400
- * through this.
2401
- */
2402
- declare function flattenTurns(stats: AgentStats): TurnUsage[];
2403
- /**
2404
- * Group cumulative usage by `TurnUsage.modelId`. Each entry sums the input,
2405
- * output, cache, cost, and turn-count across every turn the tree attributed
2406
- * to that model — naturally handling cross-model runs (vision-fallback,
2407
- * model-shifted subagents, mixed-provider workflows).
2408
- *
2409
- * Turns missing `modelId` (mock providers, providers that don't echo a model
2410
- * id) are bucketed under the literal string `'(unknown)'`.
2411
- */
2412
- declare function statsByModel(stats: AgentStats): Map<string, ModelUsage>;
2413
- //#endregion
2414
- //#region src/tracing.d.ts
2415
- /** Minimal span shape — any tracer that provides these methods is compatible. */
2416
- interface Span {
2417
- /** Close the span. Called exactly once per span. */
2418
- end: () => void;
2419
- /** Optional: attach additional attributes after the span is started (ignored if unsupported). */
2420
- setAttributes?: (attrs: Record<string, unknown>) => void;
2421
- /**
2422
- * Optional: record a structured event on the span. Used for non-span
2423
- * occurrences (gate blocks, validation rejects, budget hits, pairing
2424
- * repairs). Maps to OTel's `Span.addEvent` and Sentry's `addBreadcrumb`.
2425
- * Tracers without an event surface should treat this as a no-op (the
2426
- * helper falls back to `setAttributes` with an `event.*` key prefix).
2427
- */
2428
- addEvent?: (name: string, attrs?: Record<string, unknown>) => void;
2429
- }
2430
- /**
2431
- * Function that opens a span. Caller-provided so we stay tracer-agnostic.
2432
- *
2433
- * `parentContext` carries opaque trace metadata propagated from another
2434
- * agent (typically a W3C `{ traceparent, tracestate }` carrier received on
2435
- * `agent:start.tracingContext` after a parent agent's tracer injected it on
2436
- * `spawn:before`). Implementations that integrate with OTel should extract
2437
- * the carrier into a `Context` and use it as the parent when opening the
2438
- * span; implementations that don't care about cross-agent linkage can
2439
- * ignore the third argument entirely.
2440
- */
2441
- type StartSpan = (name: string, attrs?: Record<string, unknown>, parentContext?: Readonly<Record<string, string>>) => Span;
2442
- type TracingConventions = 'sentry' | 'otel' | 'both';
2443
- interface TracingHooksOptions {
2444
- /** Tracer seam. Receives a span name + attributes; must return a `Span`. */
2445
- startSpan: StartSpan;
2446
- /**
2447
- * Optional attribute namespace. Prepended to every span name with a `/`
2448
- * separator (e.g. `"agent"` → `agent/chat <model>`, `agent/execute_tool Bash`).
2449
- *
2450
- * Empty / undefined = no prefix.
2451
- */
2452
- namespace?: string;
2453
- /**
2454
- * Which Gen-AI attribute conventions to emit.
2455
- *
2456
- * - `'sentry'` (default) — Sentry AI Agents conventions. Most common
2457
- * choice — Sentry, Datadog AI, Honeycomb derived dashboards and
2458
- * Langfuse all consume these.
2459
- * - `'otel'` — vendor-neutral OpenTelemetry Gen AI semconv v1.36.
2460
- * Diverges from Sentry on cache-token keys, cost keys, and TTFT unit.
2461
- * - `'both'` — emit every variant. Doubles the per-span attribute
2462
- * payload; pick when shipping to multiple backends with different
2463
- * ingestion conventions.
2464
- */
2465
- conventions?: TracingConventions;
2466
- /**
2467
- * Capture the actual prompt / completion text on spans
2468
- * (`gen_ai.input.messages`, `gen_ai.output.messages`,
2469
- * `gen_ai.system_instructions`, `gen_ai.tool.definitions`,
2470
- * `gen_ai.tool.call.arguments`, `gen_ai.tool.call.result`).
2471
- *
2472
- * Defaults to `true` (required for the Sentry AI Agents conversation
2473
- * viewer). Full prompts and tool arguments can carry secrets and PII;
2474
- * captured content flows through `redact`, so pair the default with a
2475
- * redactor when payloads may hold secrets, or set `false` to keep all
2476
- * content-shaped data in-process.
2477
- */
2478
- captureMessageContent?: boolean;
2479
- /**
2480
- * Emit legacy attribute keys (`inputTokens`, `outputTokens`, `toolName`,
2481
- * `displayName`, `finishReason`, `modelId`) alongside the new
2482
- * `gen_ai.*` semconv keys. Defaults to `true` so existing dashboards
2483
- * keep working. Set `false` once you've migrated all consumers off the
2484
- * legacy names.
2485
- */
2486
- legacyAttributes?: boolean;
2487
- /**
2488
- * Error sink for tracer failures. Replaces the historic silent-swallow.
2489
- * Called when `Span.end()`, `setAttributes()`, `addEvent()`, or
2490
- * `startSpan()` throws — so degraded tracers stay visible. The helper
2491
- * still does not let tracer errors propagate into the agent loop.
2492
- *
2493
- * `kind` identifies which step failed (`'startSpan'`, `'end'`,
2494
- * `'setAttributes'`, `'addEvent'`, `'redact'`, `'getActiveTraceContext'`).
2495
- * Default: no-op (silent).
2496
- */
2497
- onError?: (kind: string, err: unknown) => void;
2498
- /**
2499
- * Optional callback the helper invokes on `spawn:before` (after opening
2500
- * the spawn span) to read the active trace context. Whatever it returns
2501
- * is written into `ctx.tracingContext` and forwarded to the child's
2502
- * `agent.run({ tracingContext })`. Typical use:
2503
- *
2504
- * ```ts
2505
- * getActiveTraceContext: () => {
2506
- * const carrier: Record<string, string> = {}
2507
- * propagation.inject(context.active(), carrier)
2508
- * return carrier
2509
- * }
2510
- * ```
2511
- *
2512
- * Returning `undefined` or an empty object leaves the carrier empty
2513
- * and the child runs with no parent context. The helper's own
2514
- * `propagator` is preferred over this when both are set (the
2515
- * propagator runs inside the helper; this callback is the escape
2516
- * hatch for hosts wanting full control).
2517
- */
2518
- getActiveTraceContext?: () => Readonly<Record<string, string>> | undefined;
2519
- /**
2520
- * Optional in-process span redactor. When set, every potentially
2521
- * sensitive string (tool input, tool result, system prompt) flows
2522
- * through this fn before landing on a span attribute / event. Returning
2523
- * the input unchanged is a no-op.
2524
- *
2525
- * Composes with the harness-wide `tracing:redact` hook: if a host has
2526
- * already registered a hook handler that mutates `ctx.redacted`, the
2527
- * tracer reuses that pipeline; setting `redact` here registers an extra
2528
- * step that runs only for the tracer's attributes. The hook is the
2529
- * canonical path; `redact` is the convenience surface for tracer-only
2530
- * setups.
2531
- */
2532
- redact?: (kind: string, value: string, meta?: Readonly<Record<string, unknown>>) => string;
2533
- }
2534
- /** Value returned by {@link createTracingHooks} — install entrypoint. */
2535
- interface TracingHookSet {
2536
- /**
2537
- * Attach every hook handler to the given agent hooks instance.
2538
- *
2539
- * @returns an `uninstall` function that detaches every handler and closes any
2540
- * still-open spans. Safe to call multiple times.
2541
- */
2542
- install: (hooks: Hookable<AgentHooks>) => () => void;
2543
- }
2544
- /**
2545
- * Build a set of tracing hook handlers that can be installed on an agent.
2546
- *
2547
- * @example Sentry
2548
- * ```ts
2549
- * const tracing = createTracingHooks({
2550
- * startSpan: (name, attrs) => Sentry.startInactiveSpan({ name, attributes: attrs }),
2551
- * })
2552
- * const uninstall = tracing.install(agent.hooks)
2553
- * try { await agent.run({ prompt }) }
2554
- * finally { uninstall() }
2555
- * ```
2556
- *
2557
- * @example OpenTelemetry with parent-context propagation
2558
- * ```ts
2559
- * import { trace, context, propagation } from '@opentelemetry/api'
2560
- *
2561
- * const tracer = trace.getTracer('zidane')
2562
- * const tracing = createTracingHooks({
2563
- * startSpan: (name, attrs, parentCtx) => {
2564
- * const ctx = parentCtx ? propagation.extract(context.active(), parentCtx) : context.active()
2565
- * return tracer.startSpan(name, { attributes: attrs }, ctx)
2566
- * },
2567
- * getActiveTraceContext: () => {
2568
- * const carrier: Record<string, string> = {}
2569
- * propagation.inject(context.active(), carrier)
2570
- * return carrier
2571
- * },
2572
- * })
2573
- * ```
2574
- */
2575
- declare function createTracingHooks(options: TracingHooksOptions): TracingHookSet;
2576
- /**
2577
- * OpenTelemetry Gen AI semantic-convention attribute keys used by the
2578
- * built-in tracer. Exported so consumers integrating with raw OTel SDKs
2579
- * (instead of going through `createTracingHooks`) can stay aligned with
2580
- * the names the harness itself emits.
2581
- */
2582
- declare const GEN_AI_ATTRIBUTES: {
2583
- readonly system: "gen_ai.system";
2584
- readonly operationName: "gen_ai.operation.name";
2585
- readonly requestModel: "gen_ai.request.model";
2586
- readonly responseModel: "gen_ai.response.model";
2587
- readonly responseFinishReasons: "gen_ai.response.finish_reasons";
2588
- readonly responseId: "gen_ai.response.id";
2589
- readonly responseStreaming: "gen_ai.response.streaming";
2590
- readonly responseTokensPerSecond: "gen_ai.response.tokens_per_second";
2591
- readonly responseTimeToFirstTokenSeconds: "gen_ai.response.time_to_first_token";
2592
- readonly responseTimeToFirstTokenMs: "gen_ai.client.time_to_first_token";
2593
- readonly usageInputTokens: "gen_ai.usage.input_tokens";
2594
- readonly usageOutputTokens: "gen_ai.usage.output_tokens";
2595
- readonly usageTotalTokens: "gen_ai.usage.total_tokens";
2596
- readonly usageInputTokensCached: "gen_ai.usage.input_tokens.cached";
2597
- readonly usageInputTokensCacheWrite: "gen_ai.usage.input_tokens.cache_write";
2598
- readonly usageOutputTokensReasoning: "gen_ai.usage.output_tokens.reasoning";
2599
- readonly usageCacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens";
2600
- readonly usageCacheCreationInputTokens: "gen_ai.usage.cache_creation_input_tokens";
2601
- readonly usageReasoningTokens: "gen_ai.usage.reasoning_tokens";
2602
- readonly costTotalTokens: "gen_ai.cost.total_tokens";
2603
- readonly costInputTokens: "gen_ai.cost.input_tokens";
2604
- readonly costOutputTokens: "gen_ai.cost.output_tokens";
2605
- readonly usageCostUsd: "gen_ai.usage.cost_usd";
2606
- readonly toolName: "gen_ai.tool.name";
2607
- readonly toolDescription: "gen_ai.tool.description";
2608
- readonly toolType: "gen_ai.tool.type";
2609
- readonly toolCallId: "gen_ai.tool.call.id";
2610
- readonly toolCallArguments: "gen_ai.tool.call.arguments";
2611
- readonly toolCallResult: "gen_ai.tool.call.result";
2612
- readonly toolMessage: "gen_ai.tool.message";
2613
- readonly toolInputDeprecated: "gen_ai.tool.input";
2614
- readonly toolOutputDeprecated: "gen_ai.tool.output";
2615
- readonly requestMaxTokens: "gen_ai.request.max_tokens";
2616
- readonly requestTemperature: "gen_ai.request.temperature";
2617
- readonly requestTopP: "gen_ai.request.top_p";
2618
- readonly requestTopK: "gen_ai.request.top_k";
2619
- readonly requestSeed: "gen_ai.request.seed";
2620
- readonly requestFrequencyPenalty: "gen_ai.request.frequency_penalty";
2621
- readonly requestPresencePenalty: "gen_ai.request.presence_penalty";
2622
- readonly inputMessages: "gen_ai.input.messages";
2623
- readonly outputMessages: "gen_ai.output.messages";
2624
- readonly systemInstructions: "gen_ai.system_instructions";
2625
- readonly toolDefinitions: "gen_ai.tool.definitions";
2626
- readonly agentName: "gen_ai.agent.name";
2627
- readonly agentRunId: "gen_ai.agent.run.id";
2628
- readonly agentParentRunId: "gen_ai.agent.parent_run.id";
2629
- readonly agentDepth: "gen_ai.agent.depth";
2630
- readonly pipelineName: "gen_ai.pipeline.name";
2631
- readonly turn: "gen_ai.agent.turn";
2632
- readonly mcpServer: "gen_ai.mcp.server";
2633
- readonly mcpToolCount: "gen_ai.mcp.tool_count";
2634
- };
2635
- //#endregion
2636
- //#region src/zod.d.ts
2637
- /**
2638
- * Zod v4 integration helper.
2639
- *
2640
- * Normalizes the output of z.toJsonSchema() for use as ToolSpec.inputSchema.
2641
- * Zod is an optional peer dependency — consumers call z.toJsonSchema() themselves.
2642
- *
2643
- * Usage:
2644
- * import { z } from 'zod'
2645
- * import { zodToJsonSchema } from 'zidane'
2646
- * const schema = zodToJsonSchema(z.toJsonSchema(z.object({ name: z.string() })))
2647
- */
2648
- /**
2649
- * Normalize a JSON Schema (e.g. from zod v4's z.toJsonSchema()) for use
2650
- * as a ToolSpec.inputSchema.
2651
- *
2652
- * Strips the $schema key that some providers reject.
2653
- */
2654
- declare function zodToJsonSchema(jsonSchema: Record<string, unknown>): Record<string, unknown>;
2655
- //#endregion
2656
- //#region src/presets/basic.d.ts
2657
- /**
2658
- * Core tools available in every basic preset (without spawn).
2659
- *
2660
- * `edit` and `multi_edit` ship in the basic set because surgical edits are the
2661
- * default modality for production agents — `write_file` is for full overwrites.
2662
- * `glob` and `grep` are exported but opt-in: not every agent needs codebase
2663
- * search, and shipping them by default would force `tool:gate` work onto
2664
- * consumers that prefer the model to use `shell` + classic Unix tools.
2665
- */
2666
- declare const basicTools: {
2667
- shell: ToolDef;
2668
- shellKill: ToolDef;
2669
- waitTask: ToolDef;
2670
- readFile: ToolDef;
2671
- writeFile: ToolDef;
2672
- listFiles: ToolDef;
2673
- edit: ToolDef;
2674
- multiEdit: ToolDef;
2675
- };
2676
- declare const _default: Preset;
2677
- //#endregion
2678
- //#region src/presets/index.d.ts
2679
- /**
2680
- * A preset is a reusable slice of `AgentOptions` — spread it into `createAgent()`
2681
- * to configure tools, a default system prompt, aliases, behavior defaults, and
2682
- * agent-lifetime hooks.
2683
- *
2684
- * `provider`, `execution`, `session`, and `mcpConnector` are excluded — they're
2685
- * ambient / per-invocation runtime wiring (a custom `mcpConnector` is the MCP
2686
- * connection seam, often closure-bound to a transport / auth provider), so
2687
- * presets stay shareable and composable.
2688
- *
2689
- * ```ts
2690
- * import { basic } from 'zidane/presets'
2691
- * createAgent({ ...basic, provider })
2692
- * ```
2693
- *
2694
- * ### Composing multiple presets
2695
- *
2696
- * Bare `...spread` is shallow — `{ ...a, ...b }` overwrites every key `b`
2697
- * defines, including `hooks`. Use {@link composePresets} when you want
2698
- * field-aware merging (per-event hook concat, tools shallow-merge, etc.):
2699
- *
2700
- * ```ts
2701
- * createAgent({ ...composePresets(basic, telemetry, mine), provider })
2702
- * ```
2703
- */
2704
- type Preset = Omit<Partial<AgentOptions>, 'provider' | 'execution' | 'session' | 'mcpConnector'>;
2705
- /**
2706
- * Identity helper for type inference when defining a preset.
2707
- */
2708
- declare function definePreset(config: Preset): Preset;
2709
- /**
2710
- * Field-aware composition of presets. Right-most preset wins for scalar fields;
2711
- * objects shallow-merge; arrays and hook handler lists concatenate. Designed so
2712
- * stacking presets does the obvious thing without the spread-collision footgun:
2713
- *
2714
- * - `name`, `system`, `eager`, `skills` → last-defined wins
2715
- * - `tools`, `toolAliases`, `behavior` → shallow-merge (later keys override)
2716
- * - `behavior.dedupTools`, `behavior.toolBudgets` → **deep-merge** (per-tool-name; later wins on collision)
2717
- * - `mcpServers` → concat with last-wins on `name` collision
2718
- * - `hooks` → per-event concat; every handler fires
2719
- *
2720
- * `hooks` always emerges as `event → handler[]` so downstream registration
2721
- * (in `createAgent`) sees a uniform shape. Order of handlers within an event
2722
- * follows preset order: earlier presets register first.
2723
- *
2724
- * `mcpServers` is deduped by `name` because shipping two servers with the same
2725
- * name would trip the connector at runtime — a later preset overriding an
2726
- * earlier preset's `github` server is the practical intent.
2727
- *
2728
- * `behavior.dedupTools` and `behavior.toolBudgets` get the same per-key deep-merge
2729
- * because they are tool-name-keyed records — a preset that ships a dedup hasher
2730
- * for one tool should not erase a hasher another preset ships for a different
2731
- * tool. Last-wins still applies on a per-tool collision so a downstream preset
2732
- * can override an upstream preset's policy for one specific tool. Other
2733
- * `behavior` fields keep last-wins semantics.
2734
- */
2735
- declare function composePresets(...presets: Preset[]): Preset;
2736
- //#endregion
2737
- export { resolvePersistDir as $, SpawnToolState as $n, anchorPreviewFor as $r, createReusableExecutionContext as $t, MetricsHooksOptions as A, ProviderTranscriptFormat as An, selectRecentFiles as Ar, EvalVariantSummary as At, McpCredentialEntry as B, transcriptToProviderMessages as Bn, CompactPromptBuilder as Br, RegisterEvalTestsOptions as Bt, createMutationValidationHooks as C, HeadlessOptions as Cn, utf8ByteLength as Cr, EvalRunSummary as Ct, Meter as D, HeadlessUsage as Dn, buildPostCompactAttachments as Dr, EvalScorer as Dt, InstrumentOptions as E, HeadlessStatus as En, RecentFile as Er, EvalScore as Et, OAuthCallbackResult as F, headlessEventToJsonl as Fn, compactConversation as Fr, MetricDirection as Ft, hasAuthorizationHeader as G, validateToolArgs as Gn, buildFromCompactPrompt as Gr, artifactPath as Gt, McpOAuthProvider as H, WAIT_TASK_TIMED_OUT_PREFIX as Hn, NO_TOOLS_PREAMBLE as Hr, Trajectory as Ht, startOAuthCallback as I, installHeadlessEventAdapter as In, CompactInvalidInputError as Ir, MetricEmitter as It, PersistInput as J, LazyToolEntry as Jn, buildUpToCompactPrompt as Jr, buildTrajectory as Jt, PERSISTED_STUB_PREFIX as K, TailTruncateOptions as Kn, buildFullCompactPrompt as Kr, buildEvalRunSummary as Kt, LoginMcpServerOptions as L, providerTranscriptFormatForProvider as Ln, CompactPromptTooLongError as Lr, MetricSpec as Lt, createMetricsHooks as M, formatHeadlessResult as Mn, CompactOptions as Mr, EvalWorkspaceOptions as Mt, OAuthCallbackHandle as N, formatHeadlessTurnEvent as Nn, CompactResult as Nr, EvalWorkspaceSnapshot as Nt, MetricAttributes as O, OpenAIChatContentPart as On, selectFilesFromReadState as Or, EvalScorerContext as Ot, OAuthCallbackOptions as P, formattedHeadlessTurnEventToJsonl as Pn, CompactStartEvent as Pr, LlmJudgeOptions as Pt, maybePersistToolResult as Q, SpawnToolOptions as Qn, SummaryToTurnInput as Qr, createEvalRunReporter as Qt, LoginMcpServerResult as R, runHeadless as Rn, BASE_INSTRUCTIONS as Rr, MetricSpecMap as Rt, SuccessfulMutationOutcome as S, HeadlessEvent as Sn, estimateTokens as Sr, EvalRunReporterOptions as St, Histogram as T, HeadlessResult as Tn, PostCompactRestoreOptions as Tr, EvalRunUsage as Tt, McpOAuthProviderOptions as U, waitTask as Un, TRAILER as Ur, TrajectoryStep as Ut, McpCredentialStore as V, writeFile as Vn, CompactPromptOptions as Vr, ReusableExecutionContext as Vt, createMemoryMcpCredentialStore as W, ValidationResult as Wn, buildCompactPrompt as Wr, TrajectoryStepKind as Wt, buildPersistedStub as X, createToolSearchTool as Xn, CompactScope as Xr, computeEvalTagScores as Xt, PersistOutcome as Y, ToolSearchToolOptions as Yn, ANCHOR_PREVIEW_MAX_CHARS as Yr, clearRegisteredEvals as Yt, cleanupPersistedSession as Z, ChildAgent as Zn, CompactionSlice as Zr, createEvalAgent as Zt, MutationValidationBatch as _, runEvalCase as _n, createInteractionTool as _r, EvalDefinitionContext as _t, basicTools as a, defaultRepeatGuardTracked as ai, fileContentQuality as an, SkillsRunScriptToolOptions as ar, CreateEvalAgentOptions as at, MutationValidationMutation as b, FormattedHeadlessTurnEvent as bn, edit as br, EvalRunMetricAggregate as bt, Span as c, localReliabilityBehavior as ci, finalizeEvalMetrics as cn, createSkillsReadTool as cr, EvalAgentMcpServers as ct, TracingHookSet as d, formatTrajectoryLine as dn, createShellTool as dr, EvalAgentRunStats as dt, sliceForCompaction as ei, defineEval as en, SubagentDef as er, resolveTasksDir as et, TracingHooksOptions as f, functionalityMetric as fn, shell as fr, EvalAgentStats as ft, statsByModel as g, relativeArtifactPath as gn, InteractionToolOptions as gr, EvalDefinition as gt, flattenTurns as h, registerEvalTests as hn, listFiles as hr, EvalCaseResult as ht, _default as i, defaultRepeatGuardNormalize as ii, fileContains as in, createSkillsUseTool as ir, TOOL_USE_SKIPPED_MESSAGE as it, UpDownCounter as j, exitCodeForHeadlessResult as jn, CompactEndEvent as jr, EvalWorkspaceFile as jt, MetricsHookSet as k, OpenAIChatMessage as kn, selectFilesFromSession as kr, EvalTestRunner as kt, StartSpan as l, formatEvalCaseSummary as ln, shellKill as lr, EvalAgentRunOptions as lt, ModelUsage as m, normalizeMetric as mn, multiEdit as mr, EvalCaseOptions as mt, composePresets as n, summaryToTurn as ni, efficiencyMetricValues as nn, createSpawnTool as nr, SHELL_CASCADE_CANCEL_MESSAGE as nt, zodToJsonSchema as o, normalizeShellCommand as oi, fileExists as on, createSkillsRunScriptTool as or, EFFICIENCY_METRICS as ot, createTracingHooks as p, llmJudge as pn, readFile as pr, EvalArtifacts as pt, PERSISTENCE_PREVIEW_BYTES as q, tailTruncate as qn, buildTailCompactPrompt as qr, buildRegisteredEvals as qt, definePreset as r, truncateHeadForPtlRetry as ri, emitEfficiencyMetrics as rn, SkillsUseToolOptions as rr, TOOL_USE_CANCELLED_MESSAGE as rt, GEN_AI_ATTRIBUTES as s, stableStringify as si, fileExistsOneOf as sn, SkillsReadToolOptions as sr, EvalAgent as st, Preset as t, stripImagesFromTurns as ti, defineMetrics as tn, SubagentRegistry as tr, INTERRUPT_MESSAGE_FOR_TOOL_USE as tt, TracingConventions as u, formatEvalRunSummary as un, CreateShellToolOptions as ur, EvalAgentRunResult as ut, MutationValidationFailure as v, statusCompleted as vn, grep as vr, EvalMetric as vt, Counter as w, HeadlessOutputFormat as wn, PostCompactAttachments as wr, EvalRunSummaryCase as wt, MutationValidationResult as x, HeadlessErrorInfo as xn, BYTES_PER_TOKEN as xr, EvalRunReporter as xt, MutationValidationHooksOptions as y, FormattedHeadlessResult as yn, glob as yr, EvalMetricError as yt, loginMcpServer as z, transcriptToOpenAIMessages as zn, CompactDirection as zr, MetricStats as zt };
2738
- //# sourceMappingURL=index-BtzE3Uaq.d.ts.map