zidane 7.0.31 → 7.1.1

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 (125) hide show
  1. package/README.md +21 -2
  2. package/dist/{acp-m3TLCY_C.js → acp-B5UfEhMd.js} +4 -4
  3. package/dist/{acp-m3TLCY_C.js.map → acp-B5UfEhMd.js.map} +1 -1
  4. package/dist/acp-cli.js +6 -6
  5. package/dist/acp.d.ts +2 -2
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-9gf8ZlBR.js → agent-_xxElOgH.js} +307 -33
  8. package/dist/agent-_xxElOgH.js.map +1 -0
  9. package/dist/agent.d.ts +1 -1
  10. package/dist/agent.js +1 -1
  11. package/dist/{anthropic-B4UmPm4H.js → anthropic-DPPs3wjJ.js} +111 -7
  12. package/dist/anthropic-DPPs3wjJ.js.map +1 -0
  13. package/dist/{approvals-DaCEPCTV.js → approvals-u2T19Dc-.js} +297 -95
  14. package/dist/approvals-u2T19Dc-.js.map +1 -0
  15. package/dist/{auth-CJogE9q7.js → auth-HRKkOErn.js} +3 -3
  16. package/dist/{auth-CJogE9q7.js.map → auth-HRKkOErn.js.map} +1 -1
  17. package/dist/chat/pure.d.ts +3 -3
  18. package/dist/chat/pure.js +1 -1
  19. package/dist/chat.d.ts +6 -6
  20. package/dist/chat.js +8 -8
  21. package/dist/contexts/daytona.d.ts +3 -3
  22. package/dist/contexts/docker.d.ts +1 -1
  23. package/dist/contexts/e2b.d.ts +2 -2
  24. package/dist/contexts/sandbox.d.ts +1 -1
  25. package/dist/{contexts-BSFQVclW.js → contexts-CRE9pw07.js} +544 -17
  26. package/dist/contexts-CRE9pw07.js.map +1 -0
  27. package/dist/contexts.d.ts +4 -4
  28. package/dist/contexts.js +2 -2
  29. package/dist/daemon-cli.js +1 -1
  30. package/dist/eval.d.ts +1 -1
  31. package/dist/eval.js +3 -3
  32. package/dist/extensions.d.ts +1 -1
  33. package/dist/extensions.js +1 -1
  34. package/dist/headless.d.ts +1 -1
  35. package/dist/headless.js +3 -3
  36. package/dist/{index-B6FkK6ZN.d.ts → index-C37_ppWv.d.ts} +2 -2
  37. package/dist/index-C37_ppWv.d.ts.map +1 -0
  38. package/dist/{index-JkEO3MBV.d.ts → index-D3TTaaQ5.d.ts} +39 -7
  39. package/dist/index-D3TTaaQ5.d.ts.map +1 -0
  40. package/dist/{index-hd4zLhp8.d.ts → index-DZhrTn-v.d.ts} +307 -16
  41. package/dist/index-DZhrTn-v.d.ts.map +1 -0
  42. package/dist/index.d.ts +5 -5
  43. package/dist/index.js +8 -8
  44. package/dist/{ipc-BtN5SIc0.js → ipc-DwauKEE-.js} +3 -3
  45. package/dist/{ipc-BtN5SIc0.js.map → ipc-DwauKEE-.js.map} +1 -1
  46. package/dist/ipc.d.ts +5 -5
  47. package/dist/ipc.js +3 -3
  48. package/dist/{types-U-rIVUDw.d.ts → isolation-Kfoof0MM.d.ts} +93 -2
  49. package/dist/isolation-Kfoof0MM.d.ts.map +1 -0
  50. package/dist/mcp.d.ts +1 -1
  51. package/dist/output/stream-json.d.ts +1 -1
  52. package/dist/output/terminal.d.ts +1 -1
  53. package/dist/{plugins-B531Tz5b.js → plugins-gbI7SBA6.js} +3 -3
  54. package/dist/{plugins-B531Tz5b.js.map → plugins-gbI7SBA6.js.map} +1 -1
  55. package/dist/plugins.d.ts +1 -1
  56. package/dist/plugins.js +1 -1
  57. package/dist/presets.d.ts +1 -1
  58. package/dist/presets.js +1 -1
  59. package/dist/providers/anthropic.d.ts +2 -2
  60. package/dist/providers/anthropic.js +2 -2
  61. package/dist/providers/arcee.d.ts +1 -1
  62. package/dist/providers/baseten.d.ts +1 -1
  63. package/dist/providers/cerebras.d.ts +1 -1
  64. package/dist/providers/local.d.ts +1 -1
  65. package/dist/providers/openai-compat.d.ts +1 -1
  66. package/dist/providers/openai.d.ts +1 -1
  67. package/dist/providers/openrouter.d.ts +1 -1
  68. package/dist/providers/xai.d.ts +1 -1
  69. package/dist/providers.d.ts +2 -2
  70. package/dist/providers.js +1 -1
  71. package/dist/restate.d.ts +2 -2
  72. package/dist/restate.js +1 -1
  73. package/dist/{sandbox-CDl9tfTo.d.ts → sandbox-BH0WQkXn.d.ts} +2 -2
  74. package/dist/{sandbox-CDl9tfTo.d.ts.map → sandbox-BH0WQkXn.d.ts.map} +1 -1
  75. package/dist/{server-ktOMu5gk.js → server-DvPnPSZb.js} +8 -8
  76. package/dist/{server-ktOMu5gk.js.map → server-DvPnPSZb.js.map} +1 -1
  77. package/dist/session/sqlite.d.ts +1 -1
  78. package/dist/session/sqlite.d.ts.map +1 -1
  79. package/dist/session/sqlite.js +7 -0
  80. package/dist/session/sqlite.js.map +1 -1
  81. package/dist/{session-CVy-2mAy.js → session-BqRP1hS7.js} +33 -3
  82. package/dist/session-BqRP1hS7.js.map +1 -0
  83. package/dist/session.d.ts +1 -1
  84. package/dist/session.js +1 -1
  85. package/dist/{skills-PJyiSRCp.js → skills-BC3dodWp.js} +2 -2
  86. package/dist/{skills-PJyiSRCp.js.map → skills-BC3dodWp.js.map} +1 -1
  87. package/dist/skills.d.ts +1 -1
  88. package/dist/skills.js +1 -1
  89. package/dist/{src-CjkY6fBj.js → src-CkNQKFKr.js} +3 -3
  90. package/dist/{src-CjkY6fBj.js.map → src-CkNQKFKr.js.map} +1 -1
  91. package/dist/{tool-formatters-C4QIFCNa.d.ts → tool-formatters-C5s88MUd.d.ts} +2 -2
  92. package/dist/{tool-formatters-C4QIFCNa.d.ts.map → tool-formatters-C5s88MUd.d.ts.map} +1 -1
  93. package/dist/tools/fetch-url.d.ts +1 -1
  94. package/dist/tools/web-search.d.ts +1 -1
  95. package/dist/tools.d.ts +1 -1
  96. package/dist/tools.js +1 -1
  97. package/dist/{transcript-anchors-Bbn1HX5D.d.ts → transcript-anchors-DxofXw_y.d.ts} +3 -3
  98. package/dist/transcript-anchors-DxofXw_y.d.ts.map +1 -0
  99. package/dist/tui.d.ts +21 -28
  100. package/dist/tui.d.ts.map +1 -1
  101. package/dist/tui.js +200 -74
  102. package/dist/tui.js.map +1 -1
  103. package/dist/{turn-operations-BgqpLlOG.js → turn-operations-6JDu2ewy.js} +24 -2
  104. package/dist/{turn-operations-BgqpLlOG.js.map → turn-operations-6JDu2ewy.js.map} +1 -1
  105. package/dist/{turn-operations-BhHCpCkP.d.ts → turn-operations-BaQnxzhr.d.ts} +14 -4
  106. package/dist/{turn-operations-BhHCpCkP.d.ts.map → turn-operations-BaQnxzhr.d.ts.map} +1 -1
  107. package/dist/types-CWgENVLY.js.map +1 -1
  108. package/dist/types.d.ts +3 -3
  109. package/docs/ARCHITECTURE.md +13 -3
  110. package/docs/CHAT.md +9 -0
  111. package/docs/EXECUTION_CONTEXT.md +64 -3
  112. package/docs/INTERACTIONS.md +14 -2
  113. package/docs/SKILL.md +31 -1
  114. package/docs/TUI.md +6 -5
  115. package/package.json +1 -1
  116. package/dist/agent-9gf8ZlBR.js.map +0 -1
  117. package/dist/anthropic-B4UmPm4H.js.map +0 -1
  118. package/dist/approvals-DaCEPCTV.js.map +0 -1
  119. package/dist/contexts-BSFQVclW.js.map +0 -1
  120. package/dist/index-B6FkK6ZN.d.ts.map +0 -1
  121. package/dist/index-JkEO3MBV.d.ts.map +0 -1
  122. package/dist/index-hd4zLhp8.d.ts.map +0 -1
  123. package/dist/session-CVy-2mAy.js.map +0 -1
  124. package/dist/transcript-anchors-Bbn1HX5D.d.ts.map +0 -1
  125. package/dist/types-U-rIVUDw.d.ts.map +0 -1
@@ -3,22 +3,22 @@ import { a as documentBlockMarker, c as toolOutputBudgetByteLength, l as toolOut
3
3
  import { a as stripLineNumberPrefixes, i as resolveOldString, n as buildContextBreakdown, o as styleReplacementForVia, r as describeVia, t as buildContextSegments } from "./context-segments-BrEsRhA0.js";
4
4
  import { n as estimateTokens, r as utf8ByteLength } from "./utils-ngQzYzZD.js";
5
5
  import { a as formatDuration, c as previewLine, o as formatTaskStatus, s as formatTaskSummary } from "./format-BF745pLL.js";
6
+ import { r as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-CRE9pw07.js";
6
7
  import { i as parseGitLsFiles, r as GIT_LS_FILES_COMMAND } from "./glob-DluQFSw1.js";
7
8
  import { i as isOutputExceededMessage } from "./output-cap-C9zukcCj.js";
8
- import { r as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-BSFQVclW.js";
9
9
  import { n as shellQuote, t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
10
10
  import { a as AgentProviderError, d as isAbortLikeError, g as toTypedError, i as AgentLengthResumeExhaustedError, n as AgentBudgetExceededError, p as isTransientTransportError, s as AgentToolPairingError, t as AgentAbortedError, u as errorMessage } from "./errors-DKiMrOKq.js";
11
11
  import { i as ARTIFACT_KIND_PATTERN, l as normalizeArtifactInput, o as ARTIFACT_URI_MAX_CHARS, r as ARTIFACT_KINDS, t as ARTIFACTS_METADATA_KEY } from "./artifacts-CV2hUKnL.js";
12
- import { E as buildCatalog, L as projectUserPaths, O as installAllowedToolsGate, P as validateResourcePathReal, R as findGitRoot, _ as lastLine, a as interpolateShellCommands, b as resolveSubdirRoot, g as fetchInstallSource, h as defaultWhich, k as createSkillActivationState, m as defaultExec, n as resolveSkills, o as stripShellInterpolations, p as InstallSourceError, v as parseInstallSource, y as resolveNpmVersion } from "./skills-PJyiSRCp.js";
12
+ import { E as buildCatalog, L as projectUserPaths, O as installAllowedToolsGate, P as validateResourcePathReal, R as findGitRoot, _ as lastLine, a as interpolateShellCommands, b as resolveSubdirRoot, g as fetchInstallSource, h as defaultWhich, k as createSkillActivationState, m as defaultExec, n as resolveSkills, o as stripShellInterpolations, p as InstallSourceError, v as parseInstallSource, y as resolveNpmVersion } from "./skills-BC3dodWp.js";
13
13
  import { n as writeFileAtomicAsync, t as writeFileAtomic } from "./atomic-write-B7zr1ddF.js";
14
- import { p as resolveStorageDirs, r as loadAgentPlugin } from "./plugins-B531Tz5b.js";
14
+ import { p as resolveStorageDirs, r as loadAgentPlugin } from "./plugins-gbI7SBA6.js";
15
15
  import { r as createLogger, t as consoleSink } from "./logger--C1VQjwJ.js";
16
16
  import { t as escapeXml } from "./xml-D5HBhJle.js";
17
17
  import { n as reconcileImageMediaType } from "./media-sniff-UKijEaiQ.js";
18
18
  import { f as wrapDiscoveredMcpTools, i as deriveMcpToolMeta, n as connectMcpServers, s as nonOwningMcpView } from "./mcp-CgNd-f3F.js";
19
19
  import { appendStaticSection, renderSystemForWire } from "./prompt.js";
20
20
  import { a as detectTurnInterruption, c as ensureToolResultPairing, l as filterUnresolvedToolUses, m as resolveContentRefsInMessages, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, p as remintDuplicateToolCallIds, s as ensureEndsWithUserMessage } from "./messages-2jcOA_5R.js";
21
- import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-CVy-2mAy.js";
21
+ import { a as getExtensionSessionState, c as setExtensionSessionState, l as withExtensionSession, n as currentExtensionSession, r as deleteExtensionSessionState, s as resumeChainRunIds } from "./session-BqRP1hS7.js";
22
22
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
23
23
  import { a as settleWithinTimeout, i as resolveTimeoutMs, n as abortableSleep, o as withInactivityTimeout, r as linkAbortSignal, s as withTimeout$1, t as OperationTimeoutError } from "./timeout-CjOG2mea.js";
24
24
  import { createRequire } from "node:module";
@@ -26,9 +26,9 @@ import { basename, delimiter, dirname, isAbsolute, join, posix, resolve, sep } f
26
26
  import { createHooks } from "hookable";
27
27
  import { Buffer } from "node:buffer";
28
28
  import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, writeFileSync } from "node:fs";
29
+ import { homedir, tmpdir } from "node:os";
29
30
  import { copyFile, mkdir, readdir, rm, stat, unlink } from "node:fs/promises";
30
31
  import { pathToFileURL } from "node:url";
31
- import { homedir, tmpdir } from "node:os";
32
32
  import { createHash } from "node:crypto";
33
33
  import { AsyncLocalStorage } from "node:async_hooks";
34
34
  //#region src/tools/read-state.ts
@@ -3022,7 +3022,14 @@ const KEYBINDING_DEFS = [
3022
3022
  action: "cancelToolCall",
3023
3023
  default: "ctrl+k",
3024
3024
  label: "cancel tool",
3025
- description: "open the in-flight tool picker to cancel a single tool call without aborting the run (esc still aborts the whole run)",
3025
+ description: "open the in-flight tool picker to cancel a single tool call without aborting the run (abortRun stops the whole run)",
3026
+ group: "Global"
3027
+ },
3028
+ {
3029
+ action: "abortRun",
3030
+ default: "ctrl+escape",
3031
+ label: "abort",
3032
+ description: "abort the run and deny pending approvals (plain esc leaves for the sessions list; rebind if your terminal cannot report ctrl+esc)",
3026
3033
  group: "Global"
3027
3034
  },
3028
3035
  {
@@ -3423,7 +3430,9 @@ function resolveExtensionKeybindings(bindings, raw) {
3423
3430
  }
3424
3431
  /**
3425
3432
  * `true` when `spec` is one of the chords the framework reserves for
3426
- * itself — `escape` (abort / back / exit) and `ctrl+c` (quit). Extensions
3433
+ * itself — `escape` (back / exit), `ctrl+escape` (the `abortRun`
3434
+ * default — the one built-in that must never be shadowed) and `ctrl+c`
3435
+ * (quit). Extensions
3427
3436
  * can never claim these, neither via their declared `default` nor via a
3428
3437
  * user override in `keybindings.json`. Single source of truth shared by
3429
3438
  * `resolveExtensionKeybindings` above and the registration-time refusal
@@ -3433,7 +3442,7 @@ function isReservedExtensionBinding(spec) {
3433
3442
  const parsed = parseBindingSpec(spec);
3434
3443
  if (!parsed) return false;
3435
3444
  const noExtraModifiers = !parsed.shift && !parsed.alt && !parsed.meta;
3436
- if (parsed.name === "escape" && !parsed.ctrl && noExtraModifiers) return true;
3445
+ if (parsed.name === "escape" && noExtraModifiers) return true;
3437
3446
  return parsed.name === "c" && parsed.ctrl && noExtraModifiers;
3438
3447
  }
3439
3448
  /**
@@ -7140,11 +7149,19 @@ function applyToolSearchToUnlocked(catalog, input, unlocked, defaultLimit, addUn
7140
7149
  */
7141
7150
  function createToolSearchTool(options) {
7142
7151
  const defaultLimit = options.defaultLimit ?? DEFAULT_LIMIT;
7152
+ const dispatcher = options.dispatcherName;
7143
7153
  return {
7144
7154
  isConcurrencySafe: true,
7145
7155
  spec: {
7146
7156
  name: "tool_search",
7147
- description: "Discover and load schemas for additional tools listed in <searchable_tools>. Tools listed there are advertised by name + description only; their input schemas are not loaded into context until you surface them through this tool. Pass `query` for a substring search, `names` to load specific tools, or `server` to load every tool from one MCP server. Returned tools become callable for the rest of this run.",
7157
+ description: [
7158
+ "Discover and load schemas for additional tools listed in <searchable_tools>.",
7159
+ "Tools listed there are advertised by name + description only; their input",
7160
+ "schemas are not loaded into context until you surface them through this tool.",
7161
+ "Pass `query` for a substring search, `names` to load specific tools, or `server`",
7162
+ "to load every tool from one MCP server.",
7163
+ dispatcher ? `Returned tools become callable through \`${dispatcher}\` (name + arguments) for the rest of this run.` : "Returned tools become callable for the rest of this run."
7164
+ ].join(" "),
7148
7165
  inputSchema: {
7149
7166
  type: "object",
7150
7167
  properties: {
@@ -7186,7 +7203,7 @@ function createToolSearchTool(options) {
7186
7203
  else {
7187
7204
  for (const entry of shown) parts.push(formatMatch(entry));
7188
7205
  parts.push("");
7189
- parts.push(" These tools are now callable. Invoke them by name in subsequent turns.");
7206
+ parts.push(dispatcher ? ` These tools are now callable through \`${dispatcher}\`: pass the tool name as \`name\` and an object matching its schema as \`arguments\`.` : " These tools are now callable. Invoke them by name in subsequent turns.");
7190
7207
  if (truncated) parts.push(` ${total - shown.length} additional matches were truncated; refine the query or raise \`limit\`.`);
7191
7208
  }
7192
7209
  if (misses.length > 0) parts.push(` <misses>${misses.map(escapeXml).join(", ")}</misses>`);
@@ -11698,6 +11715,72 @@ function textForPersistence(output) {
11698
11715
  return parts.join("\n");
11699
11716
  }
11700
11717
  //#endregion
11718
+ //#region src/tools/call-tool.ts
11719
+ const CALL_TOOL_NAME = "call_tool";
11720
+ /**
11721
+ * Unwrap a `call_tool` envelope. `null` when `name` is not the dispatcher or
11722
+ * the envelope is malformed (missing / non-string `name`, non-object
11723
+ * `arguments`) — callers then treat the call as a plain `call_tool` call and
11724
+ * let the dispatcher's own schema validation produce the error the model
11725
+ * needs to fix its input.
11726
+ *
11727
+ * `arguments` may be omitted for zero-argument tools: it defaults to `{}`.
11728
+ */
11729
+ function unwrapCallTool(name, input) {
11730
+ if (name !== "call_tool") return null;
11731
+ if (!input || typeof input !== "object" || Array.isArray(input)) return null;
11732
+ const { name: inner, arguments: args } = input;
11733
+ if (typeof inner !== "string" || inner.length === 0) return null;
11734
+ if (args === void 0) return {
11735
+ name: inner,
11736
+ input: {}
11737
+ };
11738
+ if (!args || typeof args !== "object" || Array.isArray(args)) return null;
11739
+ return {
11740
+ name: inner,
11741
+ input: args
11742
+ };
11743
+ }
11744
+ /**
11745
+ * Build the dispatcher ToolDef. The loop rewrites every envelope around a
11746
+ * lazy catalog tool into the inner call before dispatch, so `execute` only
11747
+ * runs for envelopes it refused: an inner tool that is not a catalog entry
11748
+ * (eager tools are called directly, so their history stays scannable by
11749
+ * name) or a malformed shape that slipped past schema validation.
11750
+ */
11751
+ function createCallToolTool(options = {}) {
11752
+ const discovery = options.discoveryToolName ?? "tool_search";
11753
+ const isDispatchable = options.isDispatchable ?? (() => true);
11754
+ return {
11755
+ isConcurrencySafe: false,
11756
+ spec: {
11757
+ name: CALL_TOOL_NAME,
11758
+ description: `Invoke a tool listed in <searchable_tools>. Load its schema with \`${discovery}\` first (the result shows the exact \`name\` and input schema), then call it here with \`name\` set to that tool name and \`arguments\` set to an object matching its schema. Arguments are validated against the tool's own schema; a validation error names the offending field.`,
11759
+ inputSchema: {
11760
+ type: "object",
11761
+ properties: {
11762
+ name: {
11763
+ type: "string",
11764
+ description: "Tool name exactly as shown in <searchable_tools> / the tool_search result."
11765
+ },
11766
+ arguments: {
11767
+ type: "object",
11768
+ description: "Input for the tool, matching its schema. Omit for zero-argument tools.",
11769
+ additionalProperties: true
11770
+ }
11771
+ },
11772
+ required: ["name"],
11773
+ additionalProperties: false
11774
+ }
11775
+ },
11776
+ async execute(input) {
11777
+ const target = input.name;
11778
+ if (typeof target === "string" && target.length > 0 && !isDispatchable(target)) throw new Error(`call_tool: "${target}" is not listed in <searchable_tools>. Call it directly by name if it is one of your tools; call_tool is only for surfaced catalog tools.`);
11779
+ throw new Error(`call_tool: malformed envelope for ${typeof target === "string" ? `"${target}"` : "unknown tool"}: expected \`name\` (string) and optional \`arguments\` (object).`);
11780
+ }
11781
+ };
11782
+ }
11783
+ //#endregion
11701
11784
  //#region src/loop.ts
11702
11785
  const DEFAULT_PROVIDER_STREAM_START_TIMEOUT_MS = 300 * 1e3;
11703
11786
  const DEFAULT_PROVIDER_STREAM_TIMEOUT_MS = 1800 * 1e3;
@@ -11899,8 +11982,12 @@ function executionBlobWriter(ctx) {
11899
11982
  * the per-turn `turnId` tags that the TUI's select-turn mode relies on.
11900
11983
  *
11901
11984
  * Pure: a fresh array is returned only when a marker is found. Input
11902
- * turns are never mutated; the synthetic markers are the only new
11903
- * `SessionTurn`s allocated.
11985
+ * turns are never mutated. New `SessionTurn`s allocated: the synthetic
11986
+ * markers, plus a copy of every preserved assistant turn older than the
11987
+ * newest marker whose replayable thinking was stripped (see
11988
+ * {@link withoutReplayedThinking}). The output is WIRE-shaped, not
11989
+ * display-shaped: hosts rendering a transcript should read the session
11990
+ * turns, not this view.
11904
11991
  */
11905
11992
  /**
11906
11993
  * Recover the auto-compaction hysteresis baseline from a resumed session.
@@ -11962,17 +12049,68 @@ function applyCompactSummaryCutoff(turns) {
11962
12049
  ...m.turn.runId ? { runId: m.turn.runId } : {}
11963
12050
  });
11964
12051
  }
12052
+ const newestMarkerIdx = markers[markers.length - 1].idx;
12053
+ const stripBound = preservedChainStart(turns, newestMarkerIdx);
11965
12054
  const out = [];
11966
12055
  for (let i = 0; i < turns.length; i++) {
11967
12056
  const synthetic = syntheticAt.get(i);
11968
12057
  if (synthetic) out.push(synthetic);
11969
12058
  if (markerIdxSet.has(i)) continue;
11970
12059
  if (replacedAll.has(turns[i].id)) continue;
11971
- out.push(turns[i]);
12060
+ out.push(i < stripBound ? withoutReplayedThinking(turns[i]) : turns[i]);
11972
12061
  }
11973
12062
  return out;
11974
12063
  }
11975
12064
  /**
12065
+ * Strip bound for the preserved tail behind the marker at `markerIdx`: the
12066
+ * index below which pre-marker assistant turns lose their replayed thinking.
12067
+ *
12068
+ * Reads the turn immediately before the marker to tell whether a tool loop
12069
+ * was in flight when compaction fired. A `tool_result`-only user turn (or an
12070
+ * assistant turn still holding a `tool_call`) means the marker landed mid
12071
+ * loop: the bound retreats to that chain's start — the last user turn before
12072
+ * the marker carrying real, non-`tool_result` content (`compact-summary`
12073
+ * turns render as user text but are not prompts) — so the assistant turn
12074
+ * whose `tool_use` the loop is still answering keeps its thinking. Any other
12075
+ * neighbour (a text-only assistant answer, a bare prompt) means the run had
12076
+ * settled and everything before the marker is strippable. Depends only on
12077
+ * turns before the marker, so it is stable across later requests.
12078
+ */
12079
+ function preservedChainStart(turns, markerIdx) {
12080
+ const before = turns[markerIdx - 1];
12081
+ if (!(before !== void 0 && (before.role === "user" && before.content.length > 0 && before.content.every((block) => block.type === "tool_result") || before.role === "assistant" && before.content.some((block) => block.type === "tool_call")))) return markerIdx;
12082
+ for (let i = markerIdx - 1; i >= 0; i--) {
12083
+ const turn = turns[i];
12084
+ if (turn.role !== "user") continue;
12085
+ if (turn.content.some((block) => block.type === "compact-summary")) continue;
12086
+ if (turn.content.some((block) => block.type !== "tool_result")) return i;
12087
+ }
12088
+ return markerIdx;
12089
+ }
12090
+ /**
12091
+ * Copy of `turn` with prefix-bound reasoning removed: `redacted_thinking`,
12092
+ * and SIGNED `thinking` blocks not produced by an OpenAI-family provider
12093
+ * (whose encrypted reasoning is bound per item, not per prefix). Unsigned
12094
+ * thinking is left alone — it is what `reasoning_content`-style OpenAI-compat
12095
+ * providers (vLLM, DeepSeek, Arcee) echo back, and `toAnthropic` already
12096
+ * drops it on the Anthropic wire. Same predicate as the provider's
12097
+ * signature scrub. Returns the input object when nothing is removed so
12098
+ * identity-based callers see no churn. A reasoning-only turn keeps a
12099
+ * placeholder so the assistant message stays non-empty on the wire.
12100
+ */
12101
+ function withoutReplayedThinking(turn) {
12102
+ if (turn.role !== "assistant") return turn;
12103
+ const kept = turn.content.filter((block) => block.type !== "redacted_thinking" && !(block.type === "thinking" && !!block.signature && block.signatureProducer !== "openai"));
12104
+ if (kept.length === turn.content.length) return turn;
12105
+ return {
12106
+ ...turn,
12107
+ content: kept.length > 0 ? kept : [{
12108
+ type: "text",
12109
+ text: "[historical reasoning omitted]"
12110
+ }]
12111
+ };
12112
+ }
12113
+ /**
11976
12114
  * Flatten image blocks inside previously-stored `tool_result` outputs to text
11977
12115
  * markers when the provider reports no vision capability. This handles the
11978
12116
  * session-resume / mid-session-provider-switch case:
@@ -11990,6 +12128,56 @@ function applyCompactSummaryCutoff(turns) {
11990
12128
  */
11991
12129
  const COMPACTION_STUB = "[…elided: older tool output trimmed to fit the context budget.]";
11992
12130
  const COMPACTION_STUB_BYTES = toolOutputByteLength(COMPACTION_STUB);
12131
+ /** Byte threshold tail compaction falls back to when `compactThreshold` is unset. */
12132
+ const DEFAULT_COMPACT_THRESHOLD_BYTES = 131072;
12133
+ /**
12134
+ * Effective byte threshold for client-side compaction (`'tail'` and the
12135
+ * `CompactFunction` path): the host's `compactThreshold` (default 128 KiB),
12136
+ * raised to `compactThresholdWindowFraction × contextWindow × BYTES_PER_TOKEN`
12137
+ * when both are known. Every frontier step re-bills the whole suffix at the
12138
+ * cache-write rate, so on large-context models the byte threshold alone
12139
+ * trips far too early; see `AgentBehavior.compactThresholdWindowFraction`.
12140
+ * Pure — exported for host-behavior tests.
12141
+ */
12142
+ function resolveTailCompactionThreshold(behavior, contextWindow) {
12143
+ const base = typeof behavior.compactThreshold === "number" && behavior.compactThreshold > 0 ? behavior.compactThreshold : DEFAULT_COMPACT_THRESHOLD_BYTES;
12144
+ const fraction = behavior.compactThresholdWindowFraction;
12145
+ if (typeof fraction !== "number" || !(fraction > 0) || typeof contextWindow !== "number" || !(contextWindow > 0)) return base;
12146
+ return Math.max(base, Math.floor(fraction * contextWindow * 4));
12147
+ }
12148
+ /**
12149
+ * Context window (tokens) of the model currently serving the run, for
12150
+ * window-relative wire budgets.
12151
+ *
12152
+ * On the primary target the host's explicit `behavior.contextWindow` (chat
12153
+ * hosts inject the picked model's window every run) wins, then the resolved
12154
+ * autocompact window, the primary {@link ModelTarget}'s window, and the
12155
+ * provider's advertised `meta.contextWindow`. Once the run has advanced down
12156
+ * the fallback chain, `behavior.contextWindow` describes the model that just
12157
+ * FAILED (1M Fable → 200k Sonnet is the realistic shape), so the active
12158
+ * target's own window and the re-based autocompact window take precedence
12159
+ * and the stale behavior value is only a last resort before provider meta.
12160
+ * `null` when nothing knows.
12161
+ */
12162
+ function activeContextWindow(ctx) {
12163
+ const positive = (n) => typeof n === "number" && n > 0 ? n : null;
12164
+ const advanced = (ctx.activeTargetIndex ?? 0) > 0;
12165
+ const target = ctx.targets?.[ctx.activeTargetIndex ?? 0];
12166
+ const ordered = advanced ? [
12167
+ target?.contextWindow,
12168
+ ctx.autoCompact?.contextWindow,
12169
+ ctx.behavior.contextWindow
12170
+ ] : [
12171
+ ctx.behavior.contextWindow,
12172
+ ctx.autoCompact?.contextWindow,
12173
+ target?.contextWindow
12174
+ ];
12175
+ for (const candidate of ordered) {
12176
+ const n = positive(candidate);
12177
+ if (n !== null) return n;
12178
+ }
12179
+ return positive(ctx.provider.meta.contextWindow);
12180
+ }
11993
12181
  /**
11994
12182
  * Cross-turn memo for `toolOutputBudgetByteLength`, keyed on the tool_result
11995
12183
  * block object. The wire pipeline preserves block references for unchanged
@@ -12873,7 +13061,7 @@ async function enforceSchemaOutput(ctx, turnId) {
12873
13061
  description: "Return the final structured output matching the required schema.",
12874
13062
  inputSchema: ctx.behavior.schema
12875
13063
  };
12876
- const schemaMessages = ensureEndsWithUserMessage(applyPairingRepair(ctx, rewriteMessagesToWire(await resolveContentRefsForWire(ctx, turnsToMessages(applyCompactSummaryCutoff(ctx.turns))), ctx.aliasMaps), turnId), ctx.provider);
13064
+ const schemaMessages = ensureEndsWithUserMessage(applyPairingRepair(ctx, rewriteMessagesToWire(await resolveContentRefsForWire(ctx, turnsToMessages(applyCompactSummaryCutoff(ctx.turns)).map(withoutReplayedThinking)), ctx.aliasMaps), turnId), ctx.provider);
12877
13065
  let schemaResult;
12878
13066
  try {
12879
13067
  schemaResult = await streamWithWatchdogs(ctx, {
@@ -13097,6 +13285,7 @@ async function streamWithWatchdogs(ctx, options, callbacks, turnId, opts) {
13097
13285
  if (opts?.startTimeoutCapMs !== void 0 && startTimeoutMs > 0) startTimeoutMs = Math.min(startTimeoutMs, opts.startTimeoutCapMs);
13098
13286
  const callerHistoryRepair = callbacks.onHistoryRepair;
13099
13287
  let pendingRepair;
13288
+ const callerInputTransformations = callbacks.onInputTransformations;
13100
13289
  callbacks = {
13101
13290
  ...callbacks,
13102
13291
  onDiagnostic(event) {
@@ -13106,6 +13295,20 @@ async function streamWithWatchdogs(ctx, options, callbacks, turnId, opts) {
13106
13295
  turnId
13107
13296
  })).catch(() => {});
13108
13297
  },
13298
+ onInputTransformations(transformations) {
13299
+ try {
13300
+ callerInputTransformations?.(transformations);
13301
+ } catch {}
13302
+ const info = {
13303
+ runId: ctx.runId,
13304
+ turnId,
13305
+ ...ctx.session?.id ? { sessionId: ctx.session.id } : {},
13306
+ transformations,
13307
+ prefixMismatches: transformations.filter((t) => t.reason === "prefix_binding_mismatch").length,
13308
+ modelMismatches: transformations.filter((t) => t.reason === "model_binding_mismatch").length
13309
+ };
13310
+ Promise.resolve(ctx.hooks.callHook("provider:input-transformations", info)).catch(() => {});
13311
+ },
13109
13312
  async onHistoryRepair(repair) {
13110
13313
  if (repair.type === "invalid-anthropic-thinking-signature") {
13111
13314
  const result = repairInvalidAnthropicThinkingHistory(ctx, options, repair);
@@ -13601,7 +13804,7 @@ async function executeTurn(ctx, turn, priorUsage) {
13601
13804
  let callMapsMemo;
13602
13805
  const callMaps = () => callMapsMemo ??= collectCallMaps(canonicalMessages);
13603
13806
  if (ctx.behavior.compactStrategy === "tail") {
13604
- const threshold = typeof ctx.behavior.compactThreshold === "number" && ctx.behavior.compactThreshold > 0 ? ctx.behavior.compactThreshold : 131072;
13807
+ const threshold = resolveTailCompactionThreshold(ctx.behavior, activeContextWindow(ctx));
13605
13808
  const keep = typeof ctx.behavior.compactKeepTurns === "number" && ctx.behavior.compactKeepTurns >= 0 ? ctx.behavior.compactKeepTurns : 4;
13606
13809
  const { readPathByCallId, toolNameByCallId } = callMaps();
13607
13810
  const compacted = applyTailCompaction(sanitizedMessages, threshold, keep, {
@@ -13618,7 +13821,7 @@ async function executeTurn(ctx, turn, priorUsage) {
13618
13821
  writeBlob: executionBlobWriter(ctx)
13619
13822
  });
13620
13823
  } else if (typeof ctx.behavior.compactStrategy === "function") {
13621
- const threshold = typeof ctx.behavior.compactThreshold === "number" && ctx.behavior.compactThreshold > 0 ? ctx.behavior.compactThreshold : 131072;
13824
+ const threshold = resolveTailCompactionThreshold(ctx.behavior, activeContextWindow(ctx));
13622
13825
  const keep = typeof ctx.behavior.compactKeepTurns === "number" && ctx.behavior.compactKeepTurns >= 0 ? ctx.behavior.compactKeepTurns : 4;
13623
13826
  let totalBytes = 0;
13624
13827
  for (const msg of sanitizedMessages) for (const block of msg.content) if (block.type === "tool_result") totalBytes += memoizedToolResultBudgetBytes(block);
@@ -13989,6 +14192,7 @@ async function executeTurn(ctx, turn, priorUsage) {
13989
14192
  })).catch(() => {});
13990
14193
  }
13991
14194
  }
14195
+ canonicalToolCalls = unwrapDispatchCalls(ctx, canonicalToolCalls);
13992
14196
  if (turnTtftMs !== void 0 && result.usage.timeToFirstTokenMs === void 0) result.usage.timeToFirstTokenMs = turnTtftMs;
13993
14197
  if (result.usage.streamDurationMs === void 0) result.usage.streamDurationMs = Date.now() - streamStartedAt;
13994
14198
  const assistantTurn = {
@@ -14290,6 +14494,31 @@ async function commitToolState(ctx, callId, toolName) {
14290
14494
  if (!hookCtx.handled) console.error(`[zidane] tool state commit for ${toolName} (${callId}) failed; the write did NOT land, continuing:`, error);
14291
14495
  }
14292
14496
  }
14497
+ /**
14498
+ * Rewrite every well-formed `call_tool` envelope around a lazy catalog tool
14499
+ * into the inner call it carries (same `id`, inner wire name → canonical,
14500
+ * `arguments` → `input`). No-op unless the run is in dispatch mode
14501
+ * ({@link LoopContext.dispatcher}). Left as a `call_tool` call, so the
14502
+ * dispatcher itself answers: a malformed envelope (its schema validation
14503
+ * reports the shape error) and an inner name outside the catalog (its
14504
+ * `execute` says to call the tool directly, or that it does not exist).
14505
+ */
14506
+ function unwrapDispatchCalls(ctx, calls) {
14507
+ const dispatcher = ctx.dispatcher;
14508
+ if (!dispatcher) return calls.slice();
14509
+ return calls.map((call) => {
14510
+ if (call.name !== dispatcher.name) return call;
14511
+ const inner = unwrapCallTool(call.name, call.input);
14512
+ if (!inner) return call;
14513
+ const canonical = toCanonicalName(inner.name, ctx.aliasMaps);
14514
+ if (!dispatcher.targets.has(canonical)) return call;
14515
+ return {
14516
+ ...call,
14517
+ name: canonical,
14518
+ input: inner.input
14519
+ };
14520
+ });
14521
+ }
14293
14522
  async function executeSingleTool(ctx, call, turnId) {
14294
14523
  const toolDef = ctx.tools[call.name];
14295
14524
  const callId = call.id;
@@ -15908,6 +16137,7 @@ const HOOK_EVENT_SET = /* @__PURE__ */ new Set([
15908
16137
  "compact:progress",
15909
16138
  "compact:end",
15910
16139
  "history:repair",
16140
+ "provider:input-transformations",
15911
16141
  "oauth:refresh",
15912
16142
  "provider:diagnostic",
15913
16143
  "content-ref:resolve",
@@ -16090,6 +16320,8 @@ function resolveBehavior(agentBehavior, runBehavior) {
16090
16320
  readFileDefaults: runBehavior?.readFileDefaults ?? agentBehavior?.readFileDefaults,
16091
16321
  compactStrategy: runBehavior?.compactStrategy ?? agentBehavior?.compactStrategy ?? "off",
16092
16322
  compactThreshold: runBehavior?.compactThreshold ?? agentBehavior?.compactThreshold,
16323
+ compactThresholdWindowFraction: runBehavior?.compactThresholdWindowFraction ?? agentBehavior?.compactThresholdWindowFraction,
16324
+ contextWindow: runBehavior?.contextWindow ?? agentBehavior?.contextWindow,
16093
16325
  compactKeepTurns: runBehavior?.compactKeepTurns ?? agentBehavior?.compactKeepTurns,
16094
16326
  thinkingDecay: runBehavior?.thinkingDecay ?? agentBehavior?.thinkingDecay,
16095
16327
  writeFileExistingPolicy: runBehavior?.writeFileExistingPolicy ?? agentBehavior?.writeFileExistingPolicy,
@@ -16318,6 +16550,16 @@ function buildMcpToolNameSeparatorAliases(mcpToolNames, servers, separator) {
16318
16550
  return Object.keys(aliases).length > 0 ? aliases : void 0;
16319
16551
  }
16320
16552
  /**
16553
+ * Resolve the effective `toolSearch.mode`. An explicit host value always
16554
+ * wins. When unset, Anthropic-family providers default to `'dispatch'`
16555
+ * (see {@link DisclosureStateInput.providerName}); everyone else keeps
16556
+ * `'unlock'`, whose only cost there is a prompt-cache rewrite per wave.
16557
+ */
16558
+ function resolveToolSearchMode(toolSearch, providerName) {
16559
+ if (toolSearch?.mode !== void 0) return toolSearch.mode;
16560
+ return providerName === "anthropic" ? "dispatch" : "unlock";
16561
+ }
16562
+ /**
16321
16563
  * Partition the registry into eager vs lazy buckets and build the per-run
16322
16564
  * unlock bookkeeping the loop reads when rebuilding the wire-level tool list.
16323
16565
  *
@@ -16332,7 +16574,8 @@ function buildMcpToolNameSeparatorAliases(mcpToolNames, servers, separator) {
16332
16574
  * dispatch-map lookup.
16333
16575
  */
16334
16576
  function buildRunDisclosureState(input) {
16335
- const { tools: baseTools, mcpToolNames, mcpServers, toolDisclosure, toolSearch, toolAliases, hasRunToolOverride } = input;
16577
+ const { tools: baseTools, mcpToolNames, mcpServers, toolDisclosure, toolSearch, toolAliases, hasRunToolOverride, providerName } = input;
16578
+ const toolSearchMode = resolveToolSearchMode(toolSearch, providerName);
16336
16579
  const disclosure = partitionToolDisclosure(baseTools, mcpToolNames, mcpServers, toolDisclosure, toolAliases);
16337
16580
  const unlocked = new Set(disclosure.eagerCanonicalNames);
16338
16581
  const initialUnlocked = new Set(disclosure.eagerCanonicalNames);
@@ -16347,13 +16590,15 @@ function buildRunDisclosureState(input) {
16347
16590
  };
16348
16591
  const hostDefinedToolSearch = !!baseTools.tool_search;
16349
16592
  const injectedToolSearch = !hasRunToolOverride && (toolDisclosure === "lazy" || disclosure.lazyEntries.length > 0) && toolSearch?.tool !== false && !hostDefinedToolSearch;
16593
+ const dispatchMode = injectedToolSearch && toolSearchMode === "dispatch" && disclosure.lazyEntries.length > 0 && !baseTools["call_tool"];
16350
16594
  let tools = baseTools;
16351
16595
  if (injectedToolSearch) {
16352
16596
  const toolSearchTool = createToolSearchTool({
16353
16597
  catalog: disclosure.lazyEntries,
16354
16598
  unlocked,
16355
16599
  addUnlock: recordUnlock,
16356
- ...toolSearch?.limit !== void 0 ? { defaultLimit: toolSearch.limit } : {}
16600
+ ...toolSearch?.limit !== void 0 ? { defaultLimit: toolSearch.limit } : {},
16601
+ ...dispatchMode ? { dispatcherName: CALL_TOOL_NAME } : {}
16357
16602
  });
16358
16603
  tools = {
16359
16604
  ...baseTools,
@@ -16361,6 +16606,19 @@ function buildRunDisclosureState(input) {
16361
16606
  };
16362
16607
  unlocked.add(toolSearchTool.spec.name);
16363
16608
  initialUnlocked.add(toolSearchTool.spec.name);
16609
+ if (dispatchMode) {
16610
+ const lazyWireNames = new Set(disclosure.lazyEntries.map((entry) => entry.name));
16611
+ const callTool = createCallToolTool({
16612
+ discoveryToolName: toolSearchTool.spec.name,
16613
+ isDispatchable: (name) => lazyWireNames.has(name)
16614
+ });
16615
+ tools = {
16616
+ ...tools,
16617
+ [CALL_TOOL_NAME]: callTool
16618
+ };
16619
+ unlocked.add(CALL_TOOL_NAME);
16620
+ initialUnlocked.add(CALL_TOOL_NAME);
16621
+ }
16364
16622
  }
16365
16623
  return {
16366
16624
  disclosure,
@@ -16370,7 +16628,8 @@ function buildRunDisclosureState(input) {
16370
16628
  recordUnlock,
16371
16629
  tools,
16372
16630
  injectedToolSearch,
16373
- hostDefinedToolSearch
16631
+ hostDefinedToolSearch,
16632
+ dispatchMode
16374
16633
  };
16375
16634
  }
16376
16635
  /**
@@ -16631,7 +16890,11 @@ function buildSearchableCatalog(entries, options) {
16631
16890
  }
16632
16891
  const serverNames = [...byServer.keys()].sort();
16633
16892
  const parts = [];
16634
- if (options.discoveryToolName) parts.push("The following tools are available but their input schemas are NOT loaded in your context.", `Call the \`${options.discoveryToolName}\` tool to load schemas for any tool below that you have not already surfaced. Surfaced tools persist for the rest of the run.`, "");
16893
+ if (options.discoveryToolName) {
16894
+ parts.push("The following tools are available but their input schemas are NOT loaded in your context.", `Call the \`${options.discoveryToolName}\` tool to load schemas for any tool below that you have not already surfaced. Surfaced tools persist for the rest of the run.`);
16895
+ if (options.dispatcherName) parts.push(`Surfaced tools are invoked through \`${options.dispatcherName}\` with \`name\` set to the tool name and \`arguments\` matching the loaded schema; they are never added to your tool list directly.`);
16896
+ parts.push("");
16897
+ }
16635
16898
  parts.push("<searchable_tools>");
16636
16899
  for (const server of serverNames) {
16637
16900
  parts.push(` <server name="${escapeXml(server)}">`);
@@ -16655,14 +16918,15 @@ function buildSearchableCatalog(entries, options) {
16655
16918
  * Returns an uninstall function the run-end teardown calls so handlers
16656
16919
  * never leak across runs.
16657
16920
  */
16658
- function installLazyDisclosureGate(hooks, lazyCanonicalNames, unlocked, discoveryToolName) {
16921
+ function installLazyDisclosureGate(hooks, lazyCanonicalNames, unlocked, discoveryToolName, dispatcherName) {
16659
16922
  if (lazyCanonicalNames.size === 0) return () => {};
16660
16923
  return hooks.hook("tool:gate", (ctx) => {
16661
16924
  if (ctx.block) return;
16662
16925
  if (!lazyCanonicalNames.has(ctx.name)) return;
16663
16926
  if (unlocked.has(ctx.name)) return;
16664
16927
  ctx.block = true;
16665
- ctx.reason = discoveryToolName ? `Tool "${ctx.name}" is listed in <searchable_tools> but its schema has not been loaded. Call the \`${discoveryToolName}\` tool with names: ["${ctx.name}"] first, then re-issue the call.` : `Tool "${ctx.name}" is listed in <searchable_tools> but its schema has not been loaded.`;
16928
+ const reissue = dispatcherName ? `re-issue the call through \`${dispatcherName}\`` : "re-issue the call";
16929
+ ctx.reason = discoveryToolName ? `Tool "${ctx.name}" is listed in <searchable_tools> but its schema has not been loaded. Call the \`${discoveryToolName}\` tool with names: ["${ctx.name}"] first, then ${reissue}.` : `Tool "${ctx.name}" is listed in <searchable_tools> but its schema has not been loaded.`;
16666
16930
  });
16667
16931
  }
16668
16932
  /**
@@ -17267,19 +17531,23 @@ function createAgent(rawOptions) {
17267
17531
  executionContext,
17268
17532
  behavior: resolvedBehavior
17269
17533
  });
17270
- const { disclosure, unlocked, initialUnlocked, dynamicUnlockOrder, recordUnlock: recordDynamicUnlock, tools, injectedToolSearch: shouldInjectToolSearch, hostDefinedToolSearch } = buildRunDisclosureState({
17534
+ const { disclosure, unlocked, initialUnlocked, dynamicUnlockOrder, recordUnlock: recordDynamicUnlock, tools, injectedToolSearch: shouldInjectToolSearch, hostDefinedToolSearch, dispatchMode } = buildRunDisclosureState({
17271
17535
  tools: toolsPreSearch,
17272
17536
  mcpToolNames,
17273
17537
  mcpServers,
17274
17538
  toolDisclosure,
17275
17539
  toolSearch,
17276
17540
  toolAliases: effectiveToolAliases,
17277
- hasRunToolOverride: options.tools !== void 0
17541
+ hasRunToolOverride: options.tools !== void 0,
17542
+ providerName: runProvider.name
17278
17543
  });
17279
17544
  const discoveryToolName = shouldInjectToolSearch ? "tool_search" : hostDefinedToolSearch ? effectiveToolAliases?.tool_search ?? "tool_search" : null;
17280
17545
  let searchableCatalogText;
17281
17546
  if (disclosure.lazyEntries.length > 0) {
17282
- searchableCatalogText = buildSearchableCatalog(disclosure.lazyEntries, { discoveryToolName });
17547
+ searchableCatalogText = buildSearchableCatalog(disclosure.lazyEntries, {
17548
+ discoveryToolName,
17549
+ ...dispatchMode ? { dispatcherName: CALL_TOOL_NAME } : {}
17550
+ });
17283
17551
  system = appendStaticSection(system, searchableCatalogText);
17284
17552
  }
17285
17553
  if (surfaceMcpInstructions && mcpConnection?.instructions && mcpConnection.instructions.size > 0) {
@@ -17288,10 +17556,11 @@ function createAgent(rawOptions) {
17288
17556
  }
17289
17557
  const aliasMaps = buildAliasMaps(effectiveToolAliases, Object.keys(tools));
17290
17558
  augmentMcpDoubleUnderscoreAliases(aliasMaps, Object.keys(tools));
17559
+ const wireTailLength = () => dispatchMode ? 0 : dynamicUnlockOrder.length;
17291
17560
  const formattedToolsCache = /* @__PURE__ */ new Map();
17292
17561
  function buildFormattedTools(forProvider = runProvider) {
17293
17562
  const cached = formattedToolsCache.get(forProvider);
17294
- if (cached && cached.tailLen === dynamicUnlockOrder.length) return cached.value;
17563
+ if (cached && cached.tailLen === wireTailLength()) return cached.value;
17295
17564
  const specs = [];
17296
17565
  for (const t of Object.values(tools)) {
17297
17566
  if (!initialUnlocked.has(t.spec.name)) continue;
@@ -17301,7 +17570,7 @@ function createAgent(rawOptions) {
17301
17570
  inputSchema: t.spec.inputSchema
17302
17571
  });
17303
17572
  }
17304
- for (const canonical of dynamicUnlockOrder) {
17573
+ for (const canonical of dispatchMode ? [] : dynamicUnlockOrder) {
17305
17574
  const t = tools[canonical];
17306
17575
  if (!t) continue;
17307
17576
  specs.push({
@@ -17312,7 +17581,7 @@ function createAgent(rawOptions) {
17312
17581
  }
17313
17582
  const value = specs.length > 0 ? forProvider.formatTools(specs) : [];
17314
17583
  formattedToolsCache.set(forProvider, {
17315
- tailLen: dynamicUnlockOrder.length,
17584
+ tailLen: wireTailLength(),
17316
17585
  value
17317
17586
  });
17318
17587
  return value;
@@ -17321,13 +17590,14 @@ function createAgent(rawOptions) {
17321
17590
  function advertisedToolNames() {
17322
17591
  const names = [];
17323
17592
  for (const t of Object.values(tools)) if (initialUnlocked.has(t.spec.name)) names.push(toWireName(t.spec.name, aliasMaps));
17324
- for (const canonical of dynamicUnlockOrder) if (tools[canonical]) names.push(toWireName(canonical, aliasMaps));
17593
+ for (const canonical of dispatchMode ? [] : dynamicUnlockOrder) if (tools[canonical]) names.push(toWireName(canonical, aliasMaps));
17325
17594
  return names;
17326
17595
  }
17327
17596
  {
17328
17597
  const disclosedTools = [];
17598
+ const onWire = dispatchMode ? initialUnlocked : unlocked;
17329
17599
  for (const t of Object.values(tools)) {
17330
- if (!unlocked.has(t.spec.name)) continue;
17600
+ if (!onWire.has(t.spec.name)) continue;
17331
17601
  const wireName = aliasMaps.aliasByCanonical.get(t.spec.name) ?? t.spec.name;
17332
17602
  disclosedTools.push({
17333
17603
  name: wireName,
@@ -17512,7 +17782,7 @@ function createAgent(rawOptions) {
17512
17782
  recordUnlock: recordDynamicUnlock,
17513
17783
  defaultLimit: toolSearch?.limit
17514
17784
  }));
17515
- perRunUnregisters.push(installLazyDisclosureGate(hooks, disclosure.lazyCanonicalNames, unlocked, discoveryToolName));
17785
+ perRunUnregisters.push(installLazyDisclosureGate(hooks, disclosure.lazyCanonicalNames, unlocked, discoveryToolName, dispatchMode ? CALL_TOOL_NAME : void 0));
17516
17786
  perRunUnregisters.push(installReadBeforeEditHydrationGate(hooks, resolvedBehavior.requireReadBeforeEdit === true, {
17517
17787
  session: session ?? void 0,
17518
17788
  getHandle: () => executionHandle,
@@ -17642,6 +17912,10 @@ function createAgent(rawOptions) {
17642
17912
  tools,
17643
17913
  formattedTools,
17644
17914
  rebuildFormattedTools: buildFormattedTools,
17915
+ ...dispatchMode ? { dispatcher: {
17916
+ name: CALL_TOOL_NAME,
17917
+ targets: disclosure.lazyCanonicalNames
17918
+ } } : {},
17645
17919
  aliasMaps,
17646
17920
  model,
17647
17921
  system,
@@ -18196,6 +18470,6 @@ function createAgent(rawOptions) {
18196
18470
  };
18197
18471
  }
18198
18472
  //#endregion
18199
- export { installExtensionFromSpec as $, defaultRepeatGuardNormalize as $n, KEYBINDING_DEF_BY_ACTION as $t, selectFilesFromSession as A, resolveExtensionConfig as An, createSkillsRunScriptTool as At, buildUpToCompactPrompt as B, commitKind as Bn, formatModelLine as Bt, resolveLegacySessionDir as C, createDebugLog as Cn, WAIT_TASK_TIMED_OUT_PREFIX as Ct, resolveTasksDir as D, coerceExtensionConfigInput as Dn, isSpawnTool as Dt, resolveSessionDir as E, clampExtensionConfigNumber as En, createSpawnTool as Et, TRAILER as F, createExtensionBus as Fn, tailTruncate as Ft, summaryToTurn as G, refreshArtifact as Gn, glob as Gt, anchorPreviewFor as H, githubTokenSource as Hn, listFiles as Ht, buildCompactPrompt as I, serializedPayloadBytes as In, readFile$1 as It, CompactPromptTooLongError as J, createArtifactDetectHook as Jn, artifacts_default as Jt, truncateHeadForPtlRetry as K, renderArtifactRow as Kn, edit as Kt, buildFromCompactPrompt as L, BUILTIN_ARTIFACT_KINDS as Ln, looksBinary as Lt, compactConversation as M, sanitizeExtensionConfigActionPatch as Mn, shellKill as Mt, BASE_INSTRUCTIONS as N, toWireConfigSchema as Nn, createShellTool as Nt, buildPostCompactAttachments as O, isValidExtensionConfigItem as On, reserveChildLabel as Ot, NO_TOOLS_PREAMBLE as P, EXTENSION_BUS_MAX_PAYLOAD_BYTES as Pn, shell as Pt, fetchExtensionSource as Q, shouldAutoCompact as Qn, KEYBINDING_DEFS as Qt, buildFullCompactPrompt as R, artifactKindLabel as Rn, multiEdit as Rt, resolveLegacyPersistDir as S, scanExtensionDirectories as Sn, writeFile$1 as St, resolvePersistDir as T, defineExtension as Tn, createToolSearchTool as Tt, sliceForCompaction as U, parseShortstat as Un, createInteractionTool as Ut, ANCHOR_PREVIEW_MAX_CHARS as V, fileKind as Vn, matchModelEntries as Vt, stripImagesFromTurns as W, pullRequestKind as Wn, grep as Wt, createExtensionPromptBridge as X, OUTPUT_RESERVE_TOKENS as Xn, recordArtifact as Xt, EMPTY_EXTENSION_REGISTRY as Y, AUTO_COMPACT_MIN_GROWTH_FRACTION as Yn, RECORD_ARTIFACT_TOOL as Yt, ExtensionInstallError as Z, effectiveContextWindow as Zn, DEFAULT_KEYBINDINGS as Zt, buildPersistedStub as _, defaultExtensionScanPaths as _n, createWorkspaceSurface as _t, stagedToolState as a, matchesBinding as an, hydrateReadStateFromSession as ar, createExtensionHud as at, migrateSessionArtifactDirs as b, isExtensionDefinition as bn, basicTools as bt, INTERRUPT_MESSAGE_FOR_TOOL_USE as c, readKeybindings as cn, resolveReadStateMap as cr, buildExtensionRegistry as ct, TOOL_USE_SKIPPED_MESSAGE as d, stripJsonComments as dn, filterExtensionRegistry as dt, KEYBINDING_KEY_COL_WIDTH as en, defaultRepeatGuardTracked as er, listExtensionCandidates as et, applyCompactSummaryCutoff as f, ALTERNATE_CRED_KEY_SUFFIX as fn, filterRegistryPlugins as ft, PERSISTENCE_PREVIEW_BYTES as g, ENTRY_CANDIDATES as gn, createExtensionHostRuntimeBridge as gt, PERSISTED_STUB_PREFIX as h, registerExtensionHostModules as hn, createArtifactsSurface as ht, isToolStateOps as i, keybindingsPath as in, hashContent as ir, updateInstalledExtension as it, selectRecentFiles as j, resolveExtensionConfigValue as jn, createSkillsReadTool as jt, selectFilesFromReadState as k, isValidExtensionConfigValue as kn, createSkillsUseTool as kt, SHELL_CASCADE_CANCEL_MESSAGE as l, readKeybindingsRaw as ln, composeExtensionPreset as lt, renderStaleReadNotice as m, isReservedCredKey as mn, partitionExtensionCatalog as mt, DEFAULT_MAX_VALUE_BYTES as n, formatBindingForDisplay as nn, stableStringify as nr, readExtensionInstallProvenance as nt, normalizeProviders as o, mergeKeybindings as on, hydrateReadStateFromSessionAsync as or, discoverAndBuildExtensionRegistry as ot, collectNewlyStaleReadPaths as p, alternateCredKey as pn, mergeContributions as pt, CompactInvalidInputError as q, resolveArtifactKind as qn, validateToolArgs as qt, createToolStateController as r, groupBindings as rn, getReadState as rr, removeInstalledExtension as rt, resolveModelTargets as s, parseBindingSpec as sn, readStateKey as sr, buildExtensionPreset as st, createAgent as t, ensureKeybindingsFile as tn, normalizeShellCommand as tr, parseExtensionInstallSource as tt, TOOL_USE_CANCELLED_MESSAGE as u, resolveExtensionKeybindings as un, disposeExtensionRegistry as ut, cleanupPersistedSession as v, discoverExtensions as vn, composePresets as vt, resolveMcpWarningsDir as w, setDebugLogSink as wn, waitTask as wt, rehomePersistedStubs as x, parseExtensionScanPathEnv as xn, basic_default as xt, maybePersistToolResult as y, inlineLoadedExtension as yn, definePreset as yt, buildTailCompactPrompt as z, branchKind as zn, createModelSearchTool as zt };
18473
+ export { ExtensionInstallError as $, effectiveContextWindow as $n, DEFAULT_KEYBINDINGS as $t, buildPostCompactAttachments as A, isValidExtensionConfigItem as An, reserveChildLabel as At, buildFullCompactPrompt as B, artifactKindLabel as Bn, multiEdit as Bt, rehomePersistedStubs as C, parseExtensionScanPathEnv as Cn, basic_default as Ct, resolvePersistDir as D, defineExtension as Dn, createToolSearchTool as Dt, resolveMcpWarningsDir as E, setDebugLogSink as En, waitTask as Et, BASE_INSTRUCTIONS as F, toWireConfigSchema as Fn, createShellTool as Ft, sliceForCompaction as G, parseShortstat as Gn, createInteractionTool as Gt, buildUpToCompactPrompt as H, commitKind as Hn, formatModelLine as Ht, NO_TOOLS_PREAMBLE as I, EXTENSION_BUS_MAX_PAYLOAD_BYTES as In, shell as It, truncateHeadForPtlRetry as J, renderArtifactRow as Jn, edit as Jt, stripImagesFromTurns as K, pullRequestKind as Kn, grep as Kt, TRAILER as L, createExtensionBus as Ln, tailTruncate as Lt, selectFilesFromSession as M, resolveExtensionConfig as Mn, createSkillsRunScriptTool as Mt, selectRecentFiles as N, resolveExtensionConfigValue as Nn, createSkillsReadTool as Nt, resolveSessionDir as O, clampExtensionConfigNumber as On, createSpawnTool as Ot, compactConversation as P, sanitizeExtensionConfigActionPatch as Pn, shellKill as Pt, createExtensionPromptBridge as Q, OUTPUT_RESERVE_TOKENS as Qn, recordArtifact as Qt, buildCompactPrompt as R, serializedPayloadBytes as Rn, readFile$1 as Rt, migrateSessionArtifactDirs as S, isExtensionDefinition as Sn, basicTools as St, resolveLegacySessionDir as T, createDebugLog as Tn, WAIT_TASK_TIMED_OUT_PREFIX as Tt, ANCHOR_PREVIEW_MAX_CHARS as U, fileKind as Un, matchModelEntries as Ut, buildTailCompactPrompt as V, branchKind as Vn, createModelSearchTool as Vt, anchorPreviewFor as W, githubTokenSource as Wn, listFiles as Wt, CompactPromptTooLongError as X, createArtifactDetectHook as Xn, artifacts_default as Xt, CompactInvalidInputError as Y, resolveArtifactKind as Yn, validateToolArgs as Yt, EMPTY_EXTENSION_REGISTRY as Z, AUTO_COMPACT_MIN_GROWTH_FRACTION as Zn, RECORD_ARTIFACT_TOOL as Zt, PERSISTED_STUB_PREFIX as _, registerExtensionHostModules as _n, createArtifactsSurface as _t, stagedToolState as a, groupBindings as an, getReadState as ar, removeInstalledExtension as at, cleanupPersistedSession as b, discoverExtensions as bn, composePresets as bt, INTERRUPT_MESSAGE_FOR_TOOL_USE as c, mergeKeybindings as cn, hydrateReadStateFromSessionAsync as cr, discoverAndBuildExtensionRegistry as ct, TOOL_USE_SKIPPED_MESSAGE as d, readKeybindingsRaw as dn, composeExtensionPreset as dt, KEYBINDING_DEFS as en, shouldAutoCompact as er, fetchExtensionSource as et, applyCompactSummaryCutoff as f, resolveExtensionKeybindings as fn, disposeExtensionRegistry as ft, unwrapCallTool as g, isReservedCredKey as gn, partitionExtensionCatalog as gt, CALL_TOOL_NAME as h, alternateCredKey as hn, mergeContributions as ht, isToolStateOps as i, formatBindingForDisplay as in, stableStringify as ir, readExtensionInstallProvenance as it, selectFilesFromReadState as j, isValidExtensionConfigValue as jn, createSkillsUseTool as jt, resolveTasksDir as k, coerceExtensionConfigInput as kn, isSpawnTool as kt, SHELL_CASCADE_CANCEL_MESSAGE as l, parseBindingSpec as ln, readStateKey as lr, buildExtensionPreset as lt, renderStaleReadNotice as m, ALTERNATE_CRED_KEY_SUFFIX as mn, filterRegistryPlugins as mt, DEFAULT_MAX_VALUE_BYTES as n, KEYBINDING_KEY_COL_WIDTH as nn, defaultRepeatGuardTracked as nr, listExtensionCandidates as nt, normalizeProviders as o, keybindingsPath as on, hashContent as or, updateInstalledExtension as ot, collectNewlyStaleReadPaths as p, stripJsonComments as pn, filterExtensionRegistry as pt, summaryToTurn as q, refreshArtifact as qn, glob as qt, createToolStateController as r, ensureKeybindingsFile as rn, normalizeShellCommand as rr, parseExtensionInstallSource as rt, resolveModelTargets as s, matchesBinding as sn, hydrateReadStateFromSession as sr, createExtensionHud as st, createAgent as t, KEYBINDING_DEF_BY_ACTION as tn, defaultRepeatGuardNormalize as tr, installExtensionFromSpec as tt, TOOL_USE_CANCELLED_MESSAGE as u, readKeybindings as un, resolveReadStateMap as ur, buildExtensionRegistry as ut, PERSISTENCE_PREVIEW_BYTES as v, ENTRY_CANDIDATES as vn, createExtensionHostRuntimeBridge as vt, resolveLegacyPersistDir as w, scanExtensionDirectories as wn, writeFile$1 as wt, maybePersistToolResult as x, inlineLoadedExtension as xn, definePreset as xt, buildPersistedStub as y, defaultExtensionScanPaths as yn, createWorkspaceSurface as yt, buildFromCompactPrompt as z, BUILTIN_ARTIFACT_KINDS as zn, looksBinary as zt };
18200
18474
 
18201
- //# sourceMappingURL=agent-9gf8ZlBR.js.map
18475
+ //# sourceMappingURL=agent-_xxElOgH.js.map