zidane 6.0.1 → 6.1.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 (165) hide show
  1. package/README.md +27 -0
  2. package/dist/{acp-Irby04Us.js → acp-cfR8T19u.js} +8 -8
  3. package/dist/{acp-Irby04Us.js.map → acp-cfR8T19u.js.map} +1 -1
  4. package/dist/acp-cli.js +7 -7
  5. package/dist/acp-cli.js.map +1 -1
  6. package/dist/acp.d.ts +1 -1
  7. package/dist/acp.js +1 -1
  8. package/dist/{agent-DkSmGkDM.js → agent-DZRA7wip.js} +377 -61
  9. package/dist/agent-DZRA7wip.js.map +1 -0
  10. package/dist/agent.d.ts +1 -1
  11. package/dist/agent.js +1 -1
  12. package/dist/{anthropic-CTHsdFG9.js → anthropic-DNJbRMUK.js} +7 -7
  13. package/dist/anthropic-DNJbRMUK.js.map +1 -0
  14. package/dist/atomic-write-B7zr1ddF.js.map +1 -1
  15. package/dist/{auth-BDSu_0t3.js → auth-B3cB5K6d.js} +7 -7
  16. package/dist/auth-B3cB5K6d.js.map +1 -0
  17. package/dist/cache-telemetry-BKAwsNxm.js.map +1 -1
  18. package/dist/chat/pure.d.ts +4 -4
  19. package/dist/chat/pure.js +3 -3
  20. package/dist/chat.d.ts +44 -21
  21. package/dist/chat.d.ts.map +1 -1
  22. package/dist/chat.js +7 -7
  23. package/dist/chat.js.map +1 -1
  24. package/dist/completion-core-CXYSVhZo.js.map +1 -1
  25. package/dist/context-breakdown-Dzo25N45.js.map +1 -1
  26. package/dist/contexts/daytona.d.ts +3 -1
  27. package/dist/contexts/daytona.d.ts.map +1 -1
  28. package/dist/contexts/daytona.js +2 -2
  29. package/dist/contexts/daytona.js.map +1 -1
  30. package/dist/contexts/docker.d.ts.map +1 -1
  31. package/dist/contexts/docker.js +2 -2
  32. package/dist/contexts/docker.js.map +1 -1
  33. package/dist/contexts/e2b.d.ts +3 -1
  34. package/dist/contexts/e2b.d.ts.map +1 -1
  35. package/dist/contexts/e2b.js +1 -1
  36. package/dist/contexts/e2b.js.map +1 -1
  37. package/dist/{contexts-Vone3qQQ.js → contexts-BIbcfBFH.js} +2 -2
  38. package/dist/contexts-BIbcfBFH.js.map +1 -0
  39. package/dist/contexts.js +1 -1
  40. package/dist/edit-utils-EGosADZq.js.map +1 -1
  41. package/dist/eval.d.ts +1 -1
  42. package/dist/eval.js +4 -3
  43. package/dist/eval.js.map +1 -1
  44. package/dist/exec-file-size-PXkr-MGA.js.map +1 -1
  45. package/dist/extensions.d.ts +1 -1
  46. package/dist/extensions.js +1 -1
  47. package/dist/{fetch-url-CWE8X5OD.js → fetch-url-_5WKWpbQ.js} +2 -2
  48. package/dist/{fetch-url-CWE8X5OD.js.map → fetch-url-_5WKWpbQ.js.map} +1 -1
  49. package/dist/{format-BNOXpl-1.js → format-BF745pLL.js} +9 -2
  50. package/dist/format-BF745pLL.js.map +1 -0
  51. package/dist/generate-data-WL_yGVL6.js.map +1 -1
  52. package/dist/hash-DJRzmcPI.js.map +1 -1
  53. package/dist/headless.d.ts +1 -1
  54. package/dist/headless.js +4 -4
  55. package/dist/headless.js.map +1 -1
  56. package/dist/{index-B8UtiZy7.d.ts → index-BGpM2YaU.d.ts} +378 -5
  57. package/dist/index-BGpM2YaU.d.ts.map +1 -0
  58. package/dist/index.d.ts +2 -2
  59. package/dist/index.js +11 -11
  60. package/dist/index.js.map +1 -1
  61. package/dist/logger-DBX9uYOw.js.map +1 -1
  62. package/dist/{login-DOF8pMVM.js → login-DZLG__2f.js} +4 -3
  63. package/dist/{login-DOF8pMVM.js.map → login-DZLG__2f.js.map} +1 -1
  64. package/dist/mcp-CcvuVXB9.js.map +1 -1
  65. package/dist/mcp.d.ts +1 -1
  66. package/dist/media-sniff-Bn76JxAu.js.map +1 -1
  67. package/dist/{messages-CwujiS74.js → messages-C5BDOjUG.js} +2 -2
  68. package/dist/{messages-CwujiS74.js.map → messages-C5BDOjUG.js.map} +1 -1
  69. package/dist/oauth-8LqbeI_Q.js.map +1 -1
  70. package/dist/{openai-compat-BvgYGSR1.js → openai-compat-B0kqvZqN.js} +2 -2
  71. package/dist/openai-compat-B0kqvZqN.js.map +1 -0
  72. package/dist/output/stream-json.d.ts +1 -1
  73. package/dist/output/terminal.d.ts +1 -1
  74. package/dist/output/terminal.js +1 -1
  75. package/dist/output/terminal.js.map +1 -1
  76. package/dist/output-cap-kBUHBlnq.js.map +1 -1
  77. package/dist/presets.d.ts +1 -1
  78. package/dist/presets.js +1 -1
  79. package/dist/providers/anthropic.d.ts +1 -1
  80. package/dist/providers/anthropic.js +1 -1
  81. package/dist/providers/arcee.d.ts +1 -1
  82. package/dist/providers/arcee.js +1 -1
  83. package/dist/providers/baseten.d.ts +1 -1
  84. package/dist/providers/baseten.js +2 -2
  85. package/dist/providers/baseten.js.map +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 +8 -8
  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-z6LDMAr3.js → providers-BMlrTr6a.js} +3 -3
  100. package/dist/{providers-z6LDMAr3.js.map → providers-BMlrTr6a.js.map} +1 -1
  101. package/dist/providers.d.ts +1 -1
  102. package/dist/providers.js +4 -4
  103. package/dist/read-state-Dq_TXUX1.js.map +1 -1
  104. package/dist/{resolve-Cr8JSL_O.js → resolve-CC8Lmwcj.js} +3 -3
  105. package/dist/{resolve-Cr8JSL_O.js.map → resolve-CC8Lmwcj.js.map} +1 -1
  106. package/dist/restate.d.ts +1 -1
  107. package/dist/restate.d.ts.map +1 -1
  108. package/dist/restate.js.map +1 -1
  109. package/dist/session/sqlite.d.ts +1 -1
  110. package/dist/session/sqlite.d.ts.map +1 -1
  111. package/dist/session/sqlite.js +75 -20
  112. package/dist/session/sqlite.js.map +1 -1
  113. package/dist/{session-CsdDIPY8.js → session-CsKzK8-P.js} +3 -3
  114. package/dist/session-CsKzK8-P.js.map +1 -0
  115. package/dist/session.d.ts +2 -2
  116. package/dist/session.js +2 -2
  117. package/dist/{skills-Bsb0rvWI.js → skills-BjeXSRlQ.js} +2 -2
  118. package/dist/{skills-Bsb0rvWI.js.map → skills-BjeXSRlQ.js.map} +1 -1
  119. package/dist/skills.d.ts +1 -1
  120. package/dist/skills.js +2 -2
  121. package/dist/stdio-loader-Ce68wUmM.js.map +1 -1
  122. package/dist/{tool-formatters-DY0TDb1r.d.ts → tool-formatters-CMwjDvkp.d.ts} +2 -2
  123. package/dist/tool-formatters-CMwjDvkp.d.ts.map +1 -0
  124. package/dist/tools/fetch-url.d.ts +1 -1
  125. package/dist/tools/fetch-url.d.ts.map +1 -1
  126. package/dist/tools/fetch-url.js +1 -1
  127. package/dist/tools/web-search.d.ts +1 -1
  128. package/dist/tools/web-search.js +1 -1
  129. package/dist/tools/web-search.js.map +1 -1
  130. package/dist/tools.d.ts +2 -2
  131. package/dist/tools.js +2 -2
  132. package/dist/{transcript-anchors-DSRPWjiH.js → transcript-anchors-BTNe1OJi.js} +346 -89
  133. package/dist/transcript-anchors-BTNe1OJi.js.map +1 -0
  134. package/dist/{transcript-anchors-Cb-bDbNH.d.ts → transcript-anchors-D5wvdKQQ.d.ts} +37 -3
  135. package/dist/transcript-anchors-D5wvdKQQ.d.ts.map +1 -0
  136. package/dist/tui.d.ts +21 -6
  137. package/dist/tui.d.ts.map +1 -1
  138. package/dist/tui.js +497 -83
  139. package/dist/tui.js.map +1 -1
  140. package/dist/{turn-operations-Dq9Kx7m2.js → turn-operations-CEt_l3fy.js} +23 -8
  141. package/dist/turn-operations-CEt_l3fy.js.map +1 -0
  142. package/dist/{turn-operations-CgMROLsr.d.ts → turn-operations-JO5MYM9_.d.ts} +27 -9
  143. package/dist/turn-operations-JO5MYM9_.d.ts.map +1 -0
  144. package/dist/types-BIarq1qE.js.map +1 -1
  145. package/dist/types.d.ts +1 -1
  146. package/dist/{xai-B_e6TOA8.js → xai-C_aq671K.js} +3 -3
  147. package/dist/{xai-B_e6TOA8.js.map → xai-C_aq671K.js.map} +1 -1
  148. package/docs/ARCHITECTURE.md +4 -0
  149. package/docs/CHAT.md +12 -10
  150. package/docs/SKILL.md +1 -1
  151. package/docs/TUI.md +3 -3
  152. package/package.json +2 -2
  153. package/dist/agent-DkSmGkDM.js.map +0 -1
  154. package/dist/anthropic-CTHsdFG9.js.map +0 -1
  155. package/dist/auth-BDSu_0t3.js.map +0 -1
  156. package/dist/contexts-Vone3qQQ.js.map +0 -1
  157. package/dist/format-BNOXpl-1.js.map +0 -1
  158. package/dist/index-B8UtiZy7.d.ts.map +0 -1
  159. package/dist/openai-compat-BvgYGSR1.js.map +0 -1
  160. package/dist/session-CsdDIPY8.js.map +0 -1
  161. package/dist/tool-formatters-DY0TDb1r.d.ts.map +0 -1
  162. package/dist/transcript-anchors-Cb-bDbNH.d.ts.map +0 -1
  163. package/dist/transcript-anchors-DSRPWjiH.js.map +0 -1
  164. package/dist/turn-operations-CgMROLsr.d.ts.map +0 -1
  165. package/dist/turn-operations-Dq9Kx7m2.js.map +0 -1
@@ -3,20 +3,20 @@ import { a as isWireTurn, c as toolOutputByteLength, i as documentBlockMarker, l
3
3
  import { i as styleReplacementForVia, n as resolveOldString, r as stripLineNumberPrefixes, t as describeVia } from "./edit-utils-EGosADZq.js";
4
4
  import { n as estimateTokens, r as utf8ByteLength } from "./utils-ngQzYzZD.js";
5
5
  import { t as buildContextBreakdown } from "./context-breakdown-Dzo25N45.js";
6
- import { a as formatTaskStatus, i as formatDuration, o as formatTaskSummary, s as previewLine } from "./format-BNOXpl-1.js";
6
+ import { a as formatDuration, c as previewLine, o as formatTaskStatus, s as formatTaskSummary } from "./format-BF745pLL.js";
7
7
  import { c as parseGitLsFiles, r as isOutputExceededMessage, s as GIT_LS_FILES_COMMAND } from "./output-cap-kBUHBlnq.js";
8
8
  import { n as alwaysQuote, r as shellQuote } from "./exec-file-size-PXkr-MGA.js";
9
- import { n as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-Vone3qQQ.js";
9
+ import { n as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-BIbcfBFH.js";
10
10
  import { i as AgentProviderError, l as errorMessage, m as toTypedError, n as AgentBudgetExceededError, o as AgentToolPairingError, t as AgentAbortedError, u as isAbortLikeError } from "./errors-DJUxZg9b.js";
11
- import { C as stripShellInterpolations, O as validateResourcePathReal, S as interpolateShellCommands, _ as lastLine, b as resolveSubdirRoot, d as installAllowedToolsGate, f as createSkillActivationState, g as fetchInstallSource, h as defaultWhich, j as projectUserPaths, l as buildCatalog, m as defaultExec, p as InstallSourceError, t as resolveSkills, v as parseInstallSource, x as escapeXml, y as resolveNpmVersion } from "./resolve-Cr8JSL_O.js";
11
+ import { C as stripShellInterpolations, O as validateResourcePathReal, S as interpolateShellCommands, _ as lastLine, b as resolveSubdirRoot, d as installAllowedToolsGate, f as createSkillActivationState, g as fetchInstallSource, h as defaultWhich, j as projectUserPaths, l as buildCatalog, m as defaultExec, p as InstallSourceError, t as resolveSkills, v as parseInstallSource, x as escapeXml, y as resolveNpmVersion } from "./resolve-CC8Lmwcj.js";
12
12
  import { n as writeFileAtomicAsync, t as writeFileAtomic } from "./atomic-write-B7zr1ddF.js";
13
13
  import { r as createLogger, t as consoleSink } from "./logger-DBX9uYOw.js";
14
14
  import { n as reconcileImageMediaType } from "./media-sniff-Bn76JxAu.js";
15
15
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
16
- import { S as canonicalizePrompt, x as buildPromptMessage } from "./openai-compat-BvgYGSR1.js";
16
+ import { S as canonicalizePrompt, x as buildPromptMessage } from "./openai-compat-B0kqvZqN.js";
17
17
  import { appendStaticSection, renderSystemForWire } from "./prompt.js";
18
- import { a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, f as resolveContentRefsInMessages, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, s as ensureToolResultPairing } from "./messages-CwujiS74.js";
19
- import { a as getExtensionSessionState, c as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as setExtensionSessionState } from "./session-CsdDIPY8.js";
18
+ import { a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, f as resolveContentRefsInMessages, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, s as ensureToolResultPairing } from "./messages-C5BDOjUG.js";
19
+ import { a as getExtensionSessionState, c as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as setExtensionSessionState } from "./session-CsKzK8-P.js";
20
20
  import { a as withInactivityTimeout, i as settleWithinTimeout, n as linkAbortSignal, o as withTimeout$1, r as resolveTimeoutMs, t as OperationTimeoutError } from "./timeout-BDetbuN6.js";
21
21
  import { n as connectMcpServers, s as wrapDiscoveredMcpTools } from "./mcp-CcvuVXB9.js";
22
22
  import { createRequire } from "node:module";
@@ -196,7 +196,8 @@ function matchPathPattern(path, cwd, patterns) {
196
196
  if (pattern.endsWith("*") && !pattern.startsWith("*")) {
197
197
  const prefix = pattern.slice(0, -1);
198
198
  const separator = prefix.endsWith("/") || prefix.endsWith("\\") ? "/" : "";
199
- return matchOnePath(canonical, `${canonicalizePath(cwd, prefix)}${separator}*`);
199
+ const canonicalPattern = `${canonicalizePath(cwd, prefix)}${separator}*`;
200
+ return matchOnePath(canonical, canonicalPattern);
200
201
  }
201
202
  return false;
202
203
  });
@@ -214,7 +215,7 @@ const DEFAULT_NOOP_MUTATIONS = 3;
214
215
  const DEFAULT_VALIDATION_REJECTS = 3;
215
216
  const DEFAULT_TOOL_ERRORS = 3;
216
217
  const DEFAULT_MAX_NUDGES$1 = 3;
217
- const DEFAULT_READ_ONLY_TOOLS = new Set([
218
+ const DEFAULT_READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
218
219
  "read_file",
219
220
  "grep",
220
221
  "glob",
@@ -254,7 +255,7 @@ function installProgressNudges(hooks, config, deps) {
254
255
  const noopMutations = threshold(resolvedConfig.noopMutations, DEFAULT_NOOP_MUTATIONS);
255
256
  const validationRejects = threshold(resolvedConfig.validationRejects, DEFAULT_VALIDATION_REJECTS);
256
257
  const toolErrors = threshold(resolvedConfig.toolErrors, DEFAULT_TOOL_ERRORS);
257
- const readOnlyTools = new Set([...resolvedConfig.readOnlyTools ?? DEFAULT_READ_ONLY_TOOLS]);
258
+ const readOnlyTools = /* @__PURE__ */ new Set([...resolvedConfig.readOnlyTools ?? DEFAULT_READ_ONLY_TOOLS]);
258
259
  let nudgeCount = 0;
259
260
  const fired = /* @__PURE__ */ new Set();
260
261
  let consecutiveReadOnlyTurns = 0;
@@ -1185,7 +1186,7 @@ const ENTRY_CANDIDATES = [
1185
1186
  "index.mjs",
1186
1187
  "index.js"
1187
1188
  ];
1188
- const DANGEROUS_RECORD_KEYS$1 = new Set([
1189
+ const DANGEROUS_RECORD_KEYS$1 = /* @__PURE__ */ new Set([
1189
1190
  "__proto__",
1190
1191
  "prototype",
1191
1192
  "constructor"
@@ -2286,7 +2287,7 @@ async function suggestionFor(execution, handle, path) {
2286
2287
  }
2287
2288
  //#endregion
2288
2289
  //#region src/tools/validation.ts
2289
- const TRUE_STRINGS = new Set([
2290
+ const TRUE_STRINGS = /* @__PURE__ */ new Set([
2290
2291
  "true",
2291
2292
  "True",
2292
2293
  "TRUE",
@@ -2295,7 +2296,7 @@ const TRUE_STRINGS = new Set([
2295
2296
  "Yes",
2296
2297
  "YES"
2297
2298
  ]);
2298
- const FALSE_STRINGS = new Set([
2299
+ const FALSE_STRINGS = /* @__PURE__ */ new Set([
2299
2300
  "false",
2300
2301
  "False",
2301
2302
  "FALSE",
@@ -2695,10 +2696,19 @@ const edit = {
2695
2696
  ctx.reportOutcome?.("failed");
2696
2697
  return `Edit error: ${pathErr}`;
2697
2698
  }
2698
- if (find === replacement) return `Edit error: old_string and new_string are identical — nothing to change in ${target}.`;
2699
- if (find.length === 0) return `Edit error: old_string is empty. Use write_file to create or fully overwrite a file.`;
2699
+ if (find === replacement) {
2700
+ ctx.reportOutcome?.("failed");
2701
+ return `Edit error: old_string and new_string are identical — nothing to change in ${target}.`;
2702
+ }
2703
+ if (find.length === 0) {
2704
+ ctx.reportOutcome?.("failed");
2705
+ return `Edit error: old_string is empty. Use write_file to create or fully overwrite a file.`;
2706
+ }
2700
2707
  const refusal = await wholeReadRefusal(ctx.execution, ctx.handle, target, "edit");
2701
- if (refusal) return refusal;
2708
+ if (refusal) {
2709
+ ctx.reportOutcome?.("failed");
2710
+ return refusal;
2711
+ }
2702
2712
  let original;
2703
2713
  try {
2704
2714
  original = await ctx.execution.readFile(ctx.handle, target);
@@ -2717,8 +2727,14 @@ const edit = {
2717
2727
  if (readState) {
2718
2728
  const absKey = readStateKey(ctx.handle.cwd, target);
2719
2729
  const prior = readState.get(absKey);
2720
- if (!prior) return `Edit error: ${target} has not been read in this session. Call read_file first so the edit applies against the current contents.`;
2721
- if (prior.contentHash !== hashContent(original)) return `Edit error: ${target} has changed on disk since the last read. Re-read the file before editing.`;
2730
+ if (!prior) {
2731
+ ctx.reportOutcome?.("failed");
2732
+ return `Edit error: ${target} has not been read in this session. Call read_file first so the edit applies against the current contents.`;
2733
+ }
2734
+ if (prior.contentHash !== hashContent(original)) {
2735
+ ctx.reportOutcome?.("failed");
2736
+ return `Edit error: ${target} has changed on disk since the last read. Re-read the file before editing.`;
2737
+ }
2722
2738
  }
2723
2739
  }
2724
2740
  const match = resolveOldString(original, find);
@@ -2728,7 +2744,10 @@ const edit = {
2728
2744
  return preview ? `Edit error: old_string not found in ${target}. Closest match in the file: ${preview}` : `Edit error: old_string not found in ${target}.`;
2729
2745
  }
2730
2746
  const { actual, occurrences, via } = match;
2731
- if (occurrences > 1 && !replaceAll) return `Edit error: old_string appears ${occurrences} times in ${target}. Pass replace_all=true or expand old_string for uniqueness.`;
2747
+ if (occurrences > 1 && !replaceAll) {
2748
+ ctx.reportOutcome?.("failed");
2749
+ return `Edit error: old_string appears ${occurrences} times in ${target}. Pass replace_all=true or expand old_string for uniqueness.`;
2750
+ }
2732
2751
  const styledReplacement = styleReplacementForVia(replacement, via, actual);
2733
2752
  const updated = replaceAll ? original.split(actual).join(styledReplacement) : original.replace(actual, styledReplacement);
2734
2753
  if (updated === original) {
@@ -3274,7 +3293,7 @@ const listFiles = {
3274
3293
  isConcurrencySafe: true,
3275
3294
  spec: {
3276
3295
  name: "list_files",
3277
- description: "List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list, or `(empty directory)` when the directory exists but is empty. Returns `Directory not found: <path>` for a missing path. Non-recursive: use `glob` for pattern matching across nested directories.",
3296
+ description: "List the immediate entries (files and subdirectories) at literal directory `path`. Returns a newline-separated list — subdirectories carry a trailing `/` — or `(empty directory)` when the directory exists but is empty. Non-recursive: use `glob` for pattern matching across nested directories.",
3278
3297
  inputSchema: {
3279
3298
  type: "object",
3280
3299
  properties: { path: {
@@ -3285,14 +3304,84 @@ const listFiles = {
3285
3304
  }
3286
3305
  },
3287
3306
  async execute({ path }, ctx) {
3307
+ const target = path || ".";
3288
3308
  try {
3289
- return (await ctx.execution.listFiles(ctx.handle, path || ".")).map(entryPath).join("\n") || "(empty directory)";
3290
- } catch {
3291
- return `Directory not found: ${path}`;
3309
+ return (await ctx.execution.listFiles(ctx.handle, target)).map(entryPath).join("\n") || "(empty directory)";
3310
+ } catch (err) {
3311
+ ctx.reportOutcome?.("failed");
3312
+ const message = errorMessage(err);
3313
+ if (message.includes("ENOTDIR") || message.includes("Not a directory")) return `Not a directory: ${target} — it is a file; use read_file instead.`;
3314
+ if (message.includes("EACCES") || message.includes("EPERM") || message.includes("Permission denied")) return `Permission denied: ${target}.`;
3315
+ if (message.includes("ENOENT") || message.includes("No such file")) return `Directory not found: ${target}`;
3316
+ return `list_files failed for ${target}: ${message}`;
3292
3317
  }
3293
3318
  }
3294
3319
  };
3295
3320
  //#endregion
3321
+ //#region src/tools/model-search.ts
3322
+ /**
3323
+ * One display line per model: id, provider, real pricing, context
3324
+ * window, reasoning flag. The single source of truth for how models
3325
+ * render in BOTH the spawn schema's embedded catalog and `model_search`
3326
+ * output, so the model never sees two spellings of the same entry.
3327
+ */
3328
+ function formatModelLine(entry) {
3329
+ const { model } = entry;
3330
+ const parts = [`${model.id} (${entry.provider})`];
3331
+ if (model.cost) parts.push(`$${model.cost.input}/$${model.cost.output} per Mtok`);
3332
+ if (typeof model.contextWindow === "number" && model.contextWindow > 0) parts.push(`${Math.round(model.contextWindow / 1e3)}k ctx`);
3333
+ if (model.reasoning) parts.push("reasoning");
3334
+ if (model.name && model.name !== model.id) parts.push(model.name);
3335
+ return parts.join(" · ");
3336
+ }
3337
+ /**
3338
+ * Case-insensitive multi-term filter across id, display name, and
3339
+ * provider. Every whitespace-separated term must match somewhere
3340
+ * (mirrors the TUI picker's `filterModelCatalog` semantics). Empty /
3341
+ * whitespace queries pass everything through.
3342
+ */
3343
+ function matchModelEntries(entries, query) {
3344
+ const trimmed = query.trim().toLowerCase();
3345
+ if (!trimmed) return [...entries];
3346
+ const terms = trimmed.split(/\s+/);
3347
+ return entries.filter((entry) => {
3348
+ const corpus = `${entry.model.id} ${entry.model.name ?? ""} ${entry.provider}`.toLowerCase();
3349
+ return terms.every((t) => corpus.includes(t));
3350
+ });
3351
+ }
3352
+ /**
3353
+ * Build the `model_search` tool over a spawn model catalog. Register it
3354
+ * alongside `createSpawnTool({ models })` — typically only when the
3355
+ * catalog is too large to embed in the spawn schema, though it is
3356
+ * harmless (and occasionally useful) alongside an embedded catalog too.
3357
+ */
3358
+ function createModelSearchTool(models) {
3359
+ return {
3360
+ spec: {
3361
+ name: "model_search",
3362
+ description: [
3363
+ "List the models available for spawned subagents, with per-Mtok pricing and context windows.",
3364
+ "Use it to cost-tier delegation: find a cheap, fast model for mechanical or high-volume work before calling `spawn` with its id in the `model` field.",
3365
+ "Pass `query` to filter by substring across model id, name, and provider; omit it to list everything."
3366
+ ].join("\n"),
3367
+ inputSchema: {
3368
+ type: "object",
3369
+ properties: { query: {
3370
+ type: "string",
3371
+ description: "Optional filter — space-separated terms, ALL must match (e.g. \"haiku\" or \"openrouter qwen\")."
3372
+ } },
3373
+ additionalProperties: false
3374
+ }
3375
+ },
3376
+ async execute(input) {
3377
+ const query = typeof input.query === "string" ? input.query : "";
3378
+ const matches = matchModelEntries(models, query);
3379
+ if (matches.length === 0) return query.trim() === "" ? "No models are configured for subagent use." : `No models match "${query.trim()}". Call model_search without a query to list all ${models.length}.`;
3380
+ return [query.trim() === "" ? `${matches.length} model${matches.length === 1 ? "" : "s"} available for spawned subagents:` : `${matches.length} of ${models.length} model${models.length === 1 ? "" : "s"} match:`, ...matches.map((m) => `- ${formatModelLine(m)}`)].join("\n");
3381
+ }
3382
+ };
3383
+ }
3384
+ //#endregion
3296
3385
  //#region src/tools/multi-edit.ts
3297
3386
  /**
3298
3387
  * Inline annotation builder — kept local to avoid importing from
@@ -3910,7 +3999,7 @@ const DEFAULT_SEMANTIC = (exitCode) => ({
3910
3999
  isError: exitCode !== 0,
3911
4000
  message: exitCode !== 0 ? `Command failed with exit code ${exitCode}` : void 0
3912
4001
  });
3913
- const COMMAND_SEMANTICS = new Map([
4002
+ const COMMAND_SEMANTICS = /* @__PURE__ */ new Map([
3914
4003
  ["grep", (exit) => ({
3915
4004
  isError: exit >= 2,
3916
4005
  message: exit === 1 ? "No matches found" : void 0
@@ -4030,7 +4119,7 @@ const DEFAULT_MAX_OUTPUT_BYTES = 32768;
4030
4119
  * predicate falls back to the conservative "not safe" answer for them, so
4031
4120
  * the scheduler barriers them.
4032
4121
  */
4033
- const SHELL_READ_ONLY_COMMANDS = new Set([
4122
+ const SHELL_READ_ONLY_COMMANDS = /* @__PURE__ */ new Set([
4034
4123
  "ls",
4035
4124
  "cat",
4036
4125
  "head",
@@ -4062,7 +4151,7 @@ const SHELL_READ_ONLY_COMMANDS = new Set([
4062
4151
  * `branch`/`tag`/`remote` (which can mutate when given a name) and
4063
4152
  * `config` (which writes when given a value).
4064
4153
  */
4065
- const GIT_READ_ONLY_SUBCOMMANDS = new Set([
4154
+ const GIT_READ_ONLY_SUBCOMMANDS = /* @__PURE__ */ new Set([
4066
4155
  "status",
4067
4156
  "log",
4068
4157
  "diff",
@@ -4186,7 +4275,7 @@ const SHELL_SWAP_HINTS = [
4186
4275
  */
4187
4276
  function buildShellDescription({ allowBackground, registeredCanonicals, toolAliases }) {
4188
4277
  const lines = [
4189
- "Execute a shell command in the project root and return its combined stdout/stderr.",
4278
+ "Execute a shell command from the workspace root (the `Cwd` in your environment) and return its combined stdout/stderr. Every call starts there — `cd` never persists between calls. Use relative paths (`cd src/app && bun test`, `ls docs`), not absolute ones.",
4190
4279
  "Output is tail-priority truncated at 32 KiB by default; errors and exit-code summaries live in the tail.",
4191
4280
  "By default each call appends a `(exit N, Nms)` footer and surfaces non-empty stderr in a separate section even on success — set `metadata: false` to return only stdout. Set maxOutputBytes=0 to disable truncation.",
4192
4281
  "Pass a short `description` (5-10 words) explaining the intent of the command — it surfaces in the user-facing transcript so the human can follow your reasoning at a glance. Skip it only for trivial reads where the command speaks for itself."
@@ -4292,7 +4381,7 @@ function createShellTool(opts = {}) {
4292
4381
  const stdoutTail = tailTruncate(result.stdout || "(no output)", cap);
4293
4382
  if (!wantMetadata) return stdoutTail;
4294
4383
  const stderrTrimmed = result.stderr.trim();
4295
- return `${stdoutTail}${stderrTrimmed ? `\n[stderr]\n${tailTruncate(stderrTrimmed, Math.min(cap, 2048))}` : ""}\n(exit 0, ${durationMs}ms)`;
4384
+ return `${stdoutTail}${stderrTrimmed ? `\n[stderr]\n${tailTruncate(stderrTrimmed, Math.min(cap, 2048))}` : ""}${absoluteCdNote(cmd, ctx.handle.cwd)}\n(exit 0, ${durationMs}ms)`;
4296
4385
  }
4297
4386
  if (!semantic.isError) {
4298
4387
  const tail = tailTruncate((result.stdout || result.stderr || "").trim(), cap);
@@ -4306,6 +4395,36 @@ function createShellTool(opts = {}) {
4306
4395
  };
4307
4396
  }
4308
4397
  /**
4398
+ * Detect a `cd` whose absolute target is the workspace root itself or a
4399
+ * path under it. Every shell call already starts at the root, so the
4400
+ * absolute prefix is pure token noise — and once one absolute `cd`
4401
+ * appears in the transcript, models tend to keep imitating it. Returns
4402
+ * the relative form to suggest, `''` when the `cd` is a no-op (target
4403
+ * === root), or `null` when no redundant `cd` is present. Targets
4404
+ * OUTSIDE the workspace are legitimate and never flagged.
4405
+ */
4406
+ function redundantAbsoluteCd(command, cwd) {
4407
+ if (!cwd || !cwd.startsWith("/") || cwd === "/") return null;
4408
+ const root = cwd.replace(/\/+$/, "");
4409
+ for (const m of command.matchAll(/(?:^|&&|\|\||;)\s*cd\s+(?:'(\/[^']*)'|"(\/[^"]*)"|(\/[^\s'";|&]*))/g)) {
4410
+ const target = (m[1] ?? m[2] ?? m[3]).replace(/\/+$/, "");
4411
+ if (target === root) return "";
4412
+ if (target.startsWith(`${root}/`)) return target.slice(root.length + 1);
4413
+ }
4414
+ return null;
4415
+ }
4416
+ /**
4417
+ * One-line steer appended to a successful call's metadata footer when
4418
+ * {@link redundantAbsoluteCd} fires. Deliberately gentle and
4419
+ * self-extinguishing: it only ever appears when the model actually
4420
+ * emits a redundant absolute `cd`, and disappears as soon as it stops.
4421
+ */
4422
+ function absoluteCdNote(command, cwd) {
4423
+ const rel = redundantAbsoluteCd(command, cwd);
4424
+ if (rel === null) return "";
4425
+ return rel === "" ? "\n(note: every call already runs at the workspace root — this `cd` is redundant)" : `\n(note: every call already runs at the workspace root — \`cd ${rel}\` suffices)`;
4426
+ }
4427
+ /**
4309
4428
  * Default `shell` tool with background mode enabled.
4310
4429
  *
4311
4430
  * Most hosts use this directly via `basicTools`. When the agent's
@@ -4760,6 +4879,31 @@ function buildSubagentTypeDescription(registry) {
4760
4879
  return `Optional subagent preset that overlays the spawn tool's defaults.\n${lines.join("\n")}`;
4761
4880
  }
4762
4881
  /**
4882
+ * Catalogs up to this size embed their full model list in the spawn
4883
+ * schema's `model` field description; larger ones defer to the
4884
+ * `model_search` tool so the schema stays lean.
4885
+ */
4886
+ const EMBEDDED_CATALOG_MAX = 8;
4887
+ /**
4888
+ * Build the `model` field's description: delegation doctrine plus either
4889
+ * the embedded catalog (small) or a pointer at `model_search` (large).
4890
+ */
4891
+ function buildModelFieldDescription(catalog) {
4892
+ const doctrine = "Optional model id to run the child on. Cost-tier your delegation: mechanical, parallelizable, or high-volume search work suits cheaper/faster models; keep synthesis and final judgment on your own model. Omit to inherit your model.";
4893
+ if (catalog.length <= EMBEDDED_CATALOG_MAX) return `${doctrine}\nAvailable:\n${catalog.map((e) => `- ${formatModelLine(e)}`).join("\n")}`;
4894
+ return `${doctrine}\n${catalog.length} models are available — call \`model_search\` to browse ids, pricing, and context windows.`;
4895
+ }
4896
+ /**
4897
+ * Resolve a catalog entry's `Provider.name` against the run's provider
4898
+ * list: the active provider first, then the fallback-chain providers
4899
+ * (`ToolContext.providers`, populated by the loop for multi-provider
4900
+ * runs). `undefined` when no instance with that name serves this run.
4901
+ */
4902
+ function resolveProviderByName(name, ctx) {
4903
+ if (ctx.provider.name === name) return ctx.provider;
4904
+ return ctx.providers?.find((p) => p.name === name);
4905
+ }
4906
+ /**
4763
4907
  * Race `task` (an already-running child `agent.run()` promise) against a
4764
4908
  * timer. Does NOT race against the parent abort signal — the child agent
4765
4909
  * already observes the same signal internally and handles its own aborted
@@ -4917,7 +5061,17 @@ function buildSpawnTool(options, state) {
4917
5061
  const maxDepth = options.maxDepth ?? 3;
4918
5062
  const forwardHooks = options.forwardHooks ?? true;
4919
5063
  const subagentRegistry = options.subagents;
4920
- const subagentTypeKeys = !!subagentRegistry && Object.keys(subagentRegistry).length > 0 ? [...new Set([...Object.keys(subagentRegistry), "general-purpose"])] : [];
5064
+ const subagentTypeKeys = !!subagentRegistry && Object.keys(subagentRegistry).length > 0 ? [.../* @__PURE__ */ new Set([...Object.keys(subagentRegistry), "general-purpose"])] : [];
5065
+ const subagentTypeProperty = subagentTypeKeys.length > 0 ? { subagent_type: {
5066
+ type: "string",
5067
+ enum: subagentTypeKeys,
5068
+ description: buildSubagentTypeDescription(subagentRegistry)
5069
+ } } : {};
5070
+ const modelCatalog = options.models && options.models.length > 0 ? options.models : void 0;
5071
+ const modelProperty = modelCatalog ? { model: {
5072
+ type: "string",
5073
+ description: buildModelFieldDescription(modelCatalog)
5074
+ } } : {};
4921
5075
  return {
4922
5076
  get children() {
4923
5077
  return localChildren;
@@ -4940,10 +5094,16 @@ function buildSpawnTool(options, state) {
4940
5094
  subagents: merged
4941
5095
  }, state);
4942
5096
  },
5097
+ withModels(models) {
5098
+ return buildSpawnTool({
5099
+ ...options,
5100
+ models
5101
+ }, state);
5102
+ },
4943
5103
  isConcurrencySafe: true,
4944
5104
  spec: {
4945
5105
  name: "spawn",
4946
- description: "Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries) — for example, a deep research dive or a long codegen pass on a specific file. The sub-agent runs independently with its own tool access and returns its final response. Do NOT spawn for sequential steps you could do yourself.",
5106
+ description: `Spawn a sub-agent for a self-contained task that benefits from isolation (separate context window, separate retries) — for example, a deep research dive or a long codegen pass on a specific file. The sub-agent inherits your tool set (including \`spawn\` itself, depth-capped) and your system prompt unless overridden, runs independently, and returns its final response. Do NOT spawn for sequential steps you could do yourself.${modelCatalog ? " Children can run on a DIFFERENT model via the `model` field — cost-tier your delegation: mechanical, parallelizable, or high-volume search work belongs on cheaper/faster models, while synthesis and judgment stay on your own model." : ""}`,
4947
5107
  inputSchema: {
4948
5108
  type: "object",
4949
5109
  properties: {
@@ -4953,13 +5113,10 @@ function buildSpawnTool(options, state) {
4953
5113
  },
4954
5114
  system: {
4955
5115
  type: "string",
4956
- description: "Optional system prompt override for this specific sub-agent."
5116
+ description: "Optional system prompt override for this specific sub-agent. REPLACES the entire inherited system prompt — identity, doctrine, and environment info (cwd, platform, date) are all lost. Prefer omitting this and putting specialization in `task`; if you do override, restate the working directory and any constraints the child must keep."
4957
5117
  },
4958
- ...subagentTypeKeys.length > 0 ? { subagent_type: {
4959
- type: "string",
4960
- enum: subagentTypeKeys,
4961
- description: buildSubagentTypeDescription(subagentRegistry)
4962
- } } : {}
5118
+ ...subagentTypeProperty,
5119
+ ...modelProperty
4963
5120
  },
4964
5121
  required: ["task"]
4965
5122
  }
@@ -4969,6 +5126,23 @@ function buildSpawnTool(options, state) {
4969
5126
  const systemOverride = input.system;
4970
5127
  const requestedSubagentType = typeof input.subagent_type === "string" ? input.subagent_type : void 0;
4971
5128
  const subagentDef = requestedSubagentType && subagentRegistry ? subagentRegistry[requestedSubagentType] ?? void 0 : void 0;
5129
+ const requestedModel = modelCatalog && typeof input.model === "string" && input.model.trim() !== "" ? input.model.trim() : void 0;
5130
+ if (requestedModel && modelCatalog && !modelCatalog.some((e) => e.model.id === requestedModel)) {
5131
+ const near = matchModelEntries(modelCatalog, requestedModel).slice(0, 8);
5132
+ const shown = near.length > 0 ? near : modelCatalog.slice(0, 8);
5133
+ return `Cannot spawn: unknown model "${requestedModel}". ${near.length > 0 ? "Closest matches" : "Available"}: ${shown.map((e) => e.model.id).join(", ")}${modelCatalog.length > shown.length ? ` … (${modelCatalog.length} total — use model_search to browse)` : ""}`;
5134
+ }
5135
+ const chosenModelId = requestedModel ?? subagentDef?.model ?? options.model;
5136
+ let childProvider = ctx.provider;
5137
+ const chosenEntry = chosenModelId && modelCatalog ? modelCatalog.find((e) => e.model.id === chosenModelId) : void 0;
5138
+ if (chosenEntry) {
5139
+ const routed = resolveProviderByName(chosenEntry.provider, ctx);
5140
+ if (routed) childProvider = routed;
5141
+ else if (requestedModel !== void 0) return `Cannot spawn: model "${chosenModelId}" is served by provider "${chosenEntry.provider}", which is not available in this run. Pick a model from an available provider${modelCatalog && modelCatalog.length > EMBEDDED_CATALOG_MAX ? " (use model_search)" : ""}.`;
5142
+ }
5143
+ const inheritedModel = childProvider === ctx.provider ? ctx.model : void 0;
5144
+ const childModel = chosenModelId ?? inheritedModel;
5145
+ const announcedModel = childModel ?? childProvider.meta.defaultModel;
4972
5146
  const parentDepth = ctx.depth ?? 0;
4973
5147
  const childDepth = parentDepth + 1;
4974
5148
  if (childDepth > maxDepth) return `Cannot spawn: maxDepth=${maxDepth} reached (parent depth=${parentDepth}). Deepen the cap with createSpawnTool({ maxDepth }).`;
@@ -5003,7 +5177,7 @@ function buildSpawnTool(options, state) {
5003
5177
  const agent = createAgent({
5004
5178
  ...parentPreset,
5005
5179
  ...options.preset,
5006
- provider: ctx.provider,
5180
+ provider: childProvider,
5007
5181
  execution: ctx.execution,
5008
5182
  ...options.persist && ctx.session ? { session: ctx.session } : {},
5009
5183
  ...sharedReadState ? { readState: sharedReadState } : {}
@@ -5029,6 +5203,8 @@ function buildSpawnTool(options, state) {
5029
5203
  id,
5030
5204
  task,
5031
5205
  depth: childDepth,
5206
+ model: announcedModel,
5207
+ provider: childProvider.name,
5032
5208
  tracingContext: {}
5033
5209
  };
5034
5210
  await ctx.hooks.callHook("spawn:before", spawnHookCtx);
@@ -5036,9 +5212,9 @@ function buildSpawnTool(options, state) {
5036
5212
  const effectiveSystem = systemOverride ?? subagentDef?.system ?? options.system;
5037
5213
  const runPromise = agent.run({
5038
5214
  prompt: task,
5039
- model: options.model ?? ctx.model,
5215
+ ...childModel !== void 0 ? { model: childModel } : {},
5040
5216
  system: effectiveSystem,
5041
- thinking: options.thinking,
5217
+ thinking: subagentDef?.thinking ?? options.thinking,
5042
5218
  signal: ctx.signal,
5043
5219
  depth: childDepth,
5044
5220
  ...options.persist && ctx.runId ? { parentRunId: ctx.runId } : {},
@@ -5093,6 +5269,8 @@ function buildSpawnTool(options, state) {
5093
5269
  id,
5094
5270
  task,
5095
5271
  depth: childDepth,
5272
+ model: announcedModel,
5273
+ provider: childProvider.name,
5096
5274
  error
5097
5275
  });
5098
5276
  }
@@ -5143,6 +5321,8 @@ function buildSpawnTool(options, state) {
5143
5321
  id,
5144
5322
  task,
5145
5323
  depth: childDepth,
5324
+ model: announcedModel,
5325
+ provider: childProvider.name,
5146
5326
  error: destroyError
5147
5327
  });
5148
5328
  return result;
@@ -5642,7 +5822,7 @@ function createWorkspaceSurface(resolve, isAvailable) {
5642
5822
  }
5643
5823
  //#endregion
5644
5824
  //#region src/extensions/register.ts
5645
- const DANGEROUS_RECORD_KEYS = new Set([
5825
+ const DANGEROUS_RECORD_KEYS = /* @__PURE__ */ new Set([
5646
5826
  "__proto__",
5647
5827
  "prototype",
5648
5828
  "constructor"
@@ -9635,6 +9815,20 @@ function applyPairingRepair(ctx, messages, turnId) {
9635
9815
  })).catch(() => {});
9636
9816
  return repaired;
9637
9817
  }
9818
+ /**
9819
+ * Distinct provider instances across the run's fallback targets, in chain
9820
+ * order — exposed to tools as `ToolContext.providers` so child-spawning
9821
+ * tools can route a requested model to the provider that serves it.
9822
+ * `undefined` when the run carries no target list (hand-built contexts);
9823
+ * single-provider runs return the one-element list so consumers don't
9824
+ * need a separate code path.
9825
+ */
9826
+ function runProvidersFor(ctx) {
9827
+ if (!ctx.targets || ctx.targets.length === 0) return void 0;
9828
+ const list = [];
9829
+ for (const t of ctx.targets) if (!list.includes(t.provider)) list.push(t.provider);
9830
+ return list;
9831
+ }
9638
9832
  function sanitizeStoredToolResults(provider, messages) {
9639
9833
  return messages.map((msg) => {
9640
9834
  let changed = false;
@@ -9997,11 +10191,15 @@ function checkRunBudget(input) {
9997
10191
  function wrapProviderError(err, ctx) {
9998
10192
  if (ctx.signal.aborted || err instanceof Error && err.name === "AbortError") return new AgentAbortedError("Agent run aborted", { cause: err });
9999
10193
  const classification = ctx.provider.classifyError?.(err);
10000
- if (classification) return toTypedError(classification, ctx.provider.name, err);
10001
- return new AgentProviderError(errorMessage(err), {
10194
+ const wrapped = classification ? toTypedError(classification, ctx.provider.name, err) : new AgentProviderError(errorMessage(err), {
10002
10195
  provider: ctx.provider.name,
10003
10196
  cause: err
10004
10197
  });
10198
+ if (ctx.targetFailures && ctx.targetFailures.length > 0) {
10199
+ const trail = ctx.targetFailures.map((f) => `${f.provider}/${f.model}: ${errorMessage(f.err).replace(/\s+/g, " ").slice(0, 160)}`).join("; ");
10200
+ wrapped.message += ` [fallback chain — earlier targets also failed: ${trail}]`;
10201
+ }
10202
+ return wrapped;
10005
10203
  }
10006
10204
  function providerWatchdogTimeouts(ctx) {
10007
10205
  return {
@@ -10209,6 +10407,7 @@ function resolveAutoCompact(raw, opts = {}) {
10209
10407
  return {
10210
10408
  threshold: typeof cfg.threshold === "number" ? cfg.threshold : DEFAULT_AUTO_COMPACT_THRESHOLD,
10211
10409
  contextWindow: explicitWindow ?? fallbackWindow,
10410
+ contextWindowFromProviderMeta: explicitWindow === null && fallbackWindow !== null,
10212
10411
  keepTurns,
10213
10412
  minGrowthFraction: typeof cfg.minGrowthFraction === "number" ? cfg.minGrowthFraction : AUTO_COMPACT_MIN_GROWTH_FRACTION,
10214
10413
  restore: cfg.restore !== false,
@@ -10494,7 +10693,7 @@ async function executeTurn(ctx, turn, priorUsage) {
10494
10693
  markReadStateForElidedPaths(ctx, ctx.handle.cwd, aged.elidedReadPaths);
10495
10694
  }
10496
10695
  const effectiveThinkingBudget = applyThinkingDecay(ctx.thinkingBudget, ctx.thinkingDecay, turn);
10497
- const formattedTools = ctx.rebuildFormattedTools ? ctx.rebuildFormattedTools() : ctx.formattedTools;
10696
+ const formattedTools = ctx.rebuildFormattedTools ? ctx.rebuildFormattedTools(ctx.provider) : ctx.formattedTools;
10498
10697
  const streamOptions = {
10499
10698
  model: ctx.model,
10500
10699
  system: ctx.system,
@@ -10658,6 +10857,46 @@ async function executeTurn(ctx, turn, priorUsage) {
10658
10857
  continue;
10659
10858
  }
10660
10859
  }
10860
+ if (!wasAborted && cleanSlate && ctx.targets && classified?.kind !== "context_exceeded" && classified?.kind !== "tool_pairing_corruption") {
10861
+ const fromIndex = ctx.activeTargetIndex ?? 0;
10862
+ const nextIndex = fromIndex + 1;
10863
+ if (nextIndex < ctx.targets.length) {
10864
+ const from = ctx.targets[fromIndex];
10865
+ const to = ctx.targets[nextIndex];
10866
+ ctx.activeTargetIndex = nextIndex;
10867
+ ctx.provider = to.provider;
10868
+ ctx.model = to.model;
10869
+ ctx.providerName = to.provider.name;
10870
+ if (ctx.rebuildFormattedTools) ctx.formattedTools = ctx.rebuildFormattedTools(to.provider);
10871
+ (ctx.targetFailures ??= []).push({
10872
+ provider: from.provider.name,
10873
+ model: from.model,
10874
+ err: caught
10875
+ });
10876
+ if (ctx.autoCompact) {
10877
+ const nextWindow = to.contextWindow ?? (ctx.autoCompact.contextWindowFromProviderMeta ? to.provider.meta.contextWindow : void 0);
10878
+ if (typeof nextWindow === "number" && Number.isFinite(nextWindow) && nextWindow > 0) ctx.autoCompact.contextWindow = nextWindow;
10879
+ }
10880
+ streamOptions.model = to.model;
10881
+ streamOptions.tools = ctx.formattedTools;
10882
+ streamOptions.messages = sanitizeStoredToolResults(to.provider, streamOptions.messages);
10883
+ attempt = 0;
10884
+ await settledHook(ctx, "hook model:fallback", ctx.hooks.callHook("model:fallback", {
10885
+ turnId,
10886
+ from: {
10887
+ provider: from.provider.name,
10888
+ model: from.model
10889
+ },
10890
+ to: {
10891
+ provider: to.provider.name,
10892
+ model: to.model
10893
+ },
10894
+ targetIndex: nextIndex,
10895
+ err: caught
10896
+ }));
10897
+ continue;
10898
+ }
10899
+ }
10661
10900
  await streamHookChain;
10662
10901
  const errorUsage = {
10663
10902
  input: 0,
@@ -11090,10 +11329,12 @@ async function runSingleToolDispatch(ctx, call, turnId, fixed) {
11090
11329
  let reportedOutcome;
11091
11330
  const composedSignal = composePerCallSignal(ctx.signal, perCallAbort.signal);
11092
11331
  const childSignal = composedSignal.signal;
11332
+ const runProviders = runProvidersFor(ctx);
11093
11333
  try {
11094
11334
  const toolCtx = {
11095
11335
  provider: ctx.provider,
11096
11336
  model: ctx.model,
11337
+ ...runProviders ? { providers: runProviders } : {},
11097
11338
  signal: childSignal,
11098
11339
  execution: ctx.execution,
11099
11340
  handle: ctx.handle,
@@ -11681,9 +11922,11 @@ async function startDurableToolExecution(ctx, call, turnId, index) {
11681
11922
  const composedSignal = composePerCallSignal(ctx.signal, perCallAbort.signal);
11682
11923
  const childSignal = composedSignal.signal;
11683
11924
  let reportedOutcome;
11925
+ const runProviders = runProvidersFor(ctx);
11684
11926
  const toolCtx = {
11685
11927
  provider: ctx.provider,
11686
11928
  model: ctx.model,
11929
+ ...runProviders ? { providers: runProviders } : {},
11687
11930
  signal: childSignal,
11688
11931
  execution: ctx.execution,
11689
11932
  handle: ctx.handle,
@@ -11933,6 +12176,69 @@ async function executeNativeToolBatch(ctx, toolCalls, turnId) {
11933
12176
  }
11934
12177
  }
11935
12178
  //#endregion
12179
+ //#region src/model-targets.ts
12180
+ /**
12181
+ * Normalize `AgentOptions.provider` into a non-empty provider list.
12182
+ *
12183
+ * In multi-provider setups every provider needs a non-blank, unique name —
12184
+ * model entries reference providers by `Provider.name`, so a blank or
12185
+ * duplicate name would make the reference ambiguous (and surface as a
12186
+ * baffling `duplicate provider name ""` otherwise). A single provider
12187
+ * keeps today's behavior: its name plays no role in target resolution,
12188
+ * so no constraint applies. Throws at agent construction rather than at
12189
+ * run time.
12190
+ */
12191
+ function normalizeProviders(provider) {
12192
+ const providers = Array.isArray(provider) ? [...provider] : [provider];
12193
+ if (providers.length === 0) throw new Error("AgentOptions.provider: provider array must not be empty");
12194
+ if (providers.length === 1) return providers;
12195
+ const seen = /* @__PURE__ */ new Set();
12196
+ for (const p of providers) {
12197
+ if (!p.name.trim()) throw new Error("AgentOptions.provider: multi-provider setups require a non-empty name on every provider — model entries reference providers by name");
12198
+ if (seen.has(p.name)) throw new Error(`AgentOptions.provider: duplicate provider name "${p.name}" — names must be unique so model entries can reference providers unambiguously`);
12199
+ seen.add(p.name);
12200
+ }
12201
+ return providers;
12202
+ }
12203
+ /**
12204
+ * Resolve a run's model selection into an ordered, de-duplicated fallback
12205
+ * chain of provider+model targets. `targets[0]` is the primary.
12206
+ *
12207
+ * Expansion rules:
12208
+ * - `undefined` → each provider's `meta.defaultModel`, in provider order.
12209
+ * - `string` → that model id on every provider, in provider order.
12210
+ * - array → entries in order; a `{ provider, model }` entry resolves to that
12211
+ * one provider (throws on unknown names), while bare strings and
12212
+ * provider-less objects fan out across all providers.
12213
+ */
12214
+ function resolveModelTargets(providers, model) {
12215
+ if (providers.length === 0) throw new Error("resolveModelTargets: providers list must not be empty");
12216
+ const targets = [];
12217
+ const push = (provider, model, contextWindow) => {
12218
+ if (!targets.some((t) => t.provider === provider && t.model === model)) targets.push({
12219
+ provider,
12220
+ model,
12221
+ ...contextWindow !== void 0 ? { contextWindow } : {}
12222
+ });
12223
+ };
12224
+ const fanOut = (model, contextWindow) => {
12225
+ for (const p of providers) push(p, model, contextWindow);
12226
+ };
12227
+ if (model === void 0) for (const p of providers) push(p, p.meta.defaultModel);
12228
+ else if (typeof model === "string") fanOut(model);
12229
+ else {
12230
+ if (model.length === 0) throw new Error("model: fallback array must not be empty");
12231
+ for (const entry of model) if (typeof entry === "string") fanOut(entry);
12232
+ else if (entry.provider === void 0) fanOut(entry.model, entry.contextWindow);
12233
+ else {
12234
+ const p = providers.find((x) => x.name === entry.provider);
12235
+ if (!p) throw new Error(`model: unknown provider "${entry.provider}" — configured providers: ${providers.map((x) => x.name).join(", ")}`);
12236
+ push(p, entry.model, entry.contextWindow);
12237
+ }
12238
+ }
12239
+ return targets;
12240
+ }
12241
+ //#endregion
11936
12242
  //#region src/tool-cancel.ts
11937
12243
  /**
11938
12244
  * Per-call tool-cancellation registry shared between the agent and the loop.
@@ -12183,7 +12489,7 @@ function renderTaskStallXml(info) {
12183
12489
  "</task-stall>"
12184
12490
  ].join("\n");
12185
12491
  }
12186
- const HOOK_EVENT_SET = new Set([
12492
+ const HOOK_EVENT_SET = /* @__PURE__ */ new Set([
12187
12493
  "system:before",
12188
12494
  "agent:start",
12189
12495
  "turn:before",
@@ -12197,6 +12503,7 @@ const HOOK_EVENT_SET = new Set([
12197
12503
  "stream:server_tool_result",
12198
12504
  "stream:error",
12199
12505
  "stream:retry",
12506
+ "model:fallback",
12200
12507
  "context:overflow",
12201
12508
  "compact:start",
12202
12509
  "compact:progress",
@@ -13016,7 +13323,9 @@ function warnContextContributorFailureOnce(contributor, err) {
13016
13323
  process.stderr.write(`[zidane/agent] context breakdown contributor failed${owner}: ${errorMessage(err)}\n`);
13017
13324
  }
13018
13325
  function createAgent(rawOptions) {
13019
- const { provider, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, handle: injectedHandle, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock, toolKill, contextBreakdownSections, runTransforms, behaviorTransforms, toolCatalogTransforms, mcpConfigTransforms, skillPolicies, toolResultMetadata } = foldExtensionRegistry(rawOptions);
13326
+ const { provider: providerOption, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, handle: injectedHandle, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock, toolKill, contextBreakdownSections, runTransforms, behaviorTransforms, toolCatalogTransforms, mcpConfigTransforms, skillPolicies, toolResultMetadata } = foldExtensionRegistry(rawOptions);
13327
+ const providers = normalizeProviders(providerOption);
13328
+ const provider = providers[0];
13020
13329
  const hooks = createHooks();
13021
13330
  const executionContext = execution ?? createProcessContext();
13022
13331
  const sourceTools = agentTools ?? {};
@@ -13162,6 +13471,8 @@ function createAgent(rawOptions) {
13162
13471
  async function runWithinSession(options) {
13163
13472
  if (running) throw new Error("Agent is already running. Use steer() or followUp() to queue messages, or waitForIdle().");
13164
13473
  options = applyRunTransforms(options, runTransforms);
13474
+ const targets = resolveModelTargets(providers, options.model);
13475
+ const runProvider = targets[0].provider;
13165
13476
  const resumeFilteredTurns = validateAndPrepareResume(session, options.prompt, pendingTaskNotifications.size > 0);
13166
13477
  const clock = options.clock ?? agentClock ?? DEFAULT_AGENT_CLOCK;
13167
13478
  let externalAbortListener;
@@ -13202,7 +13513,7 @@ function createAgent(rawOptions) {
13202
13513
  ...options.parentRunId ? { parentRunId: options.parentRunId } : {},
13203
13514
  depth: typeof options.depth === "number" ? options.depth : 0,
13204
13515
  ...agentName ? { agentName } : {},
13205
- ...provider.name ? { providerName: provider.name } : {},
13516
+ ...runProvider.name ? { providerName: runProvider.name } : {},
13206
13517
  startedAt: runStartedAt,
13207
13518
  ...options.tracingContext ? { tracingContext: Object.freeze({ ...options.tracingContext }) } : {}
13208
13519
  }), hookTimeoutMs);
@@ -13243,8 +13554,8 @@ function createAgent(rawOptions) {
13243
13554
  });
13244
13555
  if (resolvedSkills && session && session.turns.length > 0 && skillActivationState.active().length === 0) await rehydrateActiveSkillsFromTurns(session, resolvedSkills, skillActivationState, hooks);
13245
13556
  const thinking = options.thinking ?? "off";
13246
- const model = options.model ?? provider.meta.defaultModel;
13247
- if (provider.meta?.clearsContextServerSide) resolvedBehavior.dedupReads = false;
13557
+ const model = targets[0].model;
13558
+ if (runProvider.meta?.clearsContextServerSide) resolvedBehavior.dedupReads = false;
13248
13559
  const { maxConcurrentTools, toolBatchExecutor, toolBatchTimeoutMs, shouldRethrowToolError, maxTurns, maxTurnsWarning, maxTurnsWarningMessage, maxCostUsd, maxTotalTokens, maxWallMs, providerStreamStartTimeoutMs, providerStreamTimeoutMs, maxTokens, retry, thinkingBudget, thinkingOverrunPolicy, modelOptions: behaviorModelOptions, schema, cache, toolOutputBudget, toolOutputBudgetExcludeTools, compactStrategy, compactThreshold, compactKeepTurns, thinkingDecay, writeFileExistingPolicy, textToolCallRescue, unknownToolRecovery, progressNudges, dedupTools, toolBudgets, repeatGuard, elideStaleReads, mediaKeepTurns, autoCompact, toolDisclosure, mcpToolNameSeparator, toolSearch, surfaceMcpInstructions, persistThreshold, persistExcludeTools, persistDir, persistMaxBytes, strictToolPairing, maxPairingRepairsPerTurn, maxConsecutivePauseTurns, resumeOnMaxTokens, persistTurns } = resolvedBehavior;
13249
13560
  const modelOptions = options.modelOptions ?? behaviorModelOptions;
13250
13561
  let system = options.system || agentSystem || "You are a helpful assistant.";
@@ -13336,9 +13647,10 @@ function createAgent(rawOptions) {
13336
13647
  }
13337
13648
  const aliasMaps = buildAliasMaps(effectiveToolAliases, Object.keys(tools));
13338
13649
  augmentMcpDoubleUnderscoreAliases(aliasMaps, Object.keys(tools));
13339
- let formattedToolsCache = null;
13340
- function buildFormattedTools() {
13341
- if (formattedToolsCache && formattedToolsCache.tailLen === dynamicUnlockOrder.length) return formattedToolsCache.value;
13650
+ const formattedToolsCache = /* @__PURE__ */ new Map();
13651
+ function buildFormattedTools(forProvider = runProvider) {
13652
+ const cached = formattedToolsCache.get(forProvider);
13653
+ if (cached && cached.tailLen === dynamicUnlockOrder.length) return cached.value;
13342
13654
  const specs = [];
13343
13655
  for (const t of Object.values(tools)) {
13344
13656
  if (!initialUnlocked.has(t.spec.name)) continue;
@@ -13357,11 +13669,11 @@ function createAgent(rawOptions) {
13357
13669
  inputSchema: t.spec.inputSchema
13358
13670
  });
13359
13671
  }
13360
- const value = specs.length > 0 ? provider.formatTools(specs) : [];
13361
- formattedToolsCache = {
13672
+ const value = specs.length > 0 ? forProvider.formatTools(specs) : [];
13673
+ formattedToolsCache.set(forProvider, {
13362
13674
  tailLen: dynamicUnlockOrder.length,
13363
13675
  value
13364
- };
13676
+ });
13365
13677
  return value;
13366
13678
  }
13367
13679
  const formattedTools = buildFormattedTools();
@@ -13473,7 +13785,7 @@ function createAgent(rawOptions) {
13473
13785
  let lastPersistedTurnCount = turns.length;
13474
13786
  const promptParts = canonicalizePrompt(options.prompt);
13475
13787
  if (promptParts || drainedNotifications.length > 0) {
13476
- const promptMsg = promptParts ? buildPromptMessage(provider, promptParts) : null;
13788
+ const promptMsg = promptParts ? buildPromptMessage(runProvider, promptParts) : null;
13477
13789
  const content = [...drainedNotifications, ...promptMsg ? promptMsg.content : []];
13478
13790
  turns.push({
13479
13791
  id: await mintTurnId(),
@@ -13520,7 +13832,10 @@ function createAgent(rawOptions) {
13520
13832
  const unregisterToolResultsSync = perTurnSync ? hooks.hook("tool-results:after", persistPendingTurns) : void 0;
13521
13833
  async function flushTurns(opts = {}) {
13522
13834
  if (!session) return;
13523
- if (opts.failureFallback) await synthesizeMissingToolResults(turns, await mintTurnId(), runId, provider, hooks, clock);
13835
+ if (opts.failureFallback) {
13836
+ const turnId = await mintTurnId();
13837
+ await synthesizeMissingToolResults(turns, turnId, runId, runProvider, hooks, clock);
13838
+ }
13524
13839
  const remaining = turns.slice(lastPersistedTurnCount);
13525
13840
  if (remaining.length > 0) {
13526
13841
  await settleWithinTimeout("session.appendTurns", session.appendTurns(remaining), hookTimeoutMs);
@@ -13613,14 +13928,15 @@ function createAgent(rawOptions) {
13613
13928
  turnUsage: []
13614
13929
  };
13615
13930
  const wallStartMs = Date.now();
13616
- const providerContextWindow = typeof provider.meta.contextWindow === "number" ? provider.meta.contextWindow : void 0;
13931
+ const providerContextWindow = typeof runProvider.meta.contextWindow === "number" ? runProvider.meta.contextWindow : void 0;
13617
13932
  const resolvedAutoCompact = resolveAutoCompact(autoCompact, {
13618
13933
  ...providerContextWindow !== void 0 ? { fallbackContextWindow: providerContextWindow } : {},
13619
13934
  ...compactKeepTurns !== void 0 ? { compactKeepTurns } : {}
13620
13935
  });
13621
13936
  try {
13622
13937
  const stats = await runLoop({
13623
- provider,
13938
+ provider: runProvider,
13939
+ targets,
13624
13940
  hooks,
13625
13941
  agentName,
13626
13942
  agentSystem,
@@ -13631,7 +13947,7 @@ function createAgent(rawOptions) {
13631
13947
  agentBehavior: resolvedBehavior,
13632
13948
  tools,
13633
13949
  formattedTools,
13634
- rebuildFormattedTools: disclosure.lazyEntries.length > 0 ? buildFormattedTools : void 0,
13950
+ rebuildFormattedTools: buildFormattedTools,
13635
13951
  aliasMaps,
13636
13952
  model,
13637
13953
  system,
@@ -13688,7 +14004,7 @@ function createAgent(rawOptions) {
13688
14004
  ...maxPairingRepairsPerTurn !== void 0 ? { maxPairingRepairsPerTurn } : {},
13689
14005
  ...maxConsecutivePauseTurns !== void 0 ? { maxConsecutivePauseTurns } : {},
13690
14006
  ...resumeOnMaxTokens !== void 0 ? { resumeOnMaxTokens } : {},
13691
- providerName: provider.name,
14007
+ providerName: runProvider.name,
13692
14008
  runStartMs,
13693
14009
  runToolCounts: {},
13694
14010
  toolCancels,
@@ -14267,6 +14583,6 @@ function createAgent(rawOptions) {
14267
14583
  };
14268
14584
  }
14269
14585
  //#endregion
14270
- export { filterExtensionRegistry as $, clampExtensionConfigNumber as $t, sliceForCompaction as A, DEFAULT_KEYBINDINGS as At, installExtensionFromSpec as B, parseBindingSpec as Bt, buildCompactPrompt as C, listFiles as Ct, buildUpToCompactPrompt as D, edit as Dt, buildTailCompactPrompt as E, glob as Et, CompactPromptTooLongError as F, formatBindingForDisplay as Ft, updateInstalledExtension as G, ENTRY_CANDIDATES as Gt, parseExtensionInstallSource as H, readKeybindingsRaw as Ht, EMPTY_EXTENSION_REGISTRY as I, groupBindings as It, discoverAndBuildExtensionRegistry as J, inlineLoadedExtension as Jt, createExtensionHud as K, defaultExtensionScanPaths as Kt, createExtensionPromptBridge as L, keybindingsPath as Lt, summaryToTurn as M, KEYBINDING_DEF_BY_ACTION as Mt, truncateHeadForPtlRetry as N, KEYBINDING_KEY_COL_WIDTH as Nt, ANCHOR_PREVIEW_MAX_CHARS as O, validateToolArgs as Ot, CompactInvalidInputError as P, ensureKeybindingsFile as Pt, disposeExtensionRegistry as Q, defineExtension as Qt, ExtensionInstallError as R, matchesBinding as Rt, TRAILER as S, multiEdit as St, buildFullCompactPrompt as T, grep as Tt, readExtensionInstallProvenance as U, resolveExtensionKeybindings as Ut, listExtensionCandidates as V, readKeybindings as Vt, removeInstalledExtension as W, stripJsonComments as Wt, buildExtensionRegistry as X, parseExtensionScanPathEnv as Xt, buildExtensionPreset as Y, isExtensionDefinition as Yt, composeExtensionPreset as Z, scanExtensionDirectories as Zt, selectFilesFromSession as _, shellKill as _t, TOOL_USE_SKIPPED_MESSAGE as a, toWireConfigSchema as an, definePreset as at, BASE_INSTRUCTIONS as b, tailTruncate as bt, PERSISTENCE_PREVIEW_BYTES as c, effectiveContextWindow as cn, writeFile$1 as ct, maybePersistToolResult as d, defaultRepeatGuardTracked as dn, createToolSearchTool as dt, coerceExtensionConfigInput as en, mergeContributions as et, resolveMcpWarningsDir as f, normalizeShellCommand as fn, createSpawnTool as ft, selectFilesFromReadState as g, createSkillsReadTool as gt, buildPostCompactAttachments as h, createSkillsRunScriptTool as ht, TOOL_USE_CANCELLED_MESSAGE as i, resolveExtensionConfigValue as in, composePresets as it, stripImagesFromTurns as j, KEYBINDING_DEFS as jt, anchorPreviewFor as k, resolveStorageDirs as kt, buildPersistedStub as l, shouldAutoCompact as ln, WAIT_TASK_TIMED_OUT_PREFIX as lt, resolveTasksDir as m, createSkillsUseTool as mt, INTERRUPT_MESSAGE_FOR_TOOL_USE as n, isValidExtensionConfigValue as nn, createExtensionHostRuntimeBridge as nt, applyCompactSummaryCutoff as o, AUTO_COMPACT_MIN_GROWTH_FRACTION as on, basicTools as ot, resolvePersistDir as p, stableStringify as pn, isSpawnTool as pt, registerExtensionHostModules as q, discoverExtensions as qt, SHELL_CASCADE_CANCEL_MESSAGE as r, resolveExtensionConfig as rn, createWorkspaceSurface as rt, PERSISTED_STUB_PREFIX as s, OUTPUT_RESERVE_TOKENS as sn, basic_default as st, createAgent as t, isValidExtensionConfigItem as tn, partitionExtensionCatalog as tt, cleanupPersistedSession as u, defaultRepeatGuardNormalize as un, waitTask as ut, selectRecentFiles as v, createShellTool as vt, buildFromCompactPrompt as w, createInteractionTool as wt, NO_TOOLS_PREAMBLE as x, readFile$1 as xt, compactConversation as y, shell as yt, fetchExtensionSource as z, mergeKeybindings as zt };
14586
+ export { composeExtensionPreset as $, inlineLoadedExtension as $t, ANCHOR_PREVIEW_MAX_CHARS as A, grep as At, ExtensionInstallError as B, formatBindingForDisplay as Bt, NO_TOOLS_PREAMBLE as C, readFile$1 as Ct, buildFullCompactPrompt as D, matchModelEntries as Dt, buildFromCompactPrompt as E, formatModelLine as Et, truncateHeadForPtlRetry as F, DEFAULT_KEYBINDINGS as Ft, readExtensionInstallProvenance as G, parseBindingSpec as Gt, installExtensionFromSpec as H, keybindingsPath as Ht, CompactInvalidInputError as I, KEYBINDING_DEFS as It, createExtensionHud as J, resolveExtensionKeybindings as Jt, removeInstalledExtension as K, readKeybindings as Kt, CompactPromptTooLongError as L, KEYBINDING_DEF_BY_ACTION as Lt, sliceForCompaction as M, edit as Mt, stripImagesFromTurns as N, validateToolArgs as Nt, buildTailCompactPrompt as O, listFiles as Ot, summaryToTurn as P, resolveStorageDirs as Pt, buildExtensionRegistry as Q, discoverExtensions as Qt, EMPTY_EXTENSION_REGISTRY as R, KEYBINDING_KEY_COL_WIDTH as Rt, BASE_INSTRUCTIONS as S, tailTruncate as St, buildCompactPrompt as T, createModelSearchTool as Tt, listExtensionCandidates as U, matchesBinding as Ut, fetchExtensionSource as V, groupBindings as Vt, parseExtensionInstallSource as W, mergeKeybindings as Wt, discoverAndBuildExtensionRegistry as X, ENTRY_CANDIDATES as Xt, registerExtensionHostModules as Y, stripJsonComments as Yt, buildExtensionPreset as Z, defaultExtensionScanPaths as Zt, buildPostCompactAttachments as _, normalizeShellCommand as _n, createSkillsRunScriptTool as _t, SHELL_CASCADE_CANCEL_MESSAGE as a, coerceExtensionConfigInput as an, createWorkspaceSurface as at, selectRecentFiles as b, createShellTool as bt, applyCompactSummaryCutoff as c, resolveExtensionConfig as cn, basicTools as ct, buildPersistedStub as d, AUTO_COMPACT_MIN_GROWTH_FRACTION as dn, WAIT_TASK_TIMED_OUT_PREFIX as dt, isExtensionDefinition as en, disposeExtensionRegistry as et, cleanupPersistedSession as f, OUTPUT_RESERVE_TOKENS as fn, waitTask as ft, resolveTasksDir as g, defaultRepeatGuardTracked as gn, createSkillsUseTool as gt, resolvePersistDir as h, defaultRepeatGuardNormalize as hn, isSpawnTool as ht, INTERRUPT_MESSAGE_FOR_TOOL_USE as i, clampExtensionConfigNumber as in, createExtensionHostRuntimeBridge as it, anchorPreviewFor as j, glob as jt, buildUpToCompactPrompt as k, createInteractionTool as kt, PERSISTED_STUB_PREFIX as l, resolveExtensionConfigValue as ln, basic_default as lt, resolveMcpWarningsDir as m, shouldAutoCompact as mn, createSpawnTool as mt, normalizeProviders as n, scanExtensionDirectories as nn, mergeContributions as nt, TOOL_USE_CANCELLED_MESSAGE as o, isValidExtensionConfigItem as on, composePresets as ot, maybePersistToolResult as p, effectiveContextWindow as pn, createToolSearchTool as pt, updateInstalledExtension as q, readKeybindingsRaw as qt, resolveModelTargets as r, defineExtension as rn, partitionExtensionCatalog as rt, TOOL_USE_SKIPPED_MESSAGE as s, isValidExtensionConfigValue as sn, definePreset as st, createAgent as t, parseExtensionScanPathEnv as tn, filterExtensionRegistry as tt, PERSISTENCE_PREVIEW_BYTES as u, toWireConfigSchema as un, writeFile$1 as ut, selectFilesFromReadState as v, stableStringify as vn, createSkillsReadTool as vt, TRAILER as w, multiEdit as wt, compactConversation as x, shell as xt, selectFilesFromSession as y, shellKill as yt, createExtensionPromptBridge as z, ensureKeybindingsFile as zt };
14271
14587
 
14272
- //# sourceMappingURL=agent-DkSmGkDM.js.map
14588
+ //# sourceMappingURL=agent-DZRA7wip.js.map