@prestyj/agent 5.13.0 → 5.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +136 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +134 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -401,6 +401,20 @@ declare function isBillingError(err: unknown): boolean;
|
|
|
401
401
|
*/
|
|
402
402
|
declare function isUsageLimitError(err: unknown): boolean;
|
|
403
403
|
declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
|
|
404
|
+
/**
|
|
405
|
+
* A tool call that never reached its tool. Nothing ran, so nothing changed.
|
|
406
|
+
*/
|
|
407
|
+
declare function cancelledBeforeStartText(name: string): string;
|
|
408
|
+
/**
|
|
409
|
+
* A tool call that started running and was cut off before reporting back.
|
|
410
|
+
*
|
|
411
|
+
* The distinction from {@link cancelledBeforeStartText} is the whole point: a
|
|
412
|
+
* dispatched `git push`, deploy or MCP call may well have COMPLETED before the
|
|
413
|
+
* abort landed. Telling the model it was "interrupted" reads as "it did not
|
|
414
|
+
* happen", so the model repeats the side effect — or reports to the user that
|
|
415
|
+
* something never ran when it did.
|
|
416
|
+
*/
|
|
417
|
+
declare function indeterminateOutcomeText(name: string): string;
|
|
404
418
|
|
|
405
419
|
/**
|
|
406
420
|
* A local inference server (llama.cpp, vLLM, Ollama, LM Studio) can spend
|
|
@@ -411,4 +425,4 @@ declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGen
|
|
|
411
425
|
*/
|
|
412
426
|
declare function isLocalBackendUrl(baseUrl?: string): boolean;
|
|
413
427
|
|
|
414
|
-
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, isAbortError, isBillingError, isContextOverflow, isLocalBackendUrl, isUsageLimitError, setStreamDiagnostic };
|
|
428
|
+
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, cancelledBeforeStartText, indeterminateOutcomeText, isAbortError, isBillingError, isContextOverflow, isLocalBackendUrl, isUsageLimitError, setStreamDiagnostic };
|
package/dist/index.d.ts
CHANGED
|
@@ -401,6 +401,20 @@ declare function isBillingError(err: unknown): boolean;
|
|
|
401
401
|
*/
|
|
402
402
|
declare function isUsageLimitError(err: unknown): boolean;
|
|
403
403
|
declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGenerator<AgentEvent, AgentResult>;
|
|
404
|
+
/**
|
|
405
|
+
* A tool call that never reached its tool. Nothing ran, so nothing changed.
|
|
406
|
+
*/
|
|
407
|
+
declare function cancelledBeforeStartText(name: string): string;
|
|
408
|
+
/**
|
|
409
|
+
* A tool call that started running and was cut off before reporting back.
|
|
410
|
+
*
|
|
411
|
+
* The distinction from {@link cancelledBeforeStartText} is the whole point: a
|
|
412
|
+
* dispatched `git push`, deploy or MCP call may well have COMPLETED before the
|
|
413
|
+
* abort landed. Telling the model it was "interrupted" reads as "it did not
|
|
414
|
+
* happen", so the model repeats the side effect — or reports to the user that
|
|
415
|
+
* something never ran when it did.
|
|
416
|
+
*/
|
|
417
|
+
declare function indeterminateOutcomeText(name: string): string;
|
|
404
418
|
|
|
405
419
|
/**
|
|
406
420
|
* A local inference server (llama.cpp, vLLM, Ollama, LM Studio) can spend
|
|
@@ -411,4 +425,4 @@ declare function agentLoop(messages: Message[], options: AgentOptions): AsyncGen
|
|
|
411
425
|
*/
|
|
412
426
|
declare function isLocalBackendUrl(baseUrl?: string): boolean;
|
|
413
427
|
|
|
414
|
-
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, isAbortError, isBillingError, isContextOverflow, isLocalBackendUrl, isUsageLimitError, setStreamDiagnostic };
|
|
428
|
+
export { Agent, type AgentDoneEvent, type AgentErrorEvent, type AgentEvent, type AgentFollowUpMessageEvent, type AgentOptions, type AgentResult, type AgentRetryEvent, type AgentServerToolCallEvent, type AgentServerToolResultEvent, type AgentSteeringMessageEvent, AgentStream, type AgentTextDeltaEvent, type AgentThinkingDeltaEvent, type AgentTool, type AgentToolCallDeltaEvent, type AgentToolCallEndEvent, type AgentToolCallStartEvent, type AgentToolCallUpdateEvent, type AgentTurnEndEvent, type AgentTurnTiming, type StreamDiagnosticFn, type StructuredToolResult, type ToolContext, type ToolExecuteResult, type ToolExecutionMode, type TransformContextOptions, agentLoop, cancelledBeforeStartText, indeterminateOutcomeText, isAbortError, isBillingError, isContextOverflow, isLocalBackendUrl, isUsageLimitError, setStreamDiagnostic };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,60 @@ function isLocalBackendUrl(baseUrl) {
|
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// src/output-ceiling.ts
|
|
39
|
+
var TTL_MS = 24 * 60 * 60 * 1e3;
|
|
40
|
+
var MIN_PLAUSIBLE_CEILING = 256;
|
|
41
|
+
var MAX_PLAUSIBLE_CEILING = 1e7;
|
|
42
|
+
var ceilings = /* @__PURE__ */ new Map();
|
|
43
|
+
function outputRouteKey(route) {
|
|
44
|
+
return `${route.provider}\0${route.baseUrl ?? "default"}\0${route.model}`;
|
|
45
|
+
}
|
|
46
|
+
function parseOutputTokenCeiling(err) {
|
|
47
|
+
if (!(err instanceof Error)) return null;
|
|
48
|
+
const msg = err.message;
|
|
49
|
+
if (!/max_tokens|max output tokens|output tokens|completion tokens/i.test(msg)) return null;
|
|
50
|
+
if (err.statusCode === 402) return null;
|
|
51
|
+
if (/credit|billing|payment|insufficient|balance|quota/i.test(msg)) return null;
|
|
52
|
+
const patterns = [
|
|
53
|
+
// Anthropic: "max_tokens: 100000 > 64000, which is the maximum allowed…"
|
|
54
|
+
/max_tokens:\s*\d+\s*>\s*(\d+)/i,
|
|
55
|
+
// OpenAI: "…this model supports at most 16384 completion tokens"
|
|
56
|
+
/(?:at most|maximum of|limit of)\s+([\d,_]+)\s*(?:output|completion)?\s*tokens/i,
|
|
57
|
+
// Generic: "max output tokens is 8192" / "max_tokens must be <= 4096"
|
|
58
|
+
/(?:max_tokens|max output tokens)\b[^\d]{0,30}?([\d,_]+)/i
|
|
59
|
+
];
|
|
60
|
+
for (const pattern of patterns) {
|
|
61
|
+
const raw = msg.match(pattern)?.[1];
|
|
62
|
+
if (raw === void 0) continue;
|
|
63
|
+
const limit = Number(raw.replace(/[,_]/g, ""));
|
|
64
|
+
if (Number.isFinite(limit) && limit >= MIN_PLAUSIBLE_CEILING && limit <= MAX_PLAUSIBLE_CEILING) {
|
|
65
|
+
return limit;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function rememberOutputCeiling(key, limit) {
|
|
71
|
+
const known = outputTokenCeiling(key);
|
|
72
|
+
ceilings.set(key, {
|
|
73
|
+
limit: known === void 0 ? limit : Math.min(known, limit),
|
|
74
|
+
expiresAt: Date.now() + TTL_MS
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function outputTokenCeiling(key) {
|
|
78
|
+
const entry = ceilings.get(key);
|
|
79
|
+
if (!entry) return void 0;
|
|
80
|
+
if (entry.expiresAt <= Date.now()) {
|
|
81
|
+
ceilings.delete(key);
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
return entry.limit;
|
|
85
|
+
}
|
|
86
|
+
function clampOutputTokens(key, requested) {
|
|
87
|
+
const ceiling = outputTokenCeiling(key);
|
|
88
|
+
if (ceiling === void 0) return requested;
|
|
89
|
+
return requested === void 0 ? ceiling : Math.min(requested, ceiling);
|
|
90
|
+
}
|
|
91
|
+
|
|
38
92
|
// src/agent-loop.ts
|
|
39
93
|
var DEFAULT_MAX_TURNS = 300;
|
|
40
94
|
var DEFAULT_TOOL_TIMEOUT_MS = 3e5;
|
|
@@ -319,6 +373,16 @@ async function* agentLoop(messages, options) {
|
|
|
319
373
|
const MAX_OUTPUT_CONTINUATIONS = 2;
|
|
320
374
|
const MAX_TOKENS_CONTINUATION_PROMPT = "[Your previous response hit the output-token limit and was cut off. The text above is what was already delivered to the user. Continue exactly from where it stopped \u2014 do not repeat or restart it.]";
|
|
321
375
|
let maxTokensContinuations = 0;
|
|
376
|
+
let providerCalls = 0;
|
|
377
|
+
let nonStreamingCalls = 0;
|
|
378
|
+
let warnedNonStreaming = false;
|
|
379
|
+
const MAX_OUTPUT_CEILING_RETRIES = 1;
|
|
380
|
+
let outputCeilingRetries = 0;
|
|
381
|
+
const ceilingKey = outputRouteKey({
|
|
382
|
+
provider: options.provider,
|
|
383
|
+
model: options.model,
|
|
384
|
+
baseUrl: options.baseUrl
|
|
385
|
+
});
|
|
322
386
|
const OVERLOAD_BASE_DELAY_MS = 2e3;
|
|
323
387
|
const OVERLOAD_MAX_DELAY_MS = 3e4;
|
|
324
388
|
const STREAM_FIRST_EVENT_TIMEOUT_MS = 45e3;
|
|
@@ -448,6 +512,18 @@ async function* agentLoop(messages, options) {
|
|
|
448
512
|
let streamIterator = null;
|
|
449
513
|
try {
|
|
450
514
|
diag("stream_call", { nonStreaming: useNonStreamingFallback });
|
|
515
|
+
providerCalls++;
|
|
516
|
+
if (useNonStreamingFallback) nonStreamingCalls++;
|
|
517
|
+
if (!warnedNonStreaming && nonStreamingCalls >= 3) {
|
|
518
|
+
warnedNonStreaming = true;
|
|
519
|
+
diag("non_streaming_session", {
|
|
520
|
+
nonStreamingCalls,
|
|
521
|
+
providerCalls,
|
|
522
|
+
provider: options.provider,
|
|
523
|
+
model: options.model,
|
|
524
|
+
impact: "streaming is disabled for this session after repeated stalls: failed turns are re-billed in full instead of resuming from partial output, and replies appear only when complete"
|
|
525
|
+
});
|
|
526
|
+
}
|
|
451
527
|
streamCallStart = Date.now();
|
|
452
528
|
providerAttemptStartedAt = streamCallStart;
|
|
453
529
|
let liveApiKey = options.apiKey;
|
|
@@ -473,7 +549,9 @@ async function* agentLoop(messages, options) {
|
|
|
473
549
|
serverTools: options.serverTools,
|
|
474
550
|
toolChoice: options.toolChoice,
|
|
475
551
|
webSearch: options.webSearch,
|
|
476
|
-
|
|
552
|
+
// Clamped to whatever ceiling this route has already rejected us for
|
|
553
|
+
// (identity when nothing has been learned).
|
|
554
|
+
maxTokens: clampOutputTokens(ceilingKey, options.maxTokens),
|
|
477
555
|
temperature: options.temperature,
|
|
478
556
|
thinking: options.thinking,
|
|
479
557
|
apiKey: liveApiKey,
|
|
@@ -630,6 +708,29 @@ async function* agentLoop(messages, options) {
|
|
|
630
708
|
});
|
|
631
709
|
throw err;
|
|
632
710
|
}
|
|
711
|
+
const statedCeiling = parseOutputTokenCeiling(err);
|
|
712
|
+
if (statedCeiling !== null) {
|
|
713
|
+
rememberOutputCeiling(ceilingKey, statedCeiling);
|
|
714
|
+
diag("output_ceiling_learned", {
|
|
715
|
+
ceiling: statedCeiling,
|
|
716
|
+
requested: options.maxTokens,
|
|
717
|
+
provider: options.provider,
|
|
718
|
+
model: options.model
|
|
719
|
+
});
|
|
720
|
+
if (outputCeilingRetries < MAX_OUTPUT_CEILING_RETRIES) {
|
|
721
|
+
outputCeilingRetries++;
|
|
722
|
+
yield {
|
|
723
|
+
type: "retry",
|
|
724
|
+
reason: "provider_error",
|
|
725
|
+
attempt: outputCeilingRetries,
|
|
726
|
+
maxAttempts: MAX_OUTPUT_CEILING_RETRIES,
|
|
727
|
+
delayMs: 0,
|
|
728
|
+
silent: true
|
|
729
|
+
};
|
|
730
|
+
turn--;
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
633
734
|
if (isContextOverflow(err)) {
|
|
634
735
|
const overflowDetails = extractContextOverflowDetails(err);
|
|
635
736
|
diag("context_overflow_detected", {
|
|
@@ -1260,6 +1361,8 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
|
|
|
1260
1361
|
toolCall.name
|
|
1261
1362
|
);
|
|
1262
1363
|
}
|
|
1364
|
+
} else if (options.signal?.aborted && isAbortError(err)) {
|
|
1365
|
+
resultContent = indeterminateOutcomeText(toolCall.name);
|
|
1263
1366
|
} else {
|
|
1264
1367
|
resultContent = redactValue(err instanceof Error ? err.message : String(err));
|
|
1265
1368
|
}
|
|
@@ -1283,6 +1386,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1283
1386
|
const eventStream = new EventStream();
|
|
1284
1387
|
const state = { finalized: false };
|
|
1285
1388
|
const resultsById = /* @__PURE__ */ new Map();
|
|
1389
|
+
const dispatchedIds = /* @__PURE__ */ new Set();
|
|
1286
1390
|
const abortHandler = () => eventStream.abort(new Error("aborted"));
|
|
1287
1391
|
options.signal?.addEventListener("abort", abortHandler, { once: true });
|
|
1288
1392
|
const phases = [];
|
|
@@ -1307,6 +1411,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1307
1411
|
for (const phase of phases) {
|
|
1308
1412
|
if (options.signal?.aborted) break;
|
|
1309
1413
|
if (phase.sequential) {
|
|
1414
|
+
dispatchedIds.add(phase.sequential.id);
|
|
1310
1415
|
const record = await executeSingleToolCall(
|
|
1311
1416
|
phase.sequential,
|
|
1312
1417
|
options,
|
|
@@ -1314,6 +1419,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1314
1419
|
);
|
|
1315
1420
|
resultsById.set(record.toolCallId, record);
|
|
1316
1421
|
} else if (phase.parallel.length === 1) {
|
|
1422
|
+
dispatchedIds.add(phase.parallel[0].id);
|
|
1317
1423
|
const record = await executeSingleToolCall(
|
|
1318
1424
|
phase.parallel[0],
|
|
1319
1425
|
options,
|
|
@@ -1323,6 +1429,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1323
1429
|
} else {
|
|
1324
1430
|
await Promise.all(
|
|
1325
1431
|
phase.parallel.map(async (toolCall) => {
|
|
1432
|
+
dispatchedIds.add(toolCall.id);
|
|
1326
1433
|
const record = await executeSingleToolCall(
|
|
1327
1434
|
toolCall,
|
|
1328
1435
|
options,
|
|
@@ -1353,7 +1460,7 @@ async function* executeToolCallsMixed(toolCalls, initialToolResults, options) {
|
|
|
1353
1460
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
1354
1461
|
state.finalized = true;
|
|
1355
1462
|
}
|
|
1356
|
-
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById);
|
|
1463
|
+
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById, dispatchedIds);
|
|
1357
1464
|
capToolResults(toolResults, options.maxToolResultChars);
|
|
1358
1465
|
capTurnToolResults(toolResults, options.maxTurnToolResultChars);
|
|
1359
1466
|
return { toolResults, aborted };
|
|
@@ -1362,10 +1469,12 @@ async function* executeToolCallsParallel(toolCalls, initialToolResults, options)
|
|
|
1362
1469
|
const eventStream = new EventStream();
|
|
1363
1470
|
const state = { finalized: false };
|
|
1364
1471
|
const resultsById = /* @__PURE__ */ new Map();
|
|
1472
|
+
const dispatchedIds = /* @__PURE__ */ new Set();
|
|
1365
1473
|
const abortHandler = () => eventStream.abort(new Error("aborted"));
|
|
1366
1474
|
options.signal?.addEventListener("abort", abortHandler, { once: true });
|
|
1367
1475
|
Promise.all(
|
|
1368
1476
|
toolCalls.map(async (toolCall) => {
|
|
1477
|
+
dispatchedIds.add(toolCall.id);
|
|
1369
1478
|
const record = await executeSingleToolCall(
|
|
1370
1479
|
toolCall,
|
|
1371
1480
|
options,
|
|
@@ -1393,12 +1502,18 @@ async function* executeToolCallsParallel(toolCalls, initialToolResults, options)
|
|
|
1393
1502
|
options.signal?.removeEventListener("abort", abortHandler);
|
|
1394
1503
|
state.finalized = true;
|
|
1395
1504
|
}
|
|
1396
|
-
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById);
|
|
1505
|
+
const toolResults = buildToolResults(initialToolResults, toolCalls, resultsById, dispatchedIds);
|
|
1397
1506
|
capToolResults(toolResults, options.maxToolResultChars);
|
|
1398
1507
|
capTurnToolResults(toolResults, options.maxTurnToolResultChars);
|
|
1399
1508
|
return { toolResults, aborted };
|
|
1400
1509
|
}
|
|
1401
|
-
function
|
|
1510
|
+
function cancelledBeforeStartText(name) {
|
|
1511
|
+
return `\`${name}\` was cancelled before it started, so it had no effect. Safe to retry.`;
|
|
1512
|
+
}
|
|
1513
|
+
function indeterminateOutcomeText(name) {
|
|
1514
|
+
return `\`${name}\` started running and was cut off before it reported back, so its outcome is UNKNOWN \u2014 it may have completed. Check the real state (re-read the file, re-run a status command) before retrying it, and do not tell the user it did not happen.`;
|
|
1515
|
+
}
|
|
1516
|
+
function buildToolResults(initialToolResults, toolCalls, resultsById, dispatchedIds) {
|
|
1402
1517
|
const toolResults = [...initialToolResults];
|
|
1403
1518
|
for (const toolCall of toolCalls) {
|
|
1404
1519
|
const result = resultsById.get(toolCall.id);
|
|
@@ -1410,10 +1525,11 @@ function buildToolResults(initialToolResults, toolCalls, resultsById) {
|
|
|
1410
1525
|
isError: result.isError || void 0
|
|
1411
1526
|
});
|
|
1412
1527
|
} else {
|
|
1528
|
+
const dispatched = dispatchedIds?.has(toolCall.id) ?? true;
|
|
1413
1529
|
toolResults.push({
|
|
1414
1530
|
type: "tool_result",
|
|
1415
1531
|
toolCallId: toolCall.id,
|
|
1416
|
-
content:
|
|
1532
|
+
content: dispatched ? indeterminateOutcomeText(toolCall.name) : cancelledBeforeStartText(toolCall.name),
|
|
1417
1533
|
isError: true
|
|
1418
1534
|
});
|
|
1419
1535
|
}
|
|
@@ -1561,32 +1677,22 @@ function repairToolPairingAdjacent(messages) {
|
|
|
1561
1677
|
const msg = messages[i];
|
|
1562
1678
|
if (msg.role !== "assistant") continue;
|
|
1563
1679
|
if (typeof msg.content === "string" || !Array.isArray(msg.content)) continue;
|
|
1564
|
-
const
|
|
1565
|
-
if (
|
|
1680
|
+
const orphanCalls = msg.content.filter((p) => p.type === "tool_call").map((p) => p);
|
|
1681
|
+
if (orphanCalls.length === 0) continue;
|
|
1682
|
+
const repaired = (call) => ({
|
|
1683
|
+
type: "tool_result",
|
|
1684
|
+
toolCallId: call.id,
|
|
1685
|
+
content: indeterminateOutcomeText(call.name),
|
|
1686
|
+
isError: true
|
|
1687
|
+
});
|
|
1566
1688
|
const next = messages[i + 1];
|
|
1567
1689
|
if (next?.role === "tool" && Array.isArray(next.content)) {
|
|
1568
1690
|
const existingIds = new Set(next.content.map((r) => r.toolCallId));
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
for (const id of missing) {
|
|
1572
|
-
next.content.push({
|
|
1573
|
-
type: "tool_result",
|
|
1574
|
-
toolCallId: id,
|
|
1575
|
-
content: "Tool execution was interrupted.",
|
|
1576
|
-
isError: true
|
|
1577
|
-
});
|
|
1578
|
-
}
|
|
1691
|
+
for (const call of orphanCalls) {
|
|
1692
|
+
if (!existingIds.has(call.id)) next.content.push(repaired(call));
|
|
1579
1693
|
}
|
|
1580
1694
|
} else {
|
|
1581
|
-
messages.splice(i + 1, 0, {
|
|
1582
|
-
role: "tool",
|
|
1583
|
-
content: toolCallIds.map((id) => ({
|
|
1584
|
-
type: "tool_result",
|
|
1585
|
-
toolCallId: id,
|
|
1586
|
-
content: "Tool execution was interrupted.",
|
|
1587
|
-
isError: true
|
|
1588
|
-
}))
|
|
1589
|
-
});
|
|
1695
|
+
messages.splice(i + 1, 0, { role: "tool", content: orphanCalls.map(repaired) });
|
|
1590
1696
|
}
|
|
1591
1697
|
}
|
|
1592
1698
|
const toolCallIdSet = /* @__PURE__ */ new Set();
|
|
@@ -1745,6 +1851,8 @@ export {
|
|
|
1745
1851
|
Agent,
|
|
1746
1852
|
AgentStream,
|
|
1747
1853
|
agentLoop,
|
|
1854
|
+
cancelledBeforeStartText,
|
|
1855
|
+
indeterminateOutcomeText,
|
|
1748
1856
|
isAbortError,
|
|
1749
1857
|
isBillingError,
|
|
1750
1858
|
isContextOverflow,
|