zidane 5.3.0 → 5.3.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.
- package/dist/{agent-CYpPKn5Z.d.ts → agent-bKs7MRT2.d.ts} +430 -5
- package/dist/agent-bKs7MRT2.d.ts.map +1 -0
- package/dist/chat.d.ts +310 -6
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -2
- package/dist/{errors-COmsomd5.js → errors-Byb0F8B9.js} +44 -2
- package/dist/errors-Byb0F8B9.js.map +1 -0
- package/dist/{index-D-cTScN3.d.ts → index-BlMvPh9X.d.ts} +57 -10
- package/dist/index-BlMvPh9X.d.ts.map +1 -0
- package/dist/{index-Cc-q1hLT.d.ts → index-CTmNaIDb.d.ts} +2 -2
- package/dist/{index-Cc-q1hLT.d.ts.map → index-CTmNaIDb.d.ts.map} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +10 -10
- package/dist/{interpolate-BhmHKD6x.js → interpolate-ERgZUxgg.js} +2 -2
- package/dist/{interpolate-BhmHKD6x.js.map → interpolate-ERgZUxgg.js.map} +1 -1
- package/dist/{login-BXVt5wuA.js → login-CNS9_8Ue.js} +3 -3
- package/dist/{login-BXVt5wuA.js.map → login-CNS9_8Ue.js.map} +1 -1
- package/dist/{mcp-B1psg7jf.js → mcp-ZsSFo4Dp.js} +2 -2
- package/dist/{mcp-B1psg7jf.js.map → mcp-ZsSFo4Dp.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/{messages-DsbMYNmt.js → messages-D0xT979U.js} +631 -68
- package/dist/messages-D0xT979U.js.map +1 -0
- package/dist/{presets-tvD28pCu.js → presets-h5i3kpOP.js} +29 -10
- package/dist/presets-h5i3kpOP.js.map +1 -0
- package/dist/presets.d.ts +2 -2
- package/dist/presets.js +1 -1
- package/dist/{providers-v1Rn2rqG.js → providers-x3LZByR5.js} +38 -6
- package/dist/providers-x3LZByR5.js.map +1 -0
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +3 -3
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session/sqlite.js +1 -1
- package/dist/{session-DOJgRXvF.js → session-BHZwxmfr.js} +2 -2
- package/dist/{session-DOJgRXvF.js.map → session-BHZwxmfr.js.map} +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/session.js +2 -2
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js +1 -1
- package/dist/{tools-CMVruxF0.js → tools-CWEDS2ZT.js} +380 -48
- package/dist/tools-CWEDS2ZT.js.map +1 -0
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-eyhlGeBI.d.ts → transcript-anchors-DOUqyvXR.d.ts} +28 -4
- package/dist/transcript-anchors-DOUqyvXR.d.ts.map +1 -0
- package/dist/tui.d.ts +29 -3
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +365 -80
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-Y7e15gJf.js → turn-operations-D9HvatsR.js} +678 -33
- package/dist/turn-operations-D9HvatsR.js.map +1 -0
- package/dist/types-IcokUOyC.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/package.json +1 -1
- package/dist/agent-CYpPKn5Z.d.ts.map +0 -1
- package/dist/errors-COmsomd5.js.map +0 -1
- package/dist/index-D-cTScN3.d.ts.map +0 -1
- package/dist/messages-DsbMYNmt.js.map +0 -1
- package/dist/presets-tvD28pCu.js.map +0 -1
- package/dist/providers-v1Rn2rqG.js.map +0 -1
- package/dist/tools-CMVruxF0.js.map +0 -1
- package/dist/transcript-anchors-eyhlGeBI.d.ts.map +0 -1
- package/dist/turn-operations-Y7e15gJf.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as createProcessContext } from "./contexts-BwiHIr2w.js";
|
|
2
|
-
import {
|
|
2
|
+
import { a as AgentToolPairingError, l as toTypedError, r as AgentProviderError, s as errorMessage, t as AgentAbortedError } from "./errors-Byb0F8B9.js";
|
|
3
3
|
import { t as toolOutputByteLength } from "./types-IcokUOyC.js";
|
|
4
|
-
import {
|
|
5
|
-
import { t as connectMcpServers } from "./mcp-
|
|
6
|
-
import { _ as validateResourcePath, b as createSkillActivationState, d as escapeXml, n as resolveSkills, p as installAllowedToolsGate, t as interpolateShellCommands, u as buildCatalog } from "./interpolate-
|
|
4
|
+
import { a as detectTurnInterruption, n as SYNTHETIC_TOOL_RESULT_PLACEHOLDER, o as ensureToolResultPairing, s as filterUnresolvedToolUses } from "./messages-D0xT979U.js";
|
|
5
|
+
import { t as connectMcpServers } from "./mcp-ZsSFo4Dp.js";
|
|
6
|
+
import { _ as validateResourcePath, b as createSkillActivationState, d as escapeXml, n as resolveSkills, p as installAllowedToolsGate, t as interpolateShellCommands, u as buildCatalog } from "./interpolate-ERgZUxgg.js";
|
|
7
7
|
import { n as formatTokenUsage, t as flattenTurns } from "./stats-DgOvY7wd.js";
|
|
8
8
|
import { createHooks } from "hookable";
|
|
9
9
|
import { mkdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -480,6 +480,7 @@ function validateToolArgs(input, schema) {
|
|
|
480
480
|
};
|
|
481
481
|
let coerced;
|
|
482
482
|
const coercions = [];
|
|
483
|
+
let droppedItems;
|
|
483
484
|
for (const [key, value] of Object.entries(input)) {
|
|
484
485
|
const propSchema = properties[key];
|
|
485
486
|
if (!propSchema?.type) continue;
|
|
@@ -494,11 +495,138 @@ function validateToolArgs(input, schema) {
|
|
|
494
495
|
coerced[key] = outcome.value;
|
|
495
496
|
coercions.push(key);
|
|
496
497
|
}
|
|
498
|
+
const arrayValue = outcome.changed ? outcome.value : value;
|
|
499
|
+
if (propSchema.type === "array" && propSchema.items && Array.isArray(arrayValue)) {
|
|
500
|
+
const itemOutcome = validateArrayItems(arrayValue, propSchema);
|
|
501
|
+
if (itemOutcome.error) return {
|
|
502
|
+
valid: false,
|
|
503
|
+
error: `Field "${key}": ${itemOutcome.error}`
|
|
504
|
+
};
|
|
505
|
+
if (itemOutcome.changed || itemOutcome.dropped.length > 0 || itemOutcome.truncated) {
|
|
506
|
+
if (!coerced) coerced = { ...input };
|
|
507
|
+
coerced[key] = itemOutcome.items;
|
|
508
|
+
if (!coercions.includes(key)) coercions.push(key);
|
|
509
|
+
}
|
|
510
|
+
if (itemOutcome.dropped.length > 0) {
|
|
511
|
+
if (!droppedItems) droppedItems = {};
|
|
512
|
+
droppedItems[key] = itemOutcome.dropped;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
497
515
|
}
|
|
498
516
|
return {
|
|
499
517
|
valid: true,
|
|
500
518
|
coercedInput: coerced ?? input,
|
|
501
|
-
coercions
|
|
519
|
+
coercions,
|
|
520
|
+
...droppedItems ? { droppedItems } : {}
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
function validateArrayItems(items, schema) {
|
|
524
|
+
if (schema.minItems !== void 0 && items.length < schema.minItems) return {
|
|
525
|
+
items,
|
|
526
|
+
changed: false,
|
|
527
|
+
truncated: false,
|
|
528
|
+
dropped: [],
|
|
529
|
+
error: `expected at least ${schema.minItems} item${schema.minItems === 1 ? "" : "s"}, got ${items.length}`
|
|
530
|
+
};
|
|
531
|
+
const itemSchema = schema.items;
|
|
532
|
+
if (!itemSchema) return {
|
|
533
|
+
items,
|
|
534
|
+
changed: false,
|
|
535
|
+
truncated: false,
|
|
536
|
+
dropped: []
|
|
537
|
+
};
|
|
538
|
+
const out = [];
|
|
539
|
+
const outOriginalIdx = [];
|
|
540
|
+
const dropped = [];
|
|
541
|
+
let changed = false;
|
|
542
|
+
for (let i = 0; i < items.length; i++) {
|
|
543
|
+
const item = items[i];
|
|
544
|
+
const v = validateOneItem(item, itemSchema);
|
|
545
|
+
if (v.dropped) {
|
|
546
|
+
dropped.push(i);
|
|
547
|
+
changed = true;
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
if (v.changed) changed = true;
|
|
551
|
+
out.push(v.value);
|
|
552
|
+
outOriginalIdx.push(i);
|
|
553
|
+
}
|
|
554
|
+
let truncated = false;
|
|
555
|
+
if (schema.maxItems !== void 0 && out.length > schema.maxItems) {
|
|
556
|
+
for (let i = schema.maxItems; i < out.length; i++) dropped.push(outOriginalIdx[i]);
|
|
557
|
+
out.length = schema.maxItems;
|
|
558
|
+
truncated = true;
|
|
559
|
+
changed = true;
|
|
560
|
+
}
|
|
561
|
+
dropped.sort((a, b) => a - b);
|
|
562
|
+
return {
|
|
563
|
+
items: out,
|
|
564
|
+
changed,
|
|
565
|
+
truncated,
|
|
566
|
+
dropped
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function validateOneItem(item, schema) {
|
|
570
|
+
if (schema.type === "object") {
|
|
571
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return {
|
|
572
|
+
value: item,
|
|
573
|
+
changed: false,
|
|
574
|
+
dropped: true
|
|
575
|
+
};
|
|
576
|
+
const obj = item;
|
|
577
|
+
const required = schema.required ?? [];
|
|
578
|
+
for (const field of required) {
|
|
579
|
+
const v = obj[field];
|
|
580
|
+
if (v === void 0 || v === null) return {
|
|
581
|
+
value: item,
|
|
582
|
+
changed: false,
|
|
583
|
+
dropped: true
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
const properties = schema.properties ?? {};
|
|
587
|
+
let coercedItem;
|
|
588
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
589
|
+
const subSchema = properties[key];
|
|
590
|
+
if (!subSchema?.type) continue;
|
|
591
|
+
if (value === void 0 || value === null) continue;
|
|
592
|
+
const outcome = coerceValue(value, subSchema);
|
|
593
|
+
if (outcome.error) return {
|
|
594
|
+
value: item,
|
|
595
|
+
changed: false,
|
|
596
|
+
dropped: true
|
|
597
|
+
};
|
|
598
|
+
if (outcome.changed) {
|
|
599
|
+
if (!coercedItem) coercedItem = { ...obj };
|
|
600
|
+
coercedItem[key] = outcome.value;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return coercedItem ? {
|
|
604
|
+
value: coercedItem,
|
|
605
|
+
changed: true,
|
|
606
|
+
dropped: false
|
|
607
|
+
} : {
|
|
608
|
+
value: item,
|
|
609
|
+
changed: false,
|
|
610
|
+
dropped: false
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
if (schema.type) {
|
|
614
|
+
const outcome = coerceValue(item, schema);
|
|
615
|
+
if (outcome.error) return {
|
|
616
|
+
value: item,
|
|
617
|
+
changed: false,
|
|
618
|
+
dropped: true
|
|
619
|
+
};
|
|
620
|
+
return {
|
|
621
|
+
value: outcome.value,
|
|
622
|
+
changed: outcome.changed,
|
|
623
|
+
dropped: false
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
return {
|
|
627
|
+
value: item,
|
|
628
|
+
changed: false,
|
|
629
|
+
dropped: false
|
|
502
630
|
};
|
|
503
631
|
}
|
|
504
632
|
function coerceValue(value, schema) {
|
|
@@ -628,6 +756,30 @@ function formatValue(value) {
|
|
|
628
756
|
//#region src/loop.ts
|
|
629
757
|
const IMAGE_OMITTED_MARKER = "[image omitted — model does not support vision]";
|
|
630
758
|
/**
|
|
759
|
+
* Canonical tool_result text emitted when a tool call is interrupted by the
|
|
760
|
+
* user mid-flight (Esc / Ctrl-C / external `AbortSignal`). Mirrors Claude
|
|
761
|
+
* Code's `INTERRUPT_MESSAGE_FOR_TOOL_USE` so downstream consumers can pattern
|
|
762
|
+
* match a single string across both harnesses. Always paired with
|
|
763
|
+
* `isError: true` on the wire — the model treats it as a failed call rather
|
|
764
|
+
* than a successful tool response.
|
|
765
|
+
*/
|
|
766
|
+
const INTERRUPT_MESSAGE_FOR_TOOL_USE = "[Request interrupted by user for tool use]";
|
|
767
|
+
/**
|
|
768
|
+
* Canonical tool_result text emitted when a tool call is skipped because a
|
|
769
|
+
* sibling sequential call errored or a steering message arrived between
|
|
770
|
+
* iterations of {@link executeToolsSequential}. Distinguished from
|
|
771
|
+
* {@link INTERRUPT_MESSAGE_FOR_TOOL_USE} so consumers can distinguish "user
|
|
772
|
+
* cancelled" from "framework superseded".
|
|
773
|
+
*/
|
|
774
|
+
const TOOL_USE_SKIPPED_MESSAGE = "[Tool use skipped — superseded by user message]";
|
|
775
|
+
/**
|
|
776
|
+
* Canonical tool_result text emitted when the loop catches a sequential
|
|
777
|
+
* sibling that threw and synthesizes follow-up results for the remaining
|
|
778
|
+
* queued calls. Distinct from {@link TOOL_USE_SKIPPED_MESSAGE} so telemetry
|
|
779
|
+
* can split "skipped by user steering" from "skipped after error".
|
|
780
|
+
*/
|
|
781
|
+
const TOOL_USE_AFTER_ERROR_MESSAGE = "[Tool use skipped — previous tool call in batch threw]";
|
|
782
|
+
/**
|
|
631
783
|
* Compute the effective thinking budget for a given run-relative turn, given
|
|
632
784
|
* the configured decay schedule. Pure helper — exported for tests and so
|
|
633
785
|
* downstream tooling can preview decay curves without spinning up the loop.
|
|
@@ -929,6 +1081,32 @@ function invalidateReadStateForElidedPaths(session, elidedPaths) {
|
|
|
929
1081
|
const suffixes = elidedPaths.map((p) => `::${p}`);
|
|
930
1082
|
for (const key of [...readState.keys()]) if (suffixes.some((s) => key.endsWith(s))) readState.delete(key);
|
|
931
1083
|
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Run {@link ensureToolResultPairing} with the loop's hook + strict-mode
|
|
1086
|
+
* context plugged in. Centralized so the pre-send path and the schema-
|
|
1087
|
+
* enforcement path share identical telemetry + throw semantics.
|
|
1088
|
+
*
|
|
1089
|
+
* The captured `repairs` array is what `AgentToolPairingError` carries on
|
|
1090
|
+
* strict-mode throws, and it's what `pairing:repair` fires from. Hook
|
|
1091
|
+
* notifications run AFTER the pass completes so they don't interfere with
|
|
1092
|
+
* the synchronous walk — and we drop them on the floor in strict mode (the
|
|
1093
|
+
* throw is more informative than a fire-and-forget log).
|
|
1094
|
+
*/
|
|
1095
|
+
function applyPairingRepair(ctx, messages, turnId) {
|
|
1096
|
+
const repairs = [];
|
|
1097
|
+
const repaired = ensureToolResultPairing(messages, { onRepair: (repair) => repairs.push(repair) });
|
|
1098
|
+
if (repairs.length === 0) return repaired;
|
|
1099
|
+
if (ctx.strictToolPairing) throw new AgentToolPairingError({
|
|
1100
|
+
message: `Tool pairing corruption detected (${repairs.length} repair${repairs.length === 1 ? "" : "s"}); strict mode is on so the request was not sent.`,
|
|
1101
|
+
...ctx.providerName ? { provider: ctx.providerName } : {},
|
|
1102
|
+
repairs
|
|
1103
|
+
});
|
|
1104
|
+
for (const repair of repairs) ctx.hooks.callHook("pairing:repair", {
|
|
1105
|
+
...repair,
|
|
1106
|
+
turnId
|
|
1107
|
+
});
|
|
1108
|
+
return repaired;
|
|
1109
|
+
}
|
|
932
1110
|
function sanitizeStoredToolResults(provider, messages) {
|
|
933
1111
|
if (provider.meta.capabilities?.vision !== false) return messages;
|
|
934
1112
|
return messages.map((msg) => {
|
|
@@ -1060,6 +1238,27 @@ function wrapProviderError(err, ctx) {
|
|
|
1060
1238
|
cause: err
|
|
1061
1239
|
});
|
|
1062
1240
|
}
|
|
1241
|
+
/** Max bytes of provider error text inlined into the assistant turn placeholder. */
|
|
1242
|
+
const ERROR_PLACEHOLDER_MAX = 280;
|
|
1243
|
+
/**
|
|
1244
|
+
* Build the assistant-turn placeholder text when the provider throws before
|
|
1245
|
+
* streaming any output. Inlines the underlying error message (truncated and
|
|
1246
|
+
* stripped of stack-like newlines) so the persisted turn carries a useful
|
|
1247
|
+
* diagnostic — the human reading the transcript sees the failure mode
|
|
1248
|
+
* without having to attach a debugger, and `tool_search` schema rejections
|
|
1249
|
+
* become self-explanatory.
|
|
1250
|
+
*
|
|
1251
|
+
* The bracketed `[✗ Streaming failed: ...]` shape preserves the prior
|
|
1252
|
+
* format that hosts may pattern-match on while adding the new payload
|
|
1253
|
+
* suffix. Falls back to the original generic placeholder when no message
|
|
1254
|
+
* can be extracted.
|
|
1255
|
+
*/
|
|
1256
|
+
function buildStreamErrorPlaceholder(err) {
|
|
1257
|
+
const raw = errorMessage(err).trim();
|
|
1258
|
+
if (raw.length === 0) return "[✗ Streaming failed before any output.]";
|
|
1259
|
+
const oneLine = raw.replace(/\s+/g, " ");
|
|
1260
|
+
return `[✗ Streaming failed before any output: ${oneLine.length > ERROR_PLACEHOLDER_MAX ? `${oneLine.slice(0, ERROR_PLACEHOLDER_MAX - 1).trimEnd()}…` : oneLine}]`;
|
|
1261
|
+
}
|
|
1063
1262
|
async function executeTurn(ctx, turn) {
|
|
1064
1263
|
const turnId = await ctx.generateTurnId();
|
|
1065
1264
|
let canonicalMessages = turnsToMessages(applyCompactSummaryCutoff(ctx.turns));
|
|
@@ -1091,7 +1290,7 @@ async function executeTurn(ctx, turn) {
|
|
|
1091
1290
|
const transformCtx = { messages: streamOptions.messages };
|
|
1092
1291
|
await ctx.hooks.callHook("context:transform", transformCtx);
|
|
1093
1292
|
streamOptions.messages = transformCtx.messages;
|
|
1094
|
-
streamOptions.messages =
|
|
1293
|
+
streamOptions.messages = applyPairingRepair(ctx, streamOptions.messages, turnId);
|
|
1095
1294
|
const systemCtx = {
|
|
1096
1295
|
system: streamOptions.system,
|
|
1097
1296
|
messages: streamOptions.messages,
|
|
@@ -1137,12 +1336,13 @@ async function executeTurn(ctx, turn) {
|
|
|
1137
1336
|
input: 0,
|
|
1138
1337
|
output: 0
|
|
1139
1338
|
};
|
|
1339
|
+
const placeholderText = wasAborted ? "[⏹ Streaming was aborted.]" : buildStreamErrorPlaceholder(err);
|
|
1140
1340
|
const errorContent = currentText ? [{
|
|
1141
1341
|
type: "text",
|
|
1142
1342
|
text: currentText
|
|
1143
1343
|
}] : [{
|
|
1144
1344
|
type: "text",
|
|
1145
|
-
text:
|
|
1345
|
+
text: placeholderText
|
|
1146
1346
|
}];
|
|
1147
1347
|
const errorTurn = {
|
|
1148
1348
|
id: turnId,
|
|
@@ -1153,6 +1353,10 @@ async function executeTurn(ctx, turn) {
|
|
|
1153
1353
|
createdAt: Date.now()
|
|
1154
1354
|
};
|
|
1155
1355
|
ctx.turns.push(errorTurn);
|
|
1356
|
+
if (!wasAborted) await ctx.hooks.callHook("stream:error", {
|
|
1357
|
+
err,
|
|
1358
|
+
turnId
|
|
1359
|
+
});
|
|
1156
1360
|
await ctx.hooks.callHook("turn:after", {
|
|
1157
1361
|
turn,
|
|
1158
1362
|
turnId,
|
|
@@ -1205,7 +1409,7 @@ async function executeTurn(ctx, turn) {
|
|
|
1205
1409
|
description: "Return the final structured output matching the required schema.",
|
|
1206
1410
|
inputSchema: ctx.schema
|
|
1207
1411
|
};
|
|
1208
|
-
const schemaMessages =
|
|
1412
|
+
const schemaMessages = applyPairingRepair(ctx, rewriteMessagesToWire(turnsToMessages(applyCompactSummaryCutoff(ctx.turns)), ctx.aliasMaps), turnId);
|
|
1209
1413
|
let schemaResult;
|
|
1210
1414
|
try {
|
|
1211
1415
|
schemaResult = await ctx.provider.stream({
|
|
@@ -1351,14 +1555,35 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1351
1555
|
runToolCounts
|
|
1352
1556
|
};
|
|
1353
1557
|
await ctx.hooks.callHook("tool:gate", gateCtx);
|
|
1354
|
-
if (gateCtx.block)
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1558
|
+
if (gateCtx.block) {
|
|
1559
|
+
await fireDispatched(ctx, {
|
|
1560
|
+
turnId,
|
|
1561
|
+
callId,
|
|
1562
|
+
name: call.name,
|
|
1563
|
+
displayName,
|
|
1564
|
+
input: gateCtx.input,
|
|
1565
|
+
outcome: "gate-block",
|
|
1566
|
+
reason: gateCtx.reason,
|
|
1567
|
+
runToolCounts
|
|
1568
|
+
});
|
|
1569
|
+
return { result: {
|
|
1570
|
+
id: callId,
|
|
1571
|
+
content: `Blocked: ${gateCtx.reason}`,
|
|
1572
|
+
isError: true
|
|
1573
|
+
} };
|
|
1574
|
+
}
|
|
1358
1575
|
ctx.runToolCounts[call.name] = (ctx.runToolCounts[call.name] ?? 0) + 1;
|
|
1359
|
-
if (gateCtx.result !== void 0)
|
|
1360
|
-
|
|
1361
|
-
|
|
1576
|
+
if (gateCtx.result !== void 0) {
|
|
1577
|
+
await fireDispatched(ctx, {
|
|
1578
|
+
turnId,
|
|
1579
|
+
callId,
|
|
1580
|
+
name: call.name,
|
|
1581
|
+
displayName,
|
|
1582
|
+
input: gateCtx.input,
|
|
1583
|
+
outcome: "gate-substitute",
|
|
1584
|
+
runToolCounts
|
|
1585
|
+
});
|
|
1586
|
+
const emitted = await emitToolResult(ctx, {
|
|
1362
1587
|
turnId,
|
|
1363
1588
|
callId,
|
|
1364
1589
|
name: call.name,
|
|
@@ -1367,8 +1592,13 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1367
1592
|
output: gateCtx.result,
|
|
1368
1593
|
isError: false,
|
|
1369
1594
|
runToolCounts
|
|
1370
|
-
})
|
|
1371
|
-
|
|
1595
|
+
});
|
|
1596
|
+
return { result: {
|
|
1597
|
+
id: callId,
|
|
1598
|
+
content: emitted.output,
|
|
1599
|
+
...emitted.isError ? { isError: true } : {}
|
|
1600
|
+
} };
|
|
1601
|
+
}
|
|
1372
1602
|
let effectiveInput = gateCtx.input;
|
|
1373
1603
|
if (!toolDef) {
|
|
1374
1604
|
const unknownCtx = {
|
|
@@ -1381,6 +1611,7 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1381
1611
|
};
|
|
1382
1612
|
await ctx.hooks.callHook("tool:unknown", unknownCtx);
|
|
1383
1613
|
const content = unknownCtx.result ?? `Tool error: Unknown tool: ${call.name}`;
|
|
1614
|
+
const isError = unknownCtx.result === void 0;
|
|
1384
1615
|
if (!unknownCtx.suppressError) {
|
|
1385
1616
|
const err = /* @__PURE__ */ new Error(`Unknown tool: ${call.name}`);
|
|
1386
1617
|
await ctx.hooks.callHook("tool:error", {
|
|
@@ -1392,9 +1623,19 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1392
1623
|
error: err
|
|
1393
1624
|
});
|
|
1394
1625
|
}
|
|
1626
|
+
await fireDispatched(ctx, {
|
|
1627
|
+
turnId,
|
|
1628
|
+
callId,
|
|
1629
|
+
name: call.name,
|
|
1630
|
+
displayName,
|
|
1631
|
+
input: effectiveInput,
|
|
1632
|
+
outcome: "unknown",
|
|
1633
|
+
runToolCounts
|
|
1634
|
+
});
|
|
1395
1635
|
return { result: {
|
|
1396
1636
|
id: callId,
|
|
1397
|
-
content
|
|
1637
|
+
content,
|
|
1638
|
+
...isError ? { isError: true } : {}
|
|
1398
1639
|
} };
|
|
1399
1640
|
}
|
|
1400
1641
|
const validation = validateToolArgs(effectiveInput, toolDef.spec.inputSchema);
|
|
@@ -1408,9 +1649,19 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1408
1649
|
reason: validation.error ?? "invalid input",
|
|
1409
1650
|
schema: toolDef.spec.inputSchema
|
|
1410
1651
|
});
|
|
1652
|
+
await fireDispatched(ctx, {
|
|
1653
|
+
turnId,
|
|
1654
|
+
callId,
|
|
1655
|
+
name: call.name,
|
|
1656
|
+
displayName,
|
|
1657
|
+
input: effectiveInput,
|
|
1658
|
+
outcome: "invalid-input",
|
|
1659
|
+
runToolCounts
|
|
1660
|
+
});
|
|
1411
1661
|
return { result: {
|
|
1412
1662
|
id: callId,
|
|
1413
|
-
content: `Validation error: ${validation.error}
|
|
1663
|
+
content: `Validation error: ${validation.error}`,
|
|
1664
|
+
isError: true
|
|
1414
1665
|
} };
|
|
1415
1666
|
}
|
|
1416
1667
|
effectiveInput = validation.coercedInput ?? effectiveInput;
|
|
@@ -1424,6 +1675,15 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1424
1675
|
coercions,
|
|
1425
1676
|
schema: toolDef.spec.inputSchema
|
|
1426
1677
|
});
|
|
1678
|
+
await fireDispatched(ctx, {
|
|
1679
|
+
turnId,
|
|
1680
|
+
callId,
|
|
1681
|
+
name: call.name,
|
|
1682
|
+
displayName,
|
|
1683
|
+
input: effectiveInput,
|
|
1684
|
+
outcome: "execute",
|
|
1685
|
+
runToolCounts
|
|
1686
|
+
});
|
|
1427
1687
|
await ctx.hooks.callHook("tool:before", {
|
|
1428
1688
|
turnId,
|
|
1429
1689
|
callId,
|
|
@@ -1470,26 +1730,54 @@ async function executeSingleTool(ctx, call, turnId) {
|
|
|
1470
1730
|
output = errorCtx.result ?? `Tool error: ${error.message}`;
|
|
1471
1731
|
isError = true;
|
|
1472
1732
|
}
|
|
1733
|
+
const emitted = await emitToolResult(ctx, {
|
|
1734
|
+
turnId,
|
|
1735
|
+
callId,
|
|
1736
|
+
name: call.name,
|
|
1737
|
+
displayName,
|
|
1738
|
+
input: effectiveInput,
|
|
1739
|
+
output,
|
|
1740
|
+
isError,
|
|
1741
|
+
runToolCounts,
|
|
1742
|
+
...coercions ? { coercions } : {}
|
|
1743
|
+
});
|
|
1473
1744
|
return { result: {
|
|
1474
1745
|
id: callId,
|
|
1475
|
-
content:
|
|
1476
|
-
|
|
1477
|
-
callId,
|
|
1478
|
-
name: call.name,
|
|
1479
|
-
displayName,
|
|
1480
|
-
input: effectiveInput,
|
|
1481
|
-
output,
|
|
1482
|
-
isError,
|
|
1483
|
-
runToolCounts,
|
|
1484
|
-
...coercions ? { coercions } : {}
|
|
1485
|
-
})
|
|
1746
|
+
content: emitted.output,
|
|
1747
|
+
...emitted.isError ? { isError: true } : {}
|
|
1486
1748
|
} };
|
|
1487
1749
|
}
|
|
1488
1750
|
/**
|
|
1751
|
+
* Fire `tool:dispatched` with the resolved path discriminator. Every code
|
|
1752
|
+
* path in {@link executeSingleTool} that produces a tool_result must call
|
|
1753
|
+
* this exactly once — that contract is what makes `tool:dispatched` ↔
|
|
1754
|
+
* `tool:after` a guaranteed symmetric pairing for live-event consumers
|
|
1755
|
+
* (the chat layer, SDK consumers reconstructing wire history from events,
|
|
1756
|
+
* tracing spans that want to record refused calls separately from
|
|
1757
|
+
* executed ones).
|
|
1758
|
+
*
|
|
1759
|
+
* Helper exists to centralize the optional-field plumbing for `reason`
|
|
1760
|
+
* (only set on `gate-block`) without sprinkling spread-conditional logic
|
|
1761
|
+
* across five call sites.
|
|
1762
|
+
*/
|
|
1763
|
+
async function fireDispatched(ctx, params) {
|
|
1764
|
+
const { reason, ...rest } = params;
|
|
1765
|
+
await ctx.hooks.callHook("tool:dispatched", {
|
|
1766
|
+
...rest,
|
|
1767
|
+
...reason !== void 0 ? { reason } : {}
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
/**
|
|
1489
1771
|
* Shared post-output emission: fire `tool:transform` (mutate-allowed), strip
|
|
1490
1772
|
* images for non-vision providers, fire `tool:after`. Used by both the
|
|
1491
1773
|
* gate-substitute (Z20) and post-execute paths so they stay byte-for-byte
|
|
1492
1774
|
* identical from the consumer's perspective.
|
|
1775
|
+
*
|
|
1776
|
+
* Returns both the (possibly transformed) output and the final `isError`
|
|
1777
|
+
* flag — `tool:transform` listeners can flip the flag in either direction
|
|
1778
|
+
* (e.g. rewrite a structured error response to a graceful retry hint), and
|
|
1779
|
+
* the caller needs the post-transform value to populate `ToolResult.isError`
|
|
1780
|
+
* on the wire.
|
|
1493
1781
|
*/
|
|
1494
1782
|
async function emitToolResult(ctx, params) {
|
|
1495
1783
|
const { turnId, callId, name, displayName, input, runToolCounts, coercions } = params;
|
|
@@ -1535,7 +1823,10 @@ async function emitToolResult(ctx, params) {
|
|
|
1535
1823
|
runToolCounts,
|
|
1536
1824
|
...coercions ? { coercions } : {}
|
|
1537
1825
|
});
|
|
1538
|
-
return
|
|
1826
|
+
return {
|
|
1827
|
+
output,
|
|
1828
|
+
isError
|
|
1829
|
+
};
|
|
1539
1830
|
}
|
|
1540
1831
|
async function executeToolsSequential(ctx, toolCalls, turnId) {
|
|
1541
1832
|
const results = [];
|
|
@@ -1544,14 +1835,16 @@ async function executeToolsSequential(ctx, toolCalls, turnId) {
|
|
|
1544
1835
|
if (ctx.signal.aborted) {
|
|
1545
1836
|
for (let j = i; j < toolCalls.length; j++) results.push({
|
|
1546
1837
|
id: toolCalls[j].id,
|
|
1547
|
-
content:
|
|
1838
|
+
content: INTERRUPT_MESSAGE_FOR_TOOL_USE,
|
|
1839
|
+
isError: true
|
|
1548
1840
|
});
|
|
1549
1841
|
return results;
|
|
1550
1842
|
}
|
|
1551
1843
|
if (ctx.steeringQueue.length > 0) {
|
|
1552
1844
|
for (let j = i; j < toolCalls.length; j++) results.push({
|
|
1553
1845
|
id: toolCalls[j].id,
|
|
1554
|
-
content:
|
|
1846
|
+
content: TOOL_USE_SKIPPED_MESSAGE,
|
|
1847
|
+
isError: true
|
|
1555
1848
|
});
|
|
1556
1849
|
return results;
|
|
1557
1850
|
}
|
|
@@ -1561,11 +1854,13 @@ async function executeToolsSequential(ctx, toolCalls, turnId) {
|
|
|
1561
1854
|
} catch (err) {
|
|
1562
1855
|
results.push({
|
|
1563
1856
|
id: call.id,
|
|
1564
|
-
content: `Error: ${errorMessage(err)}
|
|
1857
|
+
content: `Error: ${errorMessage(err)}`,
|
|
1858
|
+
isError: true
|
|
1565
1859
|
});
|
|
1566
1860
|
for (let j = i + 1; j < toolCalls.length; j++) results.push({
|
|
1567
1861
|
id: toolCalls[j].id,
|
|
1568
|
-
content:
|
|
1862
|
+
content: TOOL_USE_AFTER_ERROR_MESSAGE,
|
|
1863
|
+
isError: true
|
|
1569
1864
|
});
|
|
1570
1865
|
return results;
|
|
1571
1866
|
}
|
|
@@ -1576,9 +1871,12 @@ async function executeToolsParallel(ctx, toolCalls, turnId) {
|
|
|
1576
1871
|
const executions = toolCalls.map((call) => executeSingleTool(ctx, call, turnId));
|
|
1577
1872
|
return (await Promise.allSettled(executions)).map((s, i) => {
|
|
1578
1873
|
if (s.status === "fulfilled") return s.value.result;
|
|
1874
|
+
const reason = s.reason;
|
|
1875
|
+
const isAbort = ctx.signal.aborted || reason instanceof Error && reason.name === "AbortError";
|
|
1579
1876
|
return {
|
|
1580
1877
|
id: toolCalls[i].id,
|
|
1581
|
-
content: `Error: ${
|
|
1878
|
+
content: isAbort ? INTERRUPT_MESSAGE_FOR_TOOL_USE : `Error: ${reason instanceof Error ? reason.message : String(reason)}`,
|
|
1879
|
+
isError: true
|
|
1582
1880
|
};
|
|
1583
1881
|
});
|
|
1584
1882
|
}
|
|
@@ -2157,8 +2455,10 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2157
2455
|
"stream:text",
|
|
2158
2456
|
"stream:end",
|
|
2159
2457
|
"stream:thinking",
|
|
2458
|
+
"stream:error",
|
|
2160
2459
|
"oauth:refresh",
|
|
2161
2460
|
"tool:gate",
|
|
2461
|
+
"tool:dispatched",
|
|
2162
2462
|
"tool:before",
|
|
2163
2463
|
"tool:after",
|
|
2164
2464
|
"tool:error",
|
|
@@ -2175,8 +2475,10 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2175
2475
|
"child:stream:text",
|
|
2176
2476
|
"child:stream:thinking",
|
|
2177
2477
|
"child:stream:end",
|
|
2478
|
+
"child:stream:error",
|
|
2178
2479
|
"child:tool:gate",
|
|
2179
2480
|
"child:mcp:tool:gate",
|
|
2481
|
+
"child:tool:dispatched",
|
|
2180
2482
|
"child:tool:before",
|
|
2181
2483
|
"child:tool:after",
|
|
2182
2484
|
"child:tool:transform",
|
|
@@ -2205,6 +2507,7 @@ const HOOK_EVENT_SET = new Set([
|
|
|
2205
2507
|
"output",
|
|
2206
2508
|
"budget:exceeded",
|
|
2207
2509
|
"tool-budget:exceeded",
|
|
2510
|
+
"pairing:repair",
|
|
2208
2511
|
"agent:abort",
|
|
2209
2512
|
"agent:done",
|
|
2210
2513
|
"session:start",
|
|
@@ -2224,6 +2527,16 @@ function isKnownHookEvent(event) {
|
|
|
2224
2527
|
* loop from leaving the persisted session with an orphan tool_use — which
|
|
2225
2528
|
* Anthropic rejects on resume.
|
|
2226
2529
|
*
|
|
2530
|
+
* Each synthetic result carries the shared
|
|
2531
|
+
* {@link SYNTHETIC_TOOL_RESULT_PLACEHOLDER} text (so consumers can pattern-
|
|
2532
|
+
* match the same way they would on a live pre-send repair) and
|
|
2533
|
+
* `isError: true` so the model treats it as a failed call.
|
|
2534
|
+
*
|
|
2535
|
+
* Fires `pairing:repair` (mode `orphan-tool-use-append`) for each synthetic
|
|
2536
|
+
* result, mirroring the wire-level repair pass's observability so postmortem
|
|
2537
|
+
* dashboards see the same telemetry shape regardless of where the orphan
|
|
2538
|
+
* was detected.
|
|
2539
|
+
*
|
|
2227
2540
|
* No-op when:
|
|
2228
2541
|
* - The trailing turn isn't an assistant turn (already closed, or session
|
|
2229
2542
|
* ends with the seeded user prompt).
|
|
@@ -2231,7 +2544,7 @@ function isKnownHookEvent(event) {
|
|
|
2231
2544
|
* - All tool_use ids are already answered by a tool_result somewhere later
|
|
2232
2545
|
* in the conversation (defensive — shouldn't happen but cheap to check).
|
|
2233
2546
|
*/
|
|
2234
|
-
function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider) {
|
|
2547
|
+
async function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider, hooks) {
|
|
2235
2548
|
if (turns.length === 0) return;
|
|
2236
2549
|
const last = turns[turns.length - 1];
|
|
2237
2550
|
if (last.role !== "assistant") return;
|
|
@@ -2244,7 +2557,8 @@ function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider) {
|
|
|
2244
2557
|
if (dangling.length === 0) return;
|
|
2245
2558
|
const results = dangling.map((id) => ({
|
|
2246
2559
|
id,
|
|
2247
|
-
content:
|
|
2560
|
+
content: SYNTHETIC_TOOL_RESULT_PLACEHOLDER,
|
|
2561
|
+
isError: true
|
|
2248
2562
|
}));
|
|
2249
2563
|
const msg = provider.toolResultsMessage(results);
|
|
2250
2564
|
turns.push({
|
|
@@ -2254,6 +2568,11 @@ function synthesizeMissingToolResults(turns, syntheticTurnId, runId, provider) {
|
|
|
2254
2568
|
content: msg.content,
|
|
2255
2569
|
createdAt: Date.now()
|
|
2256
2570
|
});
|
|
2571
|
+
for (const callId of dangling) await hooks.callHook("pairing:repair", {
|
|
2572
|
+
mode: "orphan-tool-use-append",
|
|
2573
|
+
callId,
|
|
2574
|
+
messageIndex: turns.length - 2
|
|
2575
|
+
});
|
|
2257
2576
|
}
|
|
2258
2577
|
function resolveBehavior(agentBehavior, runBehavior) {
|
|
2259
2578
|
return {
|
|
@@ -2278,7 +2597,8 @@ function resolveBehavior(agentBehavior, runBehavior) {
|
|
|
2278
2597
|
toolSearch: runBehavior?.toolSearch ?? agentBehavior?.toolSearch,
|
|
2279
2598
|
persistThreshold: runBehavior?.persistThreshold ?? agentBehavior?.persistThreshold,
|
|
2280
2599
|
persistExcludeTools: runBehavior?.persistExcludeTools ?? agentBehavior?.persistExcludeTools,
|
|
2281
|
-
persistDir: runBehavior?.persistDir ?? agentBehavior?.persistDir
|
|
2600
|
+
persistDir: runBehavior?.persistDir ?? agentBehavior?.persistDir,
|
|
2601
|
+
strictToolPairing: runBehavior?.strictToolPairing ?? agentBehavior?.strictToolPairing ?? false
|
|
2282
2602
|
};
|
|
2283
2603
|
}
|
|
2284
2604
|
/**
|
|
@@ -2366,7 +2686,7 @@ function buildSearchableCatalog(entries, options) {
|
|
|
2366
2686
|
}
|
|
2367
2687
|
const serverNames = [...byServer.keys()].sort();
|
|
2368
2688
|
const parts = [];
|
|
2369
|
-
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
|
|
2689
|
+
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.`, "");
|
|
2370
2690
|
parts.push("<searchable_tools>");
|
|
2371
2691
|
for (const server of serverNames) {
|
|
2372
2692
|
parts.push(` <server name="${escapeXml(server)}">`);
|
|
@@ -2494,9 +2814,14 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2494
2814
|
if (running) throw new Error("Agent is already running. Use steer() or followUp() to queue messages, or waitForIdle().");
|
|
2495
2815
|
const hasSessionTurns = session && session.turns.length > 0;
|
|
2496
2816
|
if (!options.prompt && !hasSessionTurns) throw new Error("prompt is required when no session with existing turns is provided");
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2817
|
+
let resumeFilteredTurns;
|
|
2818
|
+
if (hasSessionTurns) resumeFilteredTurns = filterUnresolvedToolUses(session.turns);
|
|
2819
|
+
if (!options.prompt && resumeFilteredTurns) {
|
|
2820
|
+
const lastTurn = resumeFilteredTurns.at(-1);
|
|
2821
|
+
if (lastTurn && lastTurn.role !== "user") {
|
|
2822
|
+
const detail = detectTurnInterruption(resumeFilteredTurns) === "completed" ? "last turn is a completed assistant message" : "last turn is mid-stream assistant content";
|
|
2823
|
+
throw new Error(`cannot resume without prompt: ${detail}. Pass a prompt to agent.run({ prompt: … }).`);
|
|
2824
|
+
}
|
|
2500
2825
|
}
|
|
2501
2826
|
let externalAbortListener;
|
|
2502
2827
|
const externalSignal = options.signal;
|
|
@@ -2561,7 +2886,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2561
2886
|
const thinking = options.thinking ?? "off";
|
|
2562
2887
|
const model = options.model ?? provider.meta.defaultModel;
|
|
2563
2888
|
const resolvedBehavior = resolveBehavior(agentBehavior, options.behavior);
|
|
2564
|
-
const { toolExecution, maxTurns, maxTokens, thinkingBudget, schema, cache, toolOutputBudget, compactStrategy, compactThreshold, compactKeepTurns, thinkingDecay, dedupTools, toolBudgets, elideStaleReads, toolDisclosure, toolSearch, persistThreshold, persistExcludeTools, persistDir } = resolvedBehavior;
|
|
2889
|
+
const { toolExecution, maxTurns, maxTokens, thinkingBudget, schema, cache, toolOutputBudget, compactStrategy, compactThreshold, compactKeepTurns, thinkingDecay, dedupTools, toolBudgets, elideStaleReads, toolDisclosure, toolSearch, persistThreshold, persistExcludeTools, persistDir, strictToolPairing } = resolvedBehavior;
|
|
2565
2890
|
let system = options.system || agentSystem || "You are a helpful assistant.";
|
|
2566
2891
|
if (skillsCatalog) system = `${system}\n\n${skillsCatalog}`;
|
|
2567
2892
|
const runBaseTools = options.tools !== void 0 ? options.tools : mcpConnection ? {
|
|
@@ -2626,7 +2951,8 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2626
2951
|
if (isResume) {
|
|
2627
2952
|
const childRunIds = new Set(session.runs.filter((r) => (r.depth ?? 0) > 0).map((r) => r.id));
|
|
2628
2953
|
const resumed = childRunIds.size === 0 ? session.turns : session.turns.filter((t) => !t.runId || !childRunIds.has(t.runId));
|
|
2629
|
-
turns
|
|
2954
|
+
const filteredForRuntime = resumeFilteredTurns && resumed === session.turns ? resumeFilteredTurns : filterUnresolvedToolUses(resumed);
|
|
2955
|
+
turns.push(...filteredForRuntime);
|
|
2630
2956
|
}
|
|
2631
2957
|
const runTurnStart = turns.length;
|
|
2632
2958
|
if (options.system) await hooks.callHook("system:before", { system: options.system });
|
|
@@ -2669,7 +2995,7 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2669
2995
|
const unregisterToolResultsSync = session ? hooks.hook("tool-results:after", persistPendingTurns) : void 0;
|
|
2670
2996
|
async function flushTurns(opts = {}) {
|
|
2671
2997
|
if (!session) return;
|
|
2672
|
-
if (opts.failureFallback) synthesizeMissingToolResults(turns, await session.generateTurnId?.() ?? crypto.randomUUID(), runId, provider);
|
|
2998
|
+
if (opts.failureFallback) await synthesizeMissingToolResults(turns, await session.generateTurnId?.() ?? crypto.randomUUID(), runId, provider, hooks);
|
|
2673
2999
|
const remaining = turns.slice(lastPersistedTurnCount);
|
|
2674
3000
|
if (remaining.length > 0) {
|
|
2675
3001
|
await session.appendTurns(remaining);
|
|
@@ -2748,6 +3074,8 @@ function createAgent({ provider, name: agentName, system: agentSystem, tools: ag
|
|
|
2748
3074
|
...persistThreshold !== void 0 ? { persistThreshold } : {},
|
|
2749
3075
|
...persistExcludeTools !== void 0 ? { persistExcludeTools } : {},
|
|
2750
3076
|
...persistDir !== void 0 ? { persistDir } : {},
|
|
3077
|
+
...strictToolPairing ? { strictToolPairing: true } : {},
|
|
3078
|
+
providerName: provider.name,
|
|
2751
3079
|
runStartMs,
|
|
2752
3080
|
runToolCounts: {}
|
|
2753
3081
|
});
|
|
@@ -4161,6 +4489,8 @@ const BUBBLED_EVENTS = [
|
|
|
4161
4489
|
"stream:text",
|
|
4162
4490
|
"stream:thinking",
|
|
4163
4491
|
"stream:end",
|
|
4492
|
+
"stream:error",
|
|
4493
|
+
"tool:dispatched",
|
|
4164
4494
|
"tool:before",
|
|
4165
4495
|
"tool:after",
|
|
4166
4496
|
"tool:error",
|
|
@@ -4175,6 +4505,8 @@ const CHILD_EVENT_NAME = {
|
|
|
4175
4505
|
"stream:text": "child:stream:text",
|
|
4176
4506
|
"stream:thinking": "child:stream:thinking",
|
|
4177
4507
|
"stream:end": "child:stream:end",
|
|
4508
|
+
"stream:error": "child:stream:error",
|
|
4509
|
+
"tool:dispatched": "child:tool:dispatched",
|
|
4178
4510
|
"tool:before": "child:tool:before",
|
|
4179
4511
|
"tool:after": "child:tool:after",
|
|
4180
4512
|
"tool:error": "child:tool:error",
|
|
@@ -4571,6 +4903,6 @@ const writeFile$1 = {
|
|
|
4571
4903
|
}
|
|
4572
4904
|
};
|
|
4573
4905
|
//#endregion
|
|
4574
|
-
export {
|
|
4906
|
+
export { PERSISTENCE_PREVIEW_BYTES as C, resolvePersistDir as D, maybePersistToolResult as E, getReadState as O, PERSISTED_STUB_PREFIX as S, cleanupPersistedSession as T, createSkillsReadTool as _, multiEdit as a, TOOL_USE_SKIPPED_MESSAGE as b, grep as c, resolveOldString as d, styleReplacementForVia as f, createSkillsRunScriptTool as g, createSkillsUseTool as h, readFile$1 as i, glob as l, createToolSearchTool as m, createSpawnTool as n, listFiles as o, createAgent as p, shell as r, createInteractionTool as s, writeFile$1 as t, edit as u, INTERRUPT_MESSAGE_FOR_TOOL_USE as v, buildPersistedStub as w, validateToolArgs as x, TOOL_USE_AFTER_ERROR_MESSAGE as y };
|
|
4575
4907
|
|
|
4576
|
-
//# sourceMappingURL=tools-
|
|
4908
|
+
//# sourceMappingURL=tools-CWEDS2ZT.js.map
|