zidane 5.11.2 → 5.12.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 (96) hide show
  1. package/dist/{agent-D0W9yClt.d.ts → agent-Dt3mALPV.d.ts} +209 -30
  2. package/dist/agent-Dt3mALPV.d.ts.map +1 -0
  3. package/dist/chat/pure.d.ts +3 -3
  4. package/dist/chat.d.ts +6 -6
  5. package/dist/chat.js +2 -2
  6. package/dist/contexts/e2b.d.ts +1 -1
  7. package/dist/{errors-DkR6GPJw.js → errors-BpPfMo_4.js} +17 -2
  8. package/dist/{errors-DkR6GPJw.js.map → errors-BpPfMo_4.js.map} +1 -1
  9. package/dist/eval.d.ts +1 -1
  10. package/dist/eval.js +2 -2
  11. package/dist/{fetch-url-DPP6-Ruo.js → fetch-url-Cgbq-HYx.js} +2 -2
  12. package/dist/{fetch-url-DPP6-Ruo.js.map → fetch-url-Cgbq-HYx.js.map} +1 -1
  13. package/dist/{headless-Bb5gU8AR.js → headless-DSOPnfFZ.js} +39 -16
  14. package/dist/headless-DSOPnfFZ.js.map +1 -0
  15. package/dist/headless.d.ts +1 -1
  16. package/dist/headless.js +1 -1
  17. package/dist/{index-DZR99FD4.d.ts → index-BDRh3kup.d.ts} +13 -2
  18. package/dist/index-BDRh3kup.d.ts.map +1 -0
  19. package/dist/{index-D60tX5XC.d.ts → index-Do7IZGW5.d.ts} +2 -2
  20. package/dist/{index-D60tX5XC.d.ts.map → index-Do7IZGW5.d.ts.map} +1 -1
  21. package/dist/index.d.ts +5 -5
  22. package/dist/index.js +17 -14
  23. package/dist/index.js.map +1 -1
  24. package/dist/{interpolate-CTfr0GdR.js → interpolate-Da6kPCXn.js} +2 -2
  25. package/dist/{interpolate-CTfr0GdR.js.map → interpolate-Da6kPCXn.js.map} +1 -1
  26. package/dist/{logger-n4LsLISE.d.ts → logger-C2E41UWq.d.ts} +2 -2
  27. package/dist/{logger-n4LsLISE.d.ts.map → logger-C2E41UWq.d.ts.map} +1 -1
  28. package/dist/{login-BHhOdTp9.js → login-LF-inV4T.js} +33 -5
  29. package/dist/login-LF-inV4T.js.map +1 -0
  30. package/dist/{mcp-Cy9mgCcr.js → mcp-DeJ9280K.js} +141 -14
  31. package/dist/mcp-DeJ9280K.js.map +1 -0
  32. package/dist/mcp.d.ts +1 -1
  33. package/dist/mcp.js +1 -1
  34. package/dist/media-sniff-Bn76JxAu.js +216 -0
  35. package/dist/media-sniff-Bn76JxAu.js.map +1 -0
  36. package/dist/{messages-RPKrEPvH.js → messages-9wyCuvLF.js} +539 -54
  37. package/dist/messages-9wyCuvLF.js.map +1 -0
  38. package/dist/output/stream-json.d.ts +2 -2
  39. package/dist/output/stream-json.js +1 -1
  40. package/dist/output/terminal.d.ts +2 -2
  41. package/dist/{presets-D5ibZTml.js → presets-By-idp1u.js} +2 -2
  42. package/dist/{presets-D5ibZTml.js.map → presets-By-idp1u.js.map} +1 -1
  43. package/dist/presets.d.ts +2 -2
  44. package/dist/presets.js +1 -1
  45. package/dist/{providers-C2cxujp_.js → providers-psx2_0LB.js} +55 -22
  46. package/dist/providers-psx2_0LB.js.map +1 -0
  47. package/dist/providers.d.ts +1 -1
  48. package/dist/providers.js +2 -2
  49. package/dist/{read-state-BFqpQRc5.js → read-state-DH2IuQHX.js} +2 -2
  50. package/dist/{read-state-BFqpQRc5.js.map → read-state-DH2IuQHX.js.map} +1 -1
  51. package/dist/restate.d.ts +1 -1
  52. package/dist/restate.js +1 -1
  53. package/dist/session/sqlite.d.ts +1 -1
  54. package/dist/session/sqlite.js +1 -1
  55. package/dist/{session-Do_TQV7c.js → session-CB23Ne0_.js} +2 -2
  56. package/dist/{session-Do_TQV7c.js.map → session-CB23Ne0_.js.map} +1 -1
  57. package/dist/session.d.ts +1 -1
  58. package/dist/session.js +2 -2
  59. package/dist/skills.d.ts +2 -2
  60. package/dist/skills.js +1 -1
  61. package/dist/{tool-formatters-RT5-gyE2.d.ts → tool-formatters-COmtAwgF.d.ts} +2 -2
  62. package/dist/{tool-formatters-RT5-gyE2.d.ts.map → tool-formatters-COmtAwgF.d.ts.map} +1 -1
  63. package/dist/tools/fetch-url.d.ts +1 -1
  64. package/dist/tools/fetch-url.js +1 -1
  65. package/dist/tools/web-search.d.ts +1 -1
  66. package/dist/tools/web-search.js +2 -2
  67. package/dist/{tools-ZHKOh44k.js → tools-CZYTs_lT.js} +98 -127
  68. package/dist/tools-CZYTs_lT.js.map +1 -0
  69. package/dist/tools.d.ts +2 -2
  70. package/dist/tools.js +2 -2
  71. package/dist/{transcript-anchors-0zzqcSm5.js → transcript-anchors-A7__EUVN.js} +25 -18
  72. package/dist/transcript-anchors-A7__EUVN.js.map +1 -0
  73. package/dist/{transcript-anchors-B4FxkG-8.d.ts → transcript-anchors-DLa8m9_E.d.ts} +4 -4
  74. package/dist/{transcript-anchors-B4FxkG-8.d.ts.map → transcript-anchors-DLa8m9_E.d.ts.map} +1 -1
  75. package/dist/tui.d.ts +3 -3
  76. package/dist/tui.js +9 -9
  77. package/dist/tui.js.map +1 -1
  78. package/dist/{turn-operations-CoRj3mYZ.d.ts → turn-operations-ifKg5muR.d.ts} +3 -3
  79. package/dist/{turn-operations-CoRj3mYZ.d.ts.map → turn-operations-ifKg5muR.d.ts.map} +1 -1
  80. package/dist/{types-BiobHM1D.js → types-DxHDaqN7.js} +23 -6
  81. package/dist/{types-BiobHM1D.js.map → types-DxHDaqN7.js.map} +1 -1
  82. package/dist/types.d.ts +3 -3
  83. package/dist/types.js +2 -2
  84. package/docs/RESTATE.md +25 -0
  85. package/package.json +2 -1
  86. package/dist/agent-D0W9yClt.d.ts.map +0 -1
  87. package/dist/headless-Bb5gU8AR.js.map +0 -1
  88. package/dist/image-sniff-B7uFSNO1.js +0 -90
  89. package/dist/image-sniff-B7uFSNO1.js.map +0 -1
  90. package/dist/index-DZR99FD4.d.ts.map +0 -1
  91. package/dist/login-BHhOdTp9.js.map +0 -1
  92. package/dist/mcp-Cy9mgCcr.js.map +0 -1
  93. package/dist/messages-RPKrEPvH.js.map +0 -1
  94. package/dist/providers-C2cxujp_.js.map +0 -1
  95. package/dist/tools-ZHKOh44k.js.map +0 -1
  96. package/dist/transcript-anchors-0zzqcSm5.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { l as errorMessage } from "../errors-DkR6GPJw.js";
2
- import { c as stripHtmlInline, o as isHostAllowed } from "../fetch-url-DPP6-Ruo.js";
1
+ import { l as errorMessage } from "../errors-BpPfMo_4.js";
2
+ import { c as stripHtmlInline, o as isHostAllowed } from "../fetch-url-Cgbq-HYx.js";
3
3
  //#region src/tools/web-search.ts
4
4
  /**
5
5
  * Web search tool with a runtime-resolved backend.
@@ -1,16 +1,16 @@
1
1
  import { r as utf8ByteLength } from "./utils-ngQzYzZD.js";
2
2
  import { t as buildContextBreakdown } from "./context-breakdown-kO-pDsay.js";
3
3
  import { a as formatTaskStatus, i as formatDuration, o as formatTaskSummary, s as previewLine } from "./format-BNOXpl-1.js";
4
- import { a as createCursorOAuthProvider, c as baseten, d as anthropic, g as FAST_MODE_OPTIONS, h as ANTHROPIC_EXTRA_MODELS, m as writeFileAtomicAsync, n as openai, o as generatePkce, r as local, s as cerebras, t as openrouter, u as arcee } from "./providers-C2cxujp_.js";
5
- import { i as AgentProviderError, l as errorMessage, n as AgentBudgetExceededError, o as AgentToolPairingError, p as toTypedError, t as AgentAbortedError } from "./errors-DkR6GPJw.js";
6
- import { A as renderSystemForWire, D as appendStaticSection, a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, s as ensureToolResultPairing } from "./messages-RPKrEPvH.js";
7
- import { a as toolResultToText, i as toolOutputByteLength, n as documentBlockMarker, r as toolOutputBudgetByteLength, t as DEFAULT_AGENT_CLOCK } from "./types-BiobHM1D.js";
8
- import { t as reconcileImageMediaType } from "./image-sniff-B7uFSNO1.js";
4
+ import { a as createCursorOAuthProvider, c as baseten, d as anthropic, g as FAST_MODE_OPTIONS, h as ANTHROPIC_EXTRA_MODELS, m as writeFileAtomicAsync, n as openai, o as generatePkce, r as local, s as cerebras, t as openrouter, u as arcee } from "./providers-psx2_0LB.js";
5
+ import { i as AgentProviderError, l as errorMessage, m as toTypedError, n as AgentBudgetExceededError, o as AgentToolPairingError, t as AgentAbortedError, u as isAbortLikeError } from "./errors-BpPfMo_4.js";
6
+ import { F as canonicalizePrompt, O as appendStaticSection, P as buildPromptMessage, a as detectTurnInterruption, c as filterUnresolvedToolUses, d as remintDuplicateToolCallIds, f as resolveContentRefsInMessages, j as renderSystemForWire, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureEndsWithUserMessage, s as ensureToolResultPairing } from "./messages-9wyCuvLF.js";
7
+ import { n as reconcileImageMediaType } from "./media-sniff-Bn76JxAu.js";
8
+ import { a as toolOutputByteLength, i as toolOutputBudgetByteLength, o as toolResultToText, r as documentBlockMarker, t as DEFAULT_AGENT_CLOCK } from "./types-DxHDaqN7.js";
9
9
  import { r as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-DglWSzmR.js";
10
10
  import { i as styleReplacementForVia, n as resolveOldString, r as stripLineNumberPrefixes, t as describeVia } from "./edit-utils-EGosADZq.js";
11
- import { a as markReadStateElided, n as getToolDedupState, o as readStateKey, r as hashContent, s as resolveReadStateMap } from "./read-state-BFqpQRc5.js";
12
- import { S as escapeXml, d as buildCatalog, n as stripShellInterpolations, p as installAllowedToolsGate, r as resolveSkills, t as interpolateShellCommands, v as validateResourcePathReal, x as createSkillActivationState } from "./interpolate-CTfr0GdR.js";
13
- import { n as connectMcpServers } from "./mcp-Cy9mgCcr.js";
11
+ import { a as markReadStateElided, n as getToolDedupState, o as readStateKey, r as hashContent, s as resolveReadStateMap } from "./read-state-DH2IuQHX.js";
12
+ import { S as escapeXml, d as buildCatalog, n as stripShellInterpolations, p as installAllowedToolsGate, r as resolveSkills, t as interpolateShellCommands, v as validateResourcePathReal, x as createSkillActivationState } from "./interpolate-Da6kPCXn.js";
13
+ import { n as connectMcpServers } from "./mcp-DeJ9280K.js";
14
14
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
15
15
  import { n as shellQuote, t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
16
16
  import { isAbsolute, join, resolve } from "node:path";
@@ -2128,6 +2128,8 @@ function formatValue(value) {
2128
2128
  //#endregion
2129
2129
  //#region src/loop.ts
2130
2130
  const IMAGE_OMITTED_MARKER = "[image omitted — model does not support vision]";
2131
+ const AUDIO_OMITTED_MARKER = "[audio omitted — model does not support audio input]";
2132
+ const VIDEO_OMITTED_MARKER = "[video omitted — model does not support video input]";
2131
2133
  function documentOmittedMarker(doc) {
2132
2134
  return documentBlockMarker(doc, "document omitted — model does not support document attachments");
2133
2135
  }
@@ -2360,7 +2362,7 @@ function applyTailCompaction(messages, threshold, keepTurns, options) {
2360
2362
  persistableElided
2361
2363
  };
2362
2364
  let totalBytes = 0;
2363
- for (const msg of messages) for (const block of msg.content) if (block.type === "tool_result") totalBytes += toolOutputByteLength(block.output);
2365
+ for (const msg of messages) for (const block of msg.content) if (block.type === "tool_result") totalBytes += toolOutputBudgetByteLength(block.output);
2364
2366
  if (totalBytes <= threshold) return {
2365
2367
  messages,
2366
2368
  elidedReadPaths,
@@ -2376,7 +2378,7 @@ function applyTailCompaction(messages, threshold, keepTurns, options) {
2376
2378
  let keptBytes = 0;
2377
2379
  let budgetCutoff = floorCutoff;
2378
2380
  for (let i = messages.length - 1; i >= 0; i--) {
2379
- for (const block of messages[i].content) if (block.type === "tool_result") keptBytes += toolOutputByteLength(block.output);
2381
+ for (const block of messages[i].content) if (block.type === "tool_result") keptBytes += toolOutputBudgetByteLength(block.output);
2380
2382
  if (keptBytes > threshold) {
2381
2383
  budgetCutoff = i + 1;
2382
2384
  break;
@@ -2613,7 +2615,6 @@ function applyPairingRepair(ctx, messages, turnId) {
2613
2615
  return repaired;
2614
2616
  }
2615
2617
  function sanitizeStoredToolResults(provider, messages) {
2616
- if (provider.meta.capabilities?.vision !== false && provider.meta.capabilities?.documents === true) return messages;
2617
2618
  return messages.map((msg) => {
2618
2619
  let changed = false;
2619
2620
  const newContent = msg.content.map((block) => {
@@ -2828,6 +2829,14 @@ async function runLoop(ctx) {
2828
2829
  unregisterTtftTool();
2829
2830
  }
2830
2831
  }
2832
+ async function resolveContentRefsForWire(ctx, messages) {
2833
+ return resolveContentRefsInMessages(messages, { resolveContentRef: async (block) => {
2834
+ const hookCtx = { block };
2835
+ await ctx.hooks.callHook("content-ref:resolve", hookCtx);
2836
+ if (typeof hookCtx.data !== "string") throw new Error(`Content ref "${block.ref}" (${block.type}) was not resolved by a content-ref:resolve hook.`);
2837
+ return { data: hookCtx.data };
2838
+ } });
2839
+ }
2831
2840
  /**
2832
2841
  * Force one provider call whose only tool is the synthetic `__output__`
2833
2842
  * spec built from `behavior.schema`, with `toolChoice` pinned to it, so
@@ -2865,7 +2874,7 @@ async function enforceSchemaOutput(ctx, turnId) {
2865
2874
  description: "Return the final structured output matching the required schema.",
2866
2875
  inputSchema: ctx.schema
2867
2876
  };
2868
- const schemaMessages = ensureEndsWithUserMessage(applyPairingRepair(ctx, rewriteMessagesToWire(turnsToMessages(applyCompactSummaryCutoff(ctx.turns)), ctx.aliasMaps), turnId), ctx.provider);
2877
+ const schemaMessages = ensureEndsWithUserMessage(applyPairingRepair(ctx, rewriteMessagesToWire(await resolveContentRefsForWire(ctx, turnsToMessages(applyCompactSummaryCutoff(ctx.turns))), ctx.aliasMaps), turnId), ctx.provider);
2869
2878
  let schemaResult;
2870
2879
  try {
2871
2880
  schemaResult = await ctx.provider.stream({
@@ -3124,6 +3133,7 @@ function abortableSleep(ms, signal) {
3124
3133
  async function executeTurn(ctx, turn, priorUsage) {
3125
3134
  const turnId = ctx.clock.randomUUID();
3126
3135
  let canonicalMessages = turnsToMessages(applyCompactSummaryCutoff(ctx.turns));
3136
+ canonicalMessages = await resolveContentRefsForWire(ctx, canonicalMessages);
3127
3137
  if (ctx.elideStaleReads === true) {
3128
3138
  const elision = applyStaleReadElision(canonicalMessages);
3129
3139
  canonicalMessages = elision.messages;
@@ -3151,7 +3161,7 @@ async function executeTurn(ctx, turn, priorUsage) {
3151
3161
  const threshold = typeof ctx.compactThreshold === "number" && ctx.compactThreshold > 0 ? ctx.compactThreshold : 131072;
3152
3162
  const keep = typeof ctx.compactKeepTurns === "number" && ctx.compactKeepTurns >= 0 ? ctx.compactKeepTurns : 4;
3153
3163
  let totalBytes = 0;
3154
- for (const msg of sanitizedMessages) for (const block of msg.content) if (block.type === "tool_result") totalBytes += toolOutputByteLength(block.output);
3164
+ for (const msg of sanitizedMessages) for (const block of msg.content) if (block.type === "tool_result") totalBytes += toolOutputBudgetByteLength(block.output);
3155
3165
  try {
3156
3166
  const compacted = await ctx.compactStrategy(sanitizedMessages, {
3157
3167
  threshold,
@@ -3179,7 +3189,7 @@ async function executeTurn(ctx, turn, priorUsage) {
3179
3189
  };
3180
3190
  const transformCtx = { messages: streamOptions.messages };
3181
3191
  await ctx.hooks.callHook("context:transform", transformCtx);
3182
- streamOptions.messages = transformCtx.messages;
3192
+ streamOptions.messages = await resolveContentRefsForWire(ctx, transformCtx.messages);
3183
3193
  streamOptions.messages = applyPairingRepair(ctx, streamOptions.messages, turnId);
3184
3194
  streamOptions.messages = ensureEndsWithUserMessage(streamOptions.messages, ctx.provider);
3185
3195
  const systemCtx = {
@@ -3196,6 +3206,7 @@ async function executeTurn(ctx, turn, priorUsage) {
3196
3206
  turnId,
3197
3207
  options: streamOptions
3198
3208
  });
3209
+ streamOptions.messages = await resolveContentRefsForWire(ctx, streamOptions.messages);
3199
3210
  streamOptions.messages = applyPairingRepair(ctx, streamOptions.messages, turnId);
3200
3211
  streamOptions.messages = ensureEndsWithUserMessage(streamOptions.messages, ctx.provider);
3201
3212
  let currentText = "";
@@ -3506,17 +3517,32 @@ function stripImagesForNonVision(provider, output) {
3506
3517
  }
3507
3518
  function sanitizeToolOutputForProvider(provider, output) {
3508
3519
  if (typeof output === "string") return output;
3509
- if (provider.meta.capabilities?.vision !== false && provider.meta.capabilities?.documents === true) return output;
3520
+ const caps = provider.meta.capabilities;
3521
+ if (caps?.vision !== false && caps?.audio === true && caps?.video === true && caps?.documents === true) return output;
3510
3522
  let changed = false;
3511
3523
  const sanitized = output.map((block) => {
3512
- if (block.type === "image" && provider.meta.capabilities?.vision === false) {
3524
+ if (block.type === "image" && caps?.vision === false) {
3513
3525
  changed = true;
3514
3526
  return {
3515
3527
  type: "text",
3516
3528
  text: IMAGE_OMITTED_MARKER
3517
3529
  };
3518
3530
  }
3519
- if (block.type === "document" && provider.meta.capabilities?.documents !== true) {
3531
+ if (block.type === "audio" && caps?.audio !== true) {
3532
+ changed = true;
3533
+ return {
3534
+ type: "text",
3535
+ text: AUDIO_OMITTED_MARKER
3536
+ };
3537
+ }
3538
+ if (block.type === "video" && caps?.video !== true) {
3539
+ changed = true;
3540
+ return {
3541
+ type: "text",
3542
+ text: VIDEO_OMITTED_MARKER
3543
+ };
3544
+ }
3545
+ if (block.type === "document" && caps?.documents !== true) {
3520
3546
  changed = true;
3521
3547
  return {
3522
3548
  type: "text",
@@ -4498,89 +4524,6 @@ async function executeNativeToolBatch(ctx, toolCalls, turnId) {
4498
4524
  }
4499
4525
  }
4500
4526
  //#endregion
4501
- //#region src/prompt.ts
4502
- /**
4503
- * Coerce the run-level prompt into a `PromptPart[]`.
4504
- *
4505
- * - `string` prompt → a single `text` part. Empty string returns `undefined`
4506
- * so callers skip pushing an empty user turn.
4507
- * - `PromptPart[]` prompt → validated and returned as-is. An empty array, or
4508
- * an array whose text parts are all empty with no image/document parts,
4509
- * returns `undefined`.
4510
- * - `undefined` → `undefined` (promptless resume path).
4511
- */
4512
- function canonicalizePrompt(prompt) {
4513
- if (prompt === void 0) return void 0;
4514
- if (typeof prompt === "string") {
4515
- if (prompt.length === 0) return void 0;
4516
- return [{
4517
- type: "text",
4518
- text: prompt
4519
- }];
4520
- }
4521
- if (prompt.length === 0) return void 0;
4522
- for (const part of prompt) {
4523
- if (!part || typeof part !== "object" || typeof part.type !== "string") throw new Error("Invalid PromptPart: each part must be an object with a `type` field.");
4524
- const type = part.type;
4525
- if (type !== "text" && type !== "image" && type !== "document") throw new Error(`Invalid PromptPart type "${type}". Expected "text" | "image" | "document".`);
4526
- }
4527
- if (!prompt.some((part) => part.type === "text" && part.text.length > 0 || part.type === "image" || part.type === "document")) return void 0;
4528
- return prompt;
4529
- }
4530
- /**
4531
- * Build a user `SessionMessage` from prompt parts without provider-specific handling.
4532
- *
4533
- * - `text` parts map to `{ type: 'text', text }` blocks.
4534
- * - `image` parts map to `{ type: 'image', mediaType, data }` blocks.
4535
- * - `document` parts with `encoding: 'text'` are inlined as an attachment-tagged
4536
- * text block so every provider can read them.
4537
- * - `document` parts with `encoding: 'base64'` throw — the caller should switch
4538
- * to a provider that implements `promptMessage` (e.g. Anthropic for PDFs).
4539
- */
4540
- function defaultPromptMessage(parts) {
4541
- const content = [];
4542
- for (const part of parts) {
4543
- if (part.type === "text") {
4544
- if (part.text.length > 0) content.push({
4545
- type: "text",
4546
- text: part.text
4547
- });
4548
- continue;
4549
- }
4550
- if (part.type === "image") {
4551
- content.push({
4552
- type: "image",
4553
- mediaType: part.mediaType,
4554
- data: part.data,
4555
- ...part.name ? { name: part.name } : {}
4556
- });
4557
- continue;
4558
- }
4559
- if (part.encoding === "text") {
4560
- const header = part.name ? `<attachment name="${part.name}" media_type="${part.mediaType}">` : `<attachment media_type="${part.mediaType}">`;
4561
- content.push({
4562
- type: "text",
4563
- text: `${header}\n${part.data}\n</attachment>`
4564
- });
4565
- continue;
4566
- }
4567
- throw new Error(`Provider does not support base64 document parts (mediaType: ${part.mediaType}). Use a text-encoded document or a provider that implements promptMessage (e.g. Anthropic).`);
4568
- }
4569
- return {
4570
- role: "user",
4571
- content
4572
- };
4573
- }
4574
- /**
4575
- * Build the prompt `SessionMessage` for a given provider.
4576
- *
4577
- * Prefers `provider.promptMessage` when defined, falling back to `defaultPromptMessage`.
4578
- */
4579
- function buildPromptMessage(provider, parts) {
4580
- if (provider.promptMessage) return provider.promptMessage(parts);
4581
- return defaultPromptMessage(parts);
4582
- }
4583
- //#endregion
4584
4527
  //#region src/repeat-guard.ts
4585
4528
  const DEFAULT_BLOCK_THRESHOLD = 4;
4586
4529
  const DEFAULT_ABORT_THRESHOLD = 8;
@@ -6094,6 +6037,7 @@ const HOOK_EVENT_SET = new Set([
6094
6037
  "stream:error",
6095
6038
  "stream:retry",
6096
6039
  "oauth:refresh",
6040
+ "content-ref:resolve",
6097
6041
  "tool:gate",
6098
6042
  "tool:dispatched",
6099
6043
  "tool:before",
@@ -7832,10 +7776,13 @@ const glob$1 = {
7832
7776
  /**
7833
7777
  * Search file contents by regex.
7834
7778
  *
7835
- * Wraps ripgrep (`rg`) when available, falls back to an in-process
7836
- * `fs/promises` `glob` + regex implementation when running in the
7837
- * in-process execution context. For non-process contexts without `rg`,
7838
- * returns a clear hint rather than silently doing nothing.
7779
+ * Wraps ripgrep (`rg`) when available; when it's not, falls back to a
7780
+ * regex search that enumerates files via the execution context's shell
7781
+ * (`find` over `exec`) and reads them via `ctx.execution.readFile`. Both
7782
+ * legs go through the {@link ToolContext.execution} seam, so the search
7783
+ * runs wherever the context's files actually live — in-process, a
7784
+ * container, or a remote sandbox — without the tool ever touching the host
7785
+ * filesystem directly.
7839
7786
  *
7840
7787
  * The tool surface mirrors Claude Code's `Grep` so models authored against the
7841
7788
  * Anthropic tool surface need no relearning. Output modes:
@@ -7858,7 +7805,7 @@ const grep = {
7858
7805
  isConcurrencySafe: true,
7859
7806
  spec: {
7860
7807
  name: "grep",
7861
- description: "Search file contents by regex. Returns matching paths (default), match content, or per-file counts. Backed by ripgrep when available with an in-process glob fallback for in-process runs.",
7808
+ description: "Search file contents by regex. Returns matching paths (default), match content, or per-file counts. Backed by ripgrep when available, with a portable shell-listing + regex fallback when `rg` is absent.",
7862
7809
  inputSchema: {
7863
7810
  type: "object",
7864
7811
  properties: {
@@ -7925,9 +7872,13 @@ const grep = {
7925
7872
  },
7926
7873
  async execute(rawInput, ctx) {
7927
7874
  const input = rawInput;
7928
- if (await isRipgrepAvailable(ctx)) return runViaRipgrep(input, ctx);
7929
- if (ctx.execution.type === "process") return runInProcess(input, ctx);
7930
- return "grep error: ripgrep is not available in the execution context. Install `rg` or use the `shell` tool with grep/awk.";
7875
+ try {
7876
+ if (await isRipgrepAvailable(ctx)) return await runViaRipgrep(input, ctx);
7877
+ return await runFallback(input, ctx);
7878
+ } catch (err) {
7879
+ if (isAbortLikeError(err)) throw err;
7880
+ return `grep error: ${errorMessage(err)}`;
7881
+ }
7931
7882
  }
7932
7883
  };
7933
7884
  /**
@@ -7939,7 +7890,7 @@ const grep = {
7939
7890
  * ~5 ms, and grep is invoked at most a few times per turn.
7940
7891
  */
7941
7892
  async function isRipgrepAvailable(ctx) {
7942
- return (await ctx.execution.exec(ctx.handle, "rg --version")).exitCode === 0;
7893
+ return (await ctx.execution.exec(ctx.handle, "rg --version", { signal: ctx.signal })).exitCode === 0;
7943
7894
  }
7944
7895
  async function runViaRipgrep(input, ctx) {
7945
7896
  const args = ["rg"];
@@ -7959,11 +7910,11 @@ async function runViaRipgrep(input, ctx) {
7959
7910
  args.push("--", input.pattern);
7960
7911
  args.push(input.path ?? ".");
7961
7912
  const command = args.map(shellQuote).join(" ");
7962
- const result = await ctx.execution.exec(ctx.handle, command);
7913
+ const result = await ctx.execution.exec(ctx.handle, command, { signal: ctx.signal });
7963
7914
  if (result.exitCode !== 0 && result.exitCode !== 1) return `grep error: ${result.stderr.trim() || `rg exited with code ${result.exitCode}`}`;
7964
7915
  return formatPaginated(result.stdout, input);
7965
7916
  }
7966
- async function runInProcess(input, ctx) {
7917
+ async function runFallback(input, ctx) {
7967
7918
  const mode = input.output_mode ?? DEFAULT_OUTPUT_MODE;
7968
7919
  const flags = `${input["-i"] ? "i" : ""}${input.multiline ? "s" : ""}${mode !== "content" ? "" : "g"}`;
7969
7920
  let regex;
@@ -7981,7 +7932,8 @@ async function runInProcess(input, ctx) {
7981
7932
  let content;
7982
7933
  try {
7983
7934
  content = await ctx.execution.readFile(ctx.handle, path);
7984
- } catch {
7935
+ } catch (err) {
7936
+ if (isAbortLikeError(err)) throw err;
7985
7937
  continue;
7986
7938
  }
7987
7939
  if (input.multiline) {
@@ -8036,19 +7988,35 @@ function formatContentLine(path, lineNo, snippet, showLineNumbers) {
8036
7988
  return showLineNumbers ? `${path}:${lineNo}:${snippet}` : `${path}:${snippet}`;
8037
7989
  }
8038
7990
  async function enumerateFiles(input, ctx) {
8039
- const cwd = ctx.handle.cwd;
8040
7991
  const root = input.path ?? ".";
8041
- if (input.path && !input.path.includes("*") && !input.path.includes("?")) try {
8042
- if ((await ctx.execution.exec(ctx.handle, `test -f ${shellQuote(input.path)} && echo file || echo dir`)).stdout.trim() === "file") return [input.path];
8043
- } catch {}
8044
- const pattern = input.glob ?? "**/*";
8045
- const scanRoot = root === "." ? cwd : `${cwd.replace(/\/$/, "")}/${root.replace(/^\.\//, "")}`;
8046
- const prefix = root === "." ? "" : `${root.replace(/\/$/, "")}/`;
8047
- const out = [];
8048
- for await (const rel of glob(pattern, { cwd: scanRoot })) try {
8049
- if ((await stat(resolve(scanRoot, rel))).isFile()) out.push(prefix ? `${prefix}${rel}` : rel);
8050
- } catch {}
8051
- return out.sort();
7992
+ if (input.path && !input.path.includes("*") && !input.path.includes("?")) {
7993
+ if ((await ctx.execution.exec(ctx.handle, `test -f ${shellQuote(input.path)} && echo file || echo dir`, { signal: ctx.signal })).stdout.trim() === "file") return [input.path];
7994
+ }
7995
+ const result = await ctx.execution.exec(ctx.handle, buildFindCommand(root, input.glob), { signal: ctx.signal });
7996
+ if (result.exitCode !== 0 && !result.stdout.trim()) throw new Error(result.stderr.trim() || `find exited with code ${result.exitCode}`);
7997
+ return result.stdout.split("\n").map((line) => line.replace(/^\.\//, "")).filter((line) => line.length > 0).sort();
7998
+ }
7999
+ /**
8000
+ * Build a `find` command listing files under `root`, optionally filtered by
8001
+ * `glob`. Mirrors `glob`'s shell fallback:
8002
+ * - a bare basename, or one behind a leading recursive-wildcard segment,
8003
+ * with no inner slash → `-name` (matches at any depth, including the top
8004
+ * level — preserving the recursive-glob semantics).
8005
+ * - anything with a slash → `-path` against the full relative path. `find`'s
8006
+ * `*` spans `/`, so the single- and double-star forms collapse to the
8007
+ * same matcher; close enough for the no-`rg` fallback.
8008
+ */
8009
+ function buildFindCommand(root, glob) {
8010
+ const findRoot = normalizeFindRoot(root);
8011
+ const base = shellQuote(findRoot);
8012
+ if (!glob) return `find ${base} -type f`;
8013
+ const anyDepth = glob.match(/^(?:\*\*\/)?([^/]+)$/);
8014
+ if (anyDepth) return `find ${base} -type f -name ${shellQuote(anyDepth[1])}`;
8015
+ const normRoot = findRoot.replace(/\/$/, "");
8016
+ return `find ${base} -type f -path ${shellQuote(root === "." ? `./${glob}` : `${normRoot}/${glob}`)}`;
8017
+ }
8018
+ function normalizeFindRoot(root) {
8019
+ return root.startsWith("-") ? `./${root}` : root;
8052
8020
  }
8053
8021
  function formatPaginated(text, input) {
8054
8022
  const headLimit = typeof input.head_limit === "number" && input.head_limit >= 0 ? input.head_limit : DEFAULT_HEAD_LIMIT;
@@ -8598,6 +8566,7 @@ const BUBBLED_EVENTS = [
8598
8566
  "turn:after"
8599
8567
  ];
8600
8568
  const BUBBLED_MUTABLE_EVENTS = [
8569
+ "content-ref:resolve",
8601
8570
  "tool:gate",
8602
8571
  "mcp:tool:gate",
8603
8572
  "tool:transform"
@@ -8620,6 +8589,7 @@ const CHILD_EVENT_NAME = {
8620
8589
  "turn:after": "child:turn:after"
8621
8590
  };
8622
8591
  const CHILD_MUTABLE_EVENT_NAME = {
8592
+ "content-ref:resolve": "content-ref:resolve",
8623
8593
  "tool:gate": "child:tool:gate",
8624
8594
  "mcp:tool:gate": "child:mcp:tool:gate",
8625
8595
  "tool:transform": "child:tool:transform"
@@ -8781,8 +8751,8 @@ function bubbleHooks(childHooks, parentHooks, childId, depth) {
8781
8751
  unregisters.push(unregister);
8782
8752
  }
8783
8753
  const tagOnCtx = (ctx) => {
8784
- ctx.childId = childId;
8785
- ctx.depth = depth;
8754
+ ctx.childId ??= childId;
8755
+ ctx.depth ??= depth;
8786
8756
  };
8787
8757
  for (const evt of BUBBLED_MUTABLE_EVENTS) {
8788
8758
  const parentEvt = CHILD_MUTABLE_EVENT_NAME[evt];
@@ -8801,6 +8771,7 @@ function bubbleHooks(childHooks, parentHooks, childId, depth) {
8801
8771
  }
8802
8772
  for (const evt of BUBBLED_MUTABLE_EVENTS) {
8803
8773
  const parentEvt = CHILD_MUTABLE_EVENT_NAME[evt];
8774
+ if (parentEvt === evt) continue;
8804
8775
  unregisters.push(chainHook(parentEvt, async (ctx) => {
8805
8776
  await fire(parentEvt, ctx);
8806
8777
  }));
@@ -9124,4 +9095,4 @@ const writeFile$1 = {
9124
9095
  //#endregion
9125
9096
  export { restoreModelOptions as $, PERSISTENCE_PREVIEW_BYTES as A, cerebrasDescriptor as B, stableStringify as C, TOOL_USE_SKIPPED_MESSAGE as D, TOOL_USE_CANCELLED_MESSAGE as E, resolvePersistDir as F, getModelInfo as G, effectiveContextWindow as H, resolveTasksDir as I, modelSupportsReasoning as J, localDescriptor as K, BUILTIN_PROVIDERS as L, cleanupPersistedSession as M, maybePersistToolResult as N, validateToolArgs as O, resolveMcpWarningsDir as P, piIdOf as Q, OUTPUT_RESERVE_TOKENS as R, normalizeShellCommand as S, SHELL_CASCADE_CANCEL_MESSAGE as T, enabledModelOptions as U, credKeyOf as V, getContextWindow as W, openaiDescriptor as X, modelsForDescriptor as Y, openrouterDescriptor as Z, createSkillsReadTool as _, multiEdit as a, defaultRepeatGuardNormalize as b, grep as c, createAgent as d, WAIT_TASK_TIMED_OUT_PREFIX as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, buildPersistedStub as j, PERSISTED_STUB_PREFIX as k, glob$1 as l, createToolSearchTool as m, createSpawnTool as n, listFiles as o, waitTask as p, modelOptionsFor as q, shellKill as r, createInteractionTool as s, writeFile$1 as t, edit as u, createShellTool as v, INTERRUPT_MESSAGE_FOR_TOOL_USE as w, defaultRepeatGuardTracked as x, shell as y, anthropicDescriptor as z };
9126
9097
 
9127
- //# sourceMappingURL=tools-ZHKOh44k.js.map
9098
+ //# sourceMappingURL=tools-CZYTs_lT.js.map