zidane 5.13.11 → 5.13.13

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 (87) hide show
  1. package/dist/{acp-HSVnQBfG.js → acp-CqXcM2Km.js} +7 -7
  2. package/dist/{acp-HSVnQBfG.js.map → acp-CqXcM2Km.js.map} +1 -1
  3. package/dist/acp-cli.js +6 -6
  4. package/dist/acp.d.ts +2 -2
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-w6htlFlx.d.ts → agent-NkKgz5Dh.d.ts} +38 -2
  7. package/dist/agent-NkKgz5Dh.d.ts.map +1 -0
  8. package/dist/{auth-nA0ZMTbM.js → auth-CGTf8v1_.js} +2 -2
  9. package/dist/{auth-nA0ZMTbM.js.map → auth-CGTf8v1_.js.map} +1 -1
  10. package/dist/chat/pure.d.ts +3 -3
  11. package/dist/chat.d.ts +6 -6
  12. package/dist/chat.js +3 -3
  13. package/dist/contexts/daytona.d.ts +1 -1
  14. package/dist/contexts/e2b.d.ts +1 -1
  15. package/dist/eval.d.ts +1 -1
  16. package/dist/eval.js +2 -2
  17. package/dist/{headless-0O6HMNBQ.js → headless-C6Idunwh.js} +6 -6
  18. package/dist/{headless-0O6HMNBQ.js.map → headless-C6Idunwh.js.map} +1 -1
  19. package/dist/headless.d.ts +1 -1
  20. package/dist/headless.js +1 -1
  21. package/dist/{index-BH0lvT7N.d.ts → index-BFY7mcar.d.ts} +2 -2
  22. package/dist/{index-BH0lvT7N.d.ts.map → index-BFY7mcar.d.ts.map} +1 -1
  23. package/dist/{index-C4sPfyg6.d.ts → index-BgB_425D.d.ts} +43 -3
  24. package/dist/index-BgB_425D.d.ts.map +1 -0
  25. package/dist/index.d.ts +4 -4
  26. package/dist/index.js +10 -10
  27. package/dist/{logger-MCqSKpby.d.ts → logger-LQmSBfD_.d.ts} +2 -2
  28. package/dist/{logger-MCqSKpby.d.ts.map → logger-LQmSBfD_.d.ts.map} +1 -1
  29. package/dist/{login-D5rb4IG8.js → login-DE-_d045.js} +2 -2
  30. package/dist/{login-D5rb4IG8.js.map → login-DE-_d045.js.map} +1 -1
  31. package/dist/{mcp-C_TIj91j.js → mcp-2OGi_NQu.js} +2 -2
  32. package/dist/{mcp-C_TIj91j.js.map → mcp-2OGi_NQu.js.map} +1 -1
  33. package/dist/mcp.d.ts +1 -1
  34. package/dist/mcp.js +1 -1
  35. package/dist/{messages-DEsLGBB9.js → messages-U_87Z7GH.js} +2 -2
  36. package/dist/{messages-DEsLGBB9.js.map → messages-U_87Z7GH.js.map} +1 -1
  37. package/dist/output/stream-json.d.ts +2 -2
  38. package/dist/output/stream-json.js +1 -1
  39. package/dist/output/terminal.d.ts +2 -2
  40. package/dist/{presets-HDIxliiq.js → presets-eC4VwuHh.js} +2 -2
  41. package/dist/{presets-HDIxliiq.js.map → presets-eC4VwuHh.js.map} +1 -1
  42. package/dist/presets.d.ts +2 -2
  43. package/dist/presets.js +1 -1
  44. package/dist/{providers-OBIysrMe.js → providers-DyMPTo51.js} +3 -3
  45. package/dist/{providers-OBIysrMe.js.map → providers-DyMPTo51.js.map} +1 -1
  46. package/dist/providers.d.ts +1 -1
  47. package/dist/providers.js +2 -2
  48. package/dist/{read-state-DH2IuQHX.js → read-state-CLK9yVpm.js} +2 -2
  49. package/dist/{read-state-DH2IuQHX.js.map → read-state-CLK9yVpm.js.map} +1 -1
  50. package/dist/restate.d.ts +88 -3
  51. package/dist/restate.d.ts.map +1 -1
  52. package/dist/restate.js +185 -59
  53. package/dist/restate.js.map +1 -1
  54. package/dist/session/sqlite.d.ts +1 -1
  55. package/dist/{session-BDWZZaYa.js → session-DQ4bEncf.js} +2 -2
  56. package/dist/{session-BDWZZaYa.js.map → session-DQ4bEncf.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/{tool-formatters-C7N1Pb1q.d.ts → tool-formatters-DvtGhbJN.d.ts} +2 -2
  61. package/dist/{tool-formatters-C7N1Pb1q.d.ts.map → tool-formatters-DvtGhbJN.d.ts.map} +1 -1
  62. package/dist/tools/fetch-url.d.ts +1 -1
  63. package/dist/tools/web-search.d.ts +1 -1
  64. package/dist/{tools-DhzKzB1y.js → tools-BvATiiCO.js} +192 -54
  65. package/dist/tools-BvATiiCO.js.map +1 -0
  66. package/dist/tools.d.ts +3 -3
  67. package/dist/tools.js +3 -3
  68. package/dist/{transcript-anchors-Cycsq0w1.js → transcript-anchors-Cn1Unhn-.js} +7 -7
  69. package/dist/{transcript-anchors-Cycsq0w1.js.map → transcript-anchors-Cn1Unhn-.js.map} +1 -1
  70. package/dist/{transcript-anchors-CJsVfcaq.d.ts → transcript-anchors-DFmfOesU.d.ts} +4 -4
  71. package/dist/{transcript-anchors-CJsVfcaq.d.ts.map → transcript-anchors-DFmfOesU.d.ts.map} +1 -1
  72. package/dist/tui.d.ts +3 -3
  73. package/dist/tui.js +8 -8
  74. package/dist/{turn-operations-BtyfLdPi.d.ts → turn-operations-DWUN8cHo.d.ts} +3 -3
  75. package/dist/{turn-operations-BtyfLdPi.d.ts.map → turn-operations-DWUN8cHo.d.ts.map} +1 -1
  76. package/dist/{types-DxHDaqN7.js → types-CyVGdbia.js} +45 -2
  77. package/dist/{types-DxHDaqN7.js.map → types-CyVGdbia.js.map} +1 -1
  78. package/dist/types.d.ts +2 -2
  79. package/dist/types.js +1 -1
  80. package/docs/ARCHITECTURE.md +1 -1
  81. package/docs/RESTATE.md +38 -11
  82. package/docs/RUN_IN_BACKGROUND.md +4 -6
  83. package/docs/SKILL.md +2 -1
  84. package/package.json +1 -1
  85. package/dist/agent-w6htlFlx.d.ts.map +0 -1
  86. package/dist/index-C4sPfyg6.d.ts.map +0 -1
  87. package/dist/tools-DhzKzB1y.js.map +0 -1
@@ -1,17 +1,17 @@
1
- import { F as canonicalizePrompt, O as appendStaticSection, P as buildPromptMessage, R as fnv1aBase36, 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-DEsLGBB9.js";
1
+ import { F as canonicalizePrompt, O as appendStaticSection, P as buildPromptMessage, R as fnv1aBase36, 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-U_87Z7GH.js";
2
2
  import { n as estimateTokens, r as utf8ByteLength } from "./utils-ngQzYzZD.js";
3
3
  import { t as buildContextBreakdown } from "./context-breakdown-kO-pDsay.js";
4
4
  import { a as formatTaskStatus, i as formatDuration, o as formatTaskSummary, s as previewLine } from "./format-BNOXpl-1.js";
5
5
  import { r as createProcessContext, t as resolveDetachedTasksCapability } from "./contexts-DHi8LPCp.js";
6
- import { a as toolOutputByteLength, i as toolOutputBudgetByteLength, o as toolResultToText, r as documentBlockMarker, t as DEFAULT_AGENT_CLOCK } from "./types-DxHDaqN7.js";
6
+ import { a as toolOutputBudgetByteLength, i as documentBlockMarker, o as toolOutputByteLength, s as toolResultToText, t as DEFAULT_AGENT_CLOCK } from "./types-CyVGdbia.js";
7
7
  import { i as styleReplacementForVia, n as resolveOldString, r as stripLineNumberPrefixes, t as describeVia } from "./edit-utils-EGosADZq.js";
8
- import { a as markReadStateElided, n as getToolDedupState, o as readStateKey, r as hashContent, s as resolveReadStateMap, t as getReadState } from "./read-state-DH2IuQHX.js";
8
+ import { a as markReadStateElided, n as getToolDedupState, o as readStateKey, r as hashContent, s as resolveReadStateMap, t as getReadState } from "./read-state-CLK9yVpm.js";
9
9
  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";
10
10
  import { n as reconcileImageMediaType } from "./media-sniff-Bn76JxAu.js";
11
11
  import { n as writeFileAtomicAsync } from "./atomic-write-Bgtr5JPu.js";
12
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-ConAiXGy.js";
13
13
  import { n as flattenTurns, r as formatTokenUsage, t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
14
- import { n as connectMcpServers, s as wrapDiscoveredMcpTools } from "./mcp-C_TIj91j.js";
14
+ import { n as connectMcpServers, s as wrapDiscoveredMcpTools } from "./mcp-2OGi_NQu.js";
15
15
  import { n as shellQuote, t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
16
16
  import { isAbsolute, join, resolve } from "node:path";
17
17
  import { createHooks } from "hookable";
@@ -2506,6 +2506,31 @@ const SHELL_CASCADE_CANCEL_MESSAGE = "Cancelled: a sibling `shell` call in the s
2506
2506
  */
2507
2507
  const CANCELLED_BY_USER_SENTINEL = "zidane:tool:cancelled-by-user";
2508
2508
  /**
2509
+ * Compose the run-scoped `ctx.signal` and a per-call abort into one child
2510
+ * signal for a tool body — WITHOUT `AbortSignal.any`.
2511
+ *
2512
+ * `AbortSignal.any([runSignal, perCall])` registers a dependent-signal
2513
+ * algorithm on each source; the run signal is long-lived (whole run), so one
2514
+ * composite per tool call accumulates on it until the composite is GC'd —
2515
+ * a slow leak across a long run with many calls. Manual `linkAbortSignal`
2516
+ * listeners removed in `dispose()` keep the run signal's listener set bounded
2517
+ * to currently-dispatching calls. `dispose()` MUST be called once the body has
2518
+ * settled. `reason` propagates from whichever source fires first (so a
2519
+ * signal-aware body still sees the per-call cancel reason).
2520
+ */
2521
+ function composePerCallSignal(runSignal, perCallSignal) {
2522
+ const controller = new AbortController();
2523
+ const unlinkRun = linkAbortSignal(runSignal, controller);
2524
+ const unlinkPerCall = linkAbortSignal(perCallSignal, controller);
2525
+ return {
2526
+ signal: controller.signal,
2527
+ dispose: () => {
2528
+ unlinkRun();
2529
+ unlinkPerCall();
2530
+ }
2531
+ };
2532
+ }
2533
+ /**
2509
2534
  * Grace window after a run-level abort before we force-settle a tool body that
2510
2535
  * hasn't returned. Well-behaved tools observe `childSignal` and finalize their
2511
2536
  * own bookkeeping (e.g. `spawn` awaits its child's session-persisting `finally`
@@ -4310,7 +4335,7 @@ async function executeSingleTool(ctx, call, turnId) {
4310
4335
  const displayName = toWireName(call.name, ctx.aliasMaps);
4311
4336
  const runToolCounts = Object.freeze({ ...ctx.runToolCounts });
4312
4337
  const perCallAbort = new AbortController();
4313
- ctx.pendingToolCancels?.set(callId, perCallAbort);
4338
+ ctx.toolCancels?.register(callId, perCallAbort);
4314
4339
  try {
4315
4340
  return await runSingleToolDispatch(ctx, call, turnId, {
4316
4341
  toolDef,
@@ -4320,7 +4345,7 @@ async function executeSingleTool(ctx, call, turnId) {
4320
4345
  perCallAbort
4321
4346
  });
4322
4347
  } finally {
4323
- ctx.pendingToolCancels?.delete(callId);
4348
+ ctx.toolCancels?.unregister(callId);
4324
4349
  }
4325
4350
  }
4326
4351
  /**
@@ -4440,7 +4465,8 @@ async function runSingleToolDispatch(ctx, call, turnId, fixed) {
4440
4465
  let isError = false;
4441
4466
  let cancelledByUser = false;
4442
4467
  let reportedOutcome;
4443
- const childSignal = typeof AbortSignal.any === "function" ? AbortSignal.any([ctx.signal, perCallAbort.signal]) : ctx.signal;
4468
+ const composedSignal = composePerCallSignal(ctx.signal, perCallAbort.signal);
4469
+ const childSignal = composedSignal.signal;
4444
4470
  try {
4445
4471
  const toolCtx = {
4446
4472
  provider: ctx.provider,
@@ -4505,6 +4531,7 @@ async function runSingleToolDispatch(ctx, call, turnId, fixed) {
4505
4531
  removeAbortListener?.();
4506
4532
  removeRunAbortListener?.();
4507
4533
  if (runAbortTimer !== void 0) clearTimeout(runAbortTimer);
4534
+ composedSignal.dispose();
4508
4535
  }
4509
4536
  } catch (err) {
4510
4537
  const isOurSentinel = err instanceof Error && err.message === CANCELLED_BY_USER_SENTINEL;
@@ -4852,7 +4879,10 @@ async function executeCustomToolBatch(ctx, toolCalls, turnId, executor) {
4852
4879
  isError: true
4853
4880
  });
4854
4881
  } finally {
4855
- for (const start of starts) childCtx.pendingToolCancels?.delete(start.callId);
4882
+ for (const start of starts) {
4883
+ childCtx.toolCancels?.unregister(start.callId);
4884
+ start.disposeSignal();
4885
+ }
4856
4886
  }
4857
4887
  };
4858
4888
  const executionCtx = {
@@ -4903,9 +4933,9 @@ async function startDurableToolExecution(ctx, call, turnId, index) {
4903
4933
  const displayName = toWireName(call.name, ctx.aliasMaps);
4904
4934
  const runToolCounts = Object.freeze({ ...ctx.runToolCounts });
4905
4935
  const perCallAbort = new AbortController();
4906
- ctx.pendingToolCancels?.set(callId, perCallAbort);
4936
+ ctx.toolCancels?.register(callId, perCallAbort);
4907
4937
  const cleanupResult = (result) => {
4908
- ctx.pendingToolCancels?.delete(callId);
4938
+ ctx.toolCancels?.unregister(callId);
4909
4939
  return {
4910
4940
  kind: "result",
4911
4941
  result
@@ -5015,7 +5045,8 @@ async function startDurableToolExecution(ctx, call, turnId, index) {
5015
5045
  runToolCounts,
5016
5046
  ...coercions ? { coercions } : {}
5017
5047
  });
5018
- const childSignal = typeof AbortSignal.any === "function" ? AbortSignal.any([ctx.signal, perCallAbort.signal]) : ctx.signal;
5048
+ const composedSignal = composePerCallSignal(ctx.signal, perCallAbort.signal);
5049
+ const childSignal = composedSignal.signal;
5019
5050
  let reportedOutcome;
5020
5051
  const toolCtx = {
5021
5052
  provider: ctx.provider,
@@ -5055,6 +5086,7 @@ async function startDurableToolExecution(ctx, call, turnId, index) {
5055
5086
  input: effectiveInput,
5056
5087
  runToolCounts,
5057
5088
  perCallAbort,
5089
+ disposeSignal: composedSignal.dispose,
5058
5090
  ...coercions ? { coercions } : {},
5059
5091
  promise: durableExecute(effectiveInput, toolCtx),
5060
5092
  reportedOutcome: () => reportedOutcome
@@ -5682,6 +5714,84 @@ function defaultHardBlockMessage(tool, count, hardMax) {
5682
5714
  return `Tool '${tool}' has been called ${count} times this run, past its hard ceiling of ${hardMax} — the earlier budget warning was not heeded. Further invocations are refused; finish the task with the information you already have.`;
5683
5715
  }
5684
5716
  //#endregion
5717
+ //#region src/tool-cancel.ts
5718
+ /**
5719
+ * Per-call tool-cancellation registry shared between the agent and the loop.
5720
+ *
5721
+ * The loop registers an `AbortController` for each tool call right before it
5722
+ * dispatches (gate → execute), and unregisters it in a `finally`, so the live
5723
+ * map only ever holds *currently dispatching* calls. `agent.cancelTool(callId)`
5724
+ * flips the matching call's controller without unwinding the rest of the run.
5725
+ *
5726
+ * Two subtleties this registry owns so callers don't have to:
5727
+ *
5728
+ * - **Pre-registration race.** A host can learn a call's id from the streamed
5729
+ * assistant turn and ask to cancel it BEFORE the loop has dispatched it
5730
+ * (very reachable under the sequential `maxConcurrentTools: 1` default —
5731
+ * later calls in a batch register only when their turn comes). A cancel for
5732
+ * an un-registered id is parked in a bounded FIFO and applied the instant
5733
+ * the call registers, instead of being silently dropped.
5734
+ *
5735
+ * - **Bounded parking.** Parked kills for ids that never dispatch (a
5736
+ * hallucinated id, a call the model retracted) can't accumulate: the FIFO
5737
+ * evicts oldest past its cap, and the agent clears it at run boundaries so a
5738
+ * stale kill never leaks across runs onto a later call that happens to reuse
5739
+ * the same id.
5740
+ */
5741
+ /** Fallback reason stamped on the abort signal when `cancel` gets no explicit reason. */
5742
+ const DEFAULT_KILL_MESSAGE = "user-cancelled-tool";
5743
+ /** Upper bound on parked pre-registration kills — FIFO-evicted past this. */
5744
+ const DEFAULT_MAX_PENDING_KILLS = 64;
5745
+ function createToolCancelRegistry(options = {}) {
5746
+ const defaultMessage = options.defaultMessage ?? DEFAULT_KILL_MESSAGE;
5747
+ const maxPending = typeof options.maxPendingKills === "number" && options.maxPendingKills > 0 ? Math.floor(options.maxPendingKills) : DEFAULT_MAX_PENDING_KILLS;
5748
+ const live = /* @__PURE__ */ new Map();
5749
+ const pending = /* @__PURE__ */ new Map();
5750
+ function park(callId, reason) {
5751
+ pending.delete(callId);
5752
+ pending.set(callId, reason);
5753
+ while (pending.size > maxPending) {
5754
+ const oldest = pending.keys().next().value;
5755
+ if (oldest === void 0) break;
5756
+ pending.delete(oldest);
5757
+ }
5758
+ }
5759
+ function applyParked(callId, controller) {
5760
+ const reason = pending.get(callId);
5761
+ if (reason === void 0) return;
5762
+ pending.delete(callId);
5763
+ if (!controller.signal.aborted) controller.abort(reason);
5764
+ }
5765
+ return {
5766
+ register(callId, controller) {
5767
+ live.set(callId, controller);
5768
+ applyParked(callId, controller);
5769
+ },
5770
+ unregister(callId) {
5771
+ live.delete(callId);
5772
+ },
5773
+ cancel(callId, reason) {
5774
+ const message = reason ?? defaultMessage;
5775
+ const controller = live.get(callId);
5776
+ if (controller) {
5777
+ if (controller.signal.aborted) return false;
5778
+ controller.abort(message);
5779
+ return true;
5780
+ }
5781
+ park(callId, message);
5782
+ return false;
5783
+ },
5784
+ abortAll(reason) {
5785
+ for (const controller of live.values()) if (!controller.signal.aborted) controller.abort(reason);
5786
+ live.clear();
5787
+ pending.clear();
5788
+ },
5789
+ clearPending() {
5790
+ pending.clear();
5791
+ }
5792
+ };
5793
+ }
5794
+ //#endregion
5685
5795
  //#region src/tools/shell-semantics.ts
5686
5796
  const DEFAULT_SEMANTIC = (exitCode) => ({
5687
5797
  isError: exitCode !== 0,
@@ -5728,6 +5838,61 @@ function extractTrailingCommand(command) {
5728
5838
  return (segments[segments.length - 1]?.trim() ?? command).split(/\s+/).filter((t) => !/^[A-Z_]\w*=/i.test(t))[0] ?? "";
5729
5839
  }
5730
5840
  //#endregion
5841
+ //#region src/tools/truncate.ts
5842
+ /**
5843
+ * Tail-priority, byte-budgeted truncation shared across tools.
5844
+ *
5845
+ * "Tail-priority" because the most useful signal in command / job output
5846
+ * (errors, exit summaries, the last thing that happened) lives at the END.
5847
+ * When `text` exceeds the byte budget the HEAD is dropped and replaced with a
5848
+ * marker, keeping as much of the tail as fits.
5849
+ *
5850
+ * The budget is a UTF-8 *byte* count, not a character count — wire/output
5851
+ * accounting is bytes, and a naive `String.prototype.slice` (UTF-16 code
5852
+ * units) under-counts multibyte text badly. The cut always lands on a whole
5853
+ * code point: the walk steps by code point (surrogate pairs included), so an
5854
+ * emoji or CJK glyph is never split into a lone surrogate. As a final safety
5855
+ * net against callers that hand us text already sliced mid-codepoint at a raw
5856
+ * byte boundary (the classic `Buffer.subarray(...).toString()` pattern, which
5857
+ * decodes a partial lead/continuation byte to U+FFFD), a leading run of
5858
+ * replacement characters is stripped from the kept tail.
5859
+ */
5860
+ function defaultMarker(droppedBytes) {
5861
+ return `…(${droppedBytes} bytes truncated from head)…\n`;
5862
+ }
5863
+ /**
5864
+ * Keep the last `maxBytes` UTF-8 bytes of `text`, dropping the head and
5865
+ * prefixing a marker. A non-positive `maxBytes` disables truncation and
5866
+ * returns `text` unchanged.
5867
+ *
5868
+ * `maxBytes` budgets the kept tail only; the marker is added on top and may
5869
+ * push the returned string slightly past `maxBytes`. That tradeoff is
5870
+ * intentional — folding the marker into the budget would shrink the content
5871
+ * actually shown.
5872
+ */
5873
+ function tailTruncate(text, maxBytes, options = {}) {
5874
+ if (!Number.isFinite(maxBytes) || maxBytes <= 0) return text;
5875
+ const totalBytes = Buffer.byteLength(text);
5876
+ if (totalBytes <= maxBytes) return text;
5877
+ let bytes = 0;
5878
+ let cut = text.length;
5879
+ while (cut > 0) {
5880
+ let start = cut - 1;
5881
+ const code = text.charCodeAt(start);
5882
+ if (code >= 56320 && code <= 57343 && start > 0) {
5883
+ const high = text.charCodeAt(start - 1);
5884
+ if (high >= 55296 && high <= 56319) start -= 1;
5885
+ }
5886
+ const codePointBytes = Buffer.byteLength(text.slice(start, cut));
5887
+ if (bytes + codePointBytes > maxBytes) break;
5888
+ bytes += codePointBytes;
5889
+ cut = start;
5890
+ }
5891
+ const tail = text.slice(cut).replace(/^\uFFFD+/, "");
5892
+ const droppedBytes = totalBytes - Buffer.byteLength(tail);
5893
+ return `${(options.marker ?? defaultMarker)(droppedBytes)}${tail}`;
5894
+ }
5895
+ //#endregion
5731
5896
  //#region src/tools/shell.ts
5732
5897
  /**
5733
5898
  * Execute a shell command in the agent's execution context.
@@ -6011,19 +6176,19 @@ function createShellTool(opts = {}) {
6011
6176
  const cap = normalizeCap(maxOutputBytes);
6012
6177
  const semantic = interpretShellResult(cmd, result.exitCode);
6013
6178
  if (result.exitCode === 0) {
6014
- const stdoutTail = truncateTail(result.stdout || "(no output)", cap);
6179
+ const stdoutTail = tailTruncate(result.stdout || "(no output)", cap);
6015
6180
  if (!wantMetadata) return stdoutTail;
6016
6181
  const stderrTrimmed = result.stderr.trim();
6017
- return `${stdoutTail}${stderrTrimmed ? `\n[stderr]\n${truncateTail(stderrTrimmed, Math.min(cap, 2048))}` : ""}\n(exit 0, ${durationMs}ms)`;
6182
+ return `${stdoutTail}${stderrTrimmed ? `\n[stderr]\n${tailTruncate(stderrTrimmed, Math.min(cap, 2048))}` : ""}\n(exit 0, ${durationMs}ms)`;
6018
6183
  }
6019
6184
  if (!semantic.isError) {
6020
- const tail = truncateTail((result.stdout || result.stderr || "").trim(), cap);
6185
+ const tail = tailTruncate((result.stdout || result.stderr || "").trim(), cap);
6021
6186
  const semanticFooter = semantic.message ? `\n(${semantic.message})` : "";
6022
6187
  const timingFooter = wantMetadata ? `\n(exit ${result.exitCode}, ${durationMs}ms)` : "";
6023
6188
  return `${tail.length > 0 ? tail : semantic.message ?? "(no output)"}${semanticFooter}${timingFooter}`;
6024
6189
  }
6025
6190
  const combined = `${result.stdout}\n${result.stderr}`.trim();
6026
- return `${wantMetadata ? `Exit code ${result.exitCode} (${durationMs}ms)` : `Exit code ${result.exitCode}`}\n${truncateTail(combined, cap)}`;
6191
+ return `${wantMetadata ? `Exit code ${result.exitCode} (${durationMs}ms)` : `Exit code ${result.exitCode}`}\n${tailTruncate(combined, cap)}`;
6027
6192
  }
6028
6193
  };
6029
6194
  }
@@ -6113,32 +6278,6 @@ function normalizeCap(value) {
6113
6278
  if (value < 0) return DEFAULT_MAX_OUTPUT_BYTES;
6114
6279
  return Math.floor(value);
6115
6280
  }
6116
- /**
6117
- * Tail-priority byte truncation. When `text` exceeds `cap` bytes, the head is
6118
- * dropped and replaced with a marker. Always cuts on character boundaries (no
6119
- * mid-codepoint splits) by walking from the end with `Buffer.byteLength`.
6120
- *
6121
- * `cap === 0` disables truncation. `cap` is interpreted as a UTF-8 byte budget
6122
- * for the tail itself — the marker is added on top and may push the visible
6123
- * length slightly past `cap`. That tradeoff is intentional: a marker that
6124
- * always fits inside the budget would shrink the actual content displayed.
6125
- */
6126
- function truncateTail(text, cap) {
6127
- if (cap === 0) return text;
6128
- const totalBytes = Buffer.byteLength(text);
6129
- if (totalBytes <= cap) return text;
6130
- let bytes = 0;
6131
- let charIdx = text.length;
6132
- while (charIdx > 0) {
6133
- const ch = text[charIdx - 1];
6134
- const chBytes = Buffer.byteLength(ch);
6135
- if (bytes + chBytes > cap) break;
6136
- bytes += chBytes;
6137
- charIdx--;
6138
- }
6139
- const tail = text.slice(charIdx);
6140
- return `…(${totalBytes - Buffer.byteLength(tail)} bytes truncated from head)…\n${tail}`;
6141
- }
6142
6281
  //#endregion
6143
6282
  //#region src/tools/binary-detect.ts
6144
6283
  /**
@@ -6621,7 +6760,7 @@ const waitTask = {
6621
6760
  async execute(input, ctx) {
6622
6761
  const taskId = input.task_id;
6623
6762
  if (!ctx.execution.waitBackground) return `wait_task error: the active execution context (${ctx.execution.type}) does not support waiting on background tasks.`;
6624
- if (ctx.execution.listBackground) {
6763
+ if (resolveDetachedTasksCapability(ctx.execution) !== "durable" && ctx.execution.listBackground) {
6625
6764
  if (!(await ctx.execution.listBackground(ctx.handle)).some((e) => e.taskId === taskId)) return `wait_task: no such task "${taskId}". It may have already exited and been cleaned up, or it was never started in this session.`;
6626
6765
  }
6627
6766
  const requested = typeof input.timeout_ms === "number" && Number.isFinite(input.timeout_ms) && input.timeout_ms > 0 ? input.timeout_ms : DEFAULT_TIMEOUT_MS;
@@ -7251,7 +7390,7 @@ function validateAndPrepareResume(session, prompt, hasPendingTaskNotifications =
7251
7390
  }
7252
7391
  return resumeFilteredTurns;
7253
7392
  }
7254
- function createAgent({ provider, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock }) {
7393
+ function createAgent({ provider, name: agentName, system: agentSystem, tools: agentTools, toolAliases, behavior: agentBehavior, execution, mcpServers, session, readState: agentReadState, skills: agentSkills, mcpConnector, mcpToolWrap, eager, hooks: initialHooks, clock: agentClock, toolKill }) {
7255
7394
  const hooks = createHooks();
7256
7395
  const executionContext = execution ?? createProcessContext();
7257
7396
  const sourceTools = agentTools ?? {};
@@ -7277,7 +7416,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
7277
7416
  const pendingTaskNotifications = /* @__PURE__ */ new Map();
7278
7417
  const pendingStallNotifications = /* @__PURE__ */ new Map();
7279
7418
  const notifiedTaskIds = /* @__PURE__ */ new Set();
7280
- const pendingToolCancels = /* @__PURE__ */ new Map();
7419
+ const toolCancels = createToolCancelRegistry(toolKill?.defaultMessage !== void 0 ? { defaultMessage: toolKill.defaultMessage } : {});
7281
7420
  let executionHandle = null;
7282
7421
  let mcpConnection = null;
7283
7422
  let lastContextAssembly = null;
@@ -7355,6 +7494,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
7355
7494
  let externalAbortListener;
7356
7495
  const externalSignal = options.signal;
7357
7496
  running = true;
7497
+ toolCancels.clearPending();
7358
7498
  try {
7359
7499
  abortController = new AbortController();
7360
7500
  idlePromise = new Promise((resolve) => {
@@ -7625,7 +7765,9 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
7625
7765
  const reconciled = new Map(pendingTaskNotifications);
7626
7766
  pendingTaskNotifications.clear();
7627
7767
  if (executionContext.listBackground && executionHandle && typeof resolvedBehavior?.tasksDir === "string" && resolvedBehavior.tasksDir.length > 0) try {
7628
- const entries = await executionContext.listBackground(executionHandle);
7768
+ const listBackground = executionContext.listBackground;
7769
+ const handle = executionHandle;
7770
+ const entries = options.journalReconcile ? await options.journalReconcile(() => listBackground(handle)) : await listBackground(handle);
7629
7771
  const acks = entries.some((e) => e.status !== "running") ? collectTaskAcksFromTurns(session ? session.turns : turns) : void 0;
7630
7772
  for (const entry of entries) {
7631
7773
  if (entry.status === "running" || notifiedTaskIds.has(entry.taskId) || reconciled.has(entry.taskId)) continue;
@@ -7837,7 +7979,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
7837
7979
  providerName: provider.name,
7838
7980
  runStartMs,
7839
7981
  runToolCounts: {},
7840
- pendingToolCancels,
7982
+ toolCancels,
7841
7983
  usageMirror
7842
7984
  });
7843
7985
  const parentTurnCost = stats.turnUsage?.reduce((sum, t) => sum + (t.cost ?? 0), 0) ?? 0;
@@ -7979,10 +8121,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
7979
8121
  abortController?.abort();
7980
8122
  }
7981
8123
  function cancelTool(callId, reason) {
7982
- const controller = pendingToolCancels.get(callId);
7983
- if (!controller || controller.signal.aborted) return false;
7984
- controller.abort(reason ?? "user-cancelled-tool");
7985
- return true;
8124
+ return toolCancels.cancel(callId, reason);
7986
8125
  }
7987
8126
  async function killBackgroundTask(taskId) {
7988
8127
  if (!executionHandle) return false;
@@ -8167,8 +8306,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
8167
8306
  pendingTaskNotifications.clear();
8168
8307
  pendingStallNotifications.clear();
8169
8308
  if (abortController && !abortController.signal.aborted) abortController.abort("agent-destroyed");
8170
- for (const controller of pendingToolCancels.values()) if (!controller.signal.aborted) controller.abort("agent-destroyed");
8171
- pendingToolCancels.clear();
8309
+ toolCancels.abortAll("agent-destroyed");
8172
8310
  const destroyTimeoutMs = resolveTimeoutMs(agentBehavior?.destroyTimeoutMs, DEFAULT_DESTROY_TIMEOUT_MS);
8173
8311
  if (mcpWarmupPromise) try {
8174
8312
  await withTimeout(mcpWarmupPromise, {
@@ -10059,6 +10197,6 @@ const writeFile$1 = {
10059
10197
  }
10060
10198
  };
10061
10199
  //#endregion
10062
- export { stripImagesFromTurns as $, PERSISTENCE_PREVIEW_BYTES as A, selectRecentFiles as B, stableStringify as C, TOOL_USE_SKIPPED_MESSAGE as D, TOOL_USE_CANCELLED_MESSAGE as E, resolvePersistDir as F, buildCompactPrompt as G, BASE_INSTRUCTIONS as H, resolveTasksDir as I, buildTailCompactPrompt as J, buildFromCompactPrompt as K, buildPostCompactAttachments as L, cleanupPersistedSession as M, maybePersistToolResult as N, validateToolArgs as O, resolveMcpWarningsDir as P, sliceForCompaction as Q, selectFilesFromReadState as R, normalizeShellCommand as S, SHELL_CASCADE_CANCEL_MESSAGE as T, NO_TOOLS_PREAMBLE as U, compactConversation as V, TRAILER as W, ANCHOR_PREVIEW_MAX_CHARS as X, buildUpToCompactPrompt as Y, anchorPreviewFor as Z, createSkillsReadTool as _, multiEdit as a, withTimeout as at, defaultRepeatGuardNormalize as b, grep as c, effectiveContextWindow as ct, createAgent as d, summaryToTurn as et, WAIT_TASK_TIMED_OUT_PREFIX as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, OperationTimeoutError as it, buildPersistedStub as j, PERSISTED_STUB_PREFIX as k, glob as l, shouldAutoCompact as lt, createToolSearchTool as m, createSpawnTool as n, CompactInvalidInputError as nt, listFiles as o, AUTO_COMPACT_MIN_GROWTH_FRACTION as ot, waitTask as p, buildFullCompactPrompt as q, shellKill as r, CompactPromptTooLongError as rt, createInteractionTool as s, OUTPUT_RESERVE_TOKENS as st, writeFile$1 as t, truncateHeadForPtlRetry as tt, edit as u, createShellTool as v, INTERRUPT_MESSAGE_FOR_TOOL_USE as w, defaultRepeatGuardTracked as x, shell as y, selectFilesFromSession as z };
10200
+ export { sliceForCompaction as $, PERSISTED_STUB_PREFIX as A, selectFilesFromSession as B, normalizeShellCommand as C, TOOL_USE_CANCELLED_MESSAGE as D, SHELL_CASCADE_CANCEL_MESSAGE as E, resolveMcpWarningsDir as F, TRAILER as G, compactConversation as H, resolvePersistDir as I, buildFullCompactPrompt as J, buildCompactPrompt as K, resolveTasksDir as L, buildPersistedStub as M, cleanupPersistedSession as N, TOOL_USE_SKIPPED_MESSAGE as O, maybePersistToolResult as P, anchorPreviewFor as Q, buildPostCompactAttachments as R, defaultRepeatGuardTracked as S, INTERRUPT_MESSAGE_FOR_TOOL_USE as T, BASE_INSTRUCTIONS as U, selectRecentFiles as V, NO_TOOLS_PREAMBLE as W, buildUpToCompactPrompt as X, buildTailCompactPrompt as Y, ANCHOR_PREVIEW_MAX_CHARS as Z, createSkillsReadTool as _, multiEdit as a, OperationTimeoutError as at, tailTruncate as b, grep as c, OUTPUT_RESERVE_TOKENS as ct, createAgent as d, stripImagesFromTurns as et, WAIT_TASK_TIMED_OUT_PREFIX as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, CompactPromptTooLongError as it, PERSISTENCE_PREVIEW_BYTES as j, validateToolArgs as k, glob as l, effectiveContextWindow as lt, createToolSearchTool as m, createSpawnTool as n, truncateHeadForPtlRetry as nt, listFiles as o, withTimeout as ot, waitTask as p, buildFromCompactPrompt as q, shellKill as r, CompactInvalidInputError as rt, createInteractionTool as s, AUTO_COMPACT_MIN_GROWTH_FRACTION as st, writeFile$1 as t, summaryToTurn as tt, edit as u, shouldAutoCompact as ut, createShellTool as v, stableStringify as w, defaultRepeatGuardNormalize as x, shell as y, selectFilesFromReadState as z };
10063
10201
 
10064
- //# sourceMappingURL=tools-DhzKzB1y.js.map
10202
+ //# sourceMappingURL=tools-BvATiiCO.js.map