@aexol/spectral 0.9.230 → 0.9.234
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/CHANGELOG.md +2 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +89 -14
- package/dist/backend/generated-images.d.ts +1 -1
- package/dist/backend/generated-images.d.ts.map +1 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +12 -1
- package/dist/designer/data/skills/blog-post.d.ts +3 -0
- package/dist/designer/data/skills/blog-post.d.ts.map +1 -0
- package/dist/designer/data/skills/blog-post.js +84 -0
- package/dist/designer/data/skills/blog-post.ts +87 -0
- package/dist/designer/data/skills/critique.d.ts +3 -0
- package/dist/designer/data/skills/critique.d.ts.map +1 -0
- package/dist/designer/data/skills/critique.js +109 -0
- package/dist/designer/data/skills/critique.ts +112 -0
- package/dist/designer/data/skills/dashboard.d.ts +3 -0
- package/dist/designer/data/skills/dashboard.d.ts.map +1 -0
- package/dist/designer/data/skills/dashboard.js +165 -0
- package/dist/designer/data/skills/dashboard.ts +168 -0
- package/dist/designer/data/skills/design-brief.d.ts +3 -0
- package/dist/designer/data/skills/design-brief.d.ts.map +1 -0
- package/dist/designer/data/skills/design-brief.js +141 -0
- package/dist/designer/data/skills/design-brief.ts +144 -0
- package/dist/designer/data/skills/design-skill.d.ts +10 -0
- package/dist/designer/data/skills/design-skill.d.ts.map +1 -0
- package/dist/designer/data/skills/design-skill.js +1 -0
- package/dist/designer/data/skills/design-skill.ts +9 -0
- package/dist/designer/data/skills/docs-page.d.ts +3 -0
- package/dist/designer/data/skills/docs-page.d.ts.map +1 -0
- package/dist/designer/data/skills/docs-page.js +68 -0
- package/dist/designer/data/skills/docs-page.ts +71 -0
- package/dist/designer/data/skills/index.d.ts +3 -0
- package/dist/designer/data/skills/index.d.ts.map +1 -0
- package/dist/designer/data/skills/index.js +28 -0
- package/dist/designer/data/skills/index.ts +30 -0
- package/dist/designer/data/skills/magazine-poster.d.ts +3 -0
- package/dist/designer/data/skills/magazine-poster.d.ts.map +1 -0
- package/dist/designer/data/skills/magazine-poster.js +70 -0
- package/dist/designer/data/skills/magazine-poster.ts +73 -0
- package/dist/designer/data/skills/mobile-app.d.ts +3 -0
- package/dist/designer/data/skills/mobile-app.d.ts.map +1 -0
- package/dist/designer/data/skills/mobile-app.js +229 -0
- package/dist/designer/data/skills/mobile-app.ts +232 -0
- package/dist/designer/data/skills/motion-frames.d.ts +3 -0
- package/dist/designer/data/skills/motion-frames.d.ts.map +1 -0
- package/dist/designer/data/skills/motion-frames.js +121 -0
- package/dist/designer/data/skills/motion-frames.ts +124 -0
- package/dist/designer/data/skills/pricing-page.d.ts +3 -0
- package/dist/designer/data/skills/pricing-page.d.ts.map +1 -0
- package/dist/designer/data/skills/pricing-page.js +76 -0
- package/dist/designer/data/skills/pricing-page.ts +79 -0
- package/dist/designer/data/skills/saas-landing.d.ts +3 -0
- package/dist/designer/data/skills/saas-landing.d.ts.map +1 -0
- package/dist/designer/data/skills/saas-landing.js +71 -0
- package/dist/designer/data/skills/saas-landing.ts +74 -0
- package/dist/designer/data/skills/slide-deck.d.ts +3 -0
- package/dist/designer/data/skills/slide-deck.d.ts.map +1 -0
- package/dist/designer/data/skills/slide-deck.js +213 -0
- package/dist/designer/data/skills/slide-deck.ts +216 -0
- package/dist/designer/data/skills/social-carousel.d.ts +3 -0
- package/dist/designer/data/skills/social-carousel.d.ts.map +1 -0
- package/dist/designer/data/skills/social-carousel.js +135 -0
- package/dist/designer/data/skills/social-carousel.ts +138 -0
- package/dist/designer/data/skills/web-prototype.d.ts +3 -0
- package/dist/designer/data/skills/web-prototype.d.ts.map +1 -0
- package/dist/designer/data/skills/web-prototype.js +159 -0
- package/dist/designer/data/skills/web-prototype.ts +162 -0
- package/dist/designer/skills.d.ts +4 -10
- package/dist/designer/skills.d.ts.map +1 -1
- package/dist/designer/skills.js +2 -1643
- package/dist/extensions/logic-trace.d.ts +1 -1
- package/dist/extensions/logic-trace.d.ts.map +1 -1
- package/dist/extensions/logic-trace.js +199 -70
- package/dist/extensions/video-generation/index.d.ts +3 -0
- package/dist/extensions/video-generation/index.d.ts.map +1 -0
- package/dist/extensions/video-generation/index.js +299 -0
- package/dist/extensions/wizard/index.js +9 -1
- package/dist/generated/parser/ast/nodes.d.ts +115 -0
- package/dist/generated/parser/ast/nodes.d.ts.map +1 -0
- package/dist/generated/parser/ast/nodes.js +8 -0
- package/dist/generated/parser/lexer/lexer.d.ts +28 -0
- package/dist/generated/parser/lexer/lexer.d.ts.map +1 -0
- package/dist/generated/parser/{lexer.js → lexer/lexer.js} +1 -180
- package/dist/generated/parser/{lexer.d.ts → lexer/tokens.d.ts} +5 -24
- package/dist/generated/parser/lexer/tokens.d.ts.map +1 -0
- package/dist/generated/parser/lexer/tokens.js +187 -0
- package/dist/generated/parser/mod.d.ts +5 -7
- package/dist/generated/parser/mod.d.ts.map +1 -1
- package/dist/generated/parser/mod.js +2 -1
- package/dist/generated/parser/parser/cursor.d.ts +47 -0
- package/dist/generated/parser/parser/cursor.d.ts.map +1 -0
- package/dist/generated/parser/parser/cursor.js +12 -0
- package/dist/generated/parser/parser/definitions.d.ts +16 -0
- package/dist/generated/parser/parser/definitions.d.ts.map +1 -0
- package/dist/generated/parser/parser/definitions.js +353 -0
- package/dist/generated/parser/parser/expressions.d.ts +17 -0
- package/dist/generated/parser/parser/expressions.d.ts.map +1 -0
- package/dist/generated/parser/parser/expressions.js +165 -0
- package/dist/generated/parser/parser.d.ts +18 -133
- package/dist/generated/parser/parser.d.ts.map +1 -1
- package/dist/generated/parser/parser.js +9 -505
- package/dist/generated/parser/tokenizer.d.ts +1 -2
- package/dist/generated/parser/tokenizer.d.ts.map +1 -1
- package/dist/generated/parser/tokenizer.js +2 -1
- package/dist/generated/parser/validator.d.ts +1 -1
- package/dist/generated/parser/validator.d.ts.map +1 -1
- package/dist/generated/zeus/const.d.ts.map +1 -1
- package/dist/generated/zeus/const.js +30 -0
- package/dist/generated/zeus/index.d.ts +140 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/generated/zeus/index.js +5 -0
- package/dist/mcp/glimpse-ui.js +9 -1
- package/dist/relay/dispatcher.d.ts +23 -104
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +21 -1130
- package/dist/relay/rest.d.ts +31 -0
- package/dist/relay/rest.d.ts.map +1 -0
- package/dist/relay/rest.js +85 -0
- package/dist/relay/routing.d.ts +109 -0
- package/dist/relay/routing.d.ts.map +1 -0
- package/dist/relay/routing.js +669 -0
- package/dist/relay/wizard-login.d.ts +17 -0
- package/dist/relay/wizard-login.d.ts.map +1 -0
- package/dist/relay/wizard-login.js +419 -0
- package/dist/sdk/agent-core/agent-loop.d.ts +2 -9
- package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +17 -291
- package/dist/sdk/agent-core/agent.d.ts +11 -4
- package/dist/sdk/agent-core/agent.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent.js +16 -4
- package/dist/sdk/agent-core/tool-call-registry.d.ts +75 -0
- package/dist/sdk/agent-core/tool-call-registry.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-call-registry.js +131 -0
- package/dist/sdk/agent-core/tool-execution.d.ts +33 -0
- package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-execution.js +399 -0
- package/dist/sdk/agent-core/types.d.ts +15 -4
- package/dist/sdk/agent-core/types.d.ts.map +1 -1
- package/dist/sdk/ai/env-api-keys.js +9 -1
- package/dist/sdk/ai/index.d.ts +3 -0
- package/dist/sdk/ai/index.d.ts.map +1 -1
- package/dist/sdk/ai/index.js +3 -0
- package/dist/sdk/ai/providers/faux.d.ts.map +1 -1
- package/dist/sdk/ai/providers/faux.js +3 -0
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts +39 -6
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts.map +1 -1
- package/dist/sdk/ai/providers/leaked-tool-call-parser.js +159 -18
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts +48 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openai/reasoning-replay.js +209 -0
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +23 -211
- package/dist/sdk/ai/providers/openrouter-videos.d.ts +3 -0
- package/dist/sdk/ai/providers/openrouter-videos.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openrouter-videos.js +412 -0
- package/dist/sdk/ai/providers/register-builtins.d.ts.map +1 -1
- package/dist/sdk/ai/providers/register-builtins.js +6 -0
- package/dist/sdk/ai/providers/simple-options.d.ts +1 -6
- package/dist/sdk/ai/providers/simple-options.d.ts.map +1 -1
- package/dist/sdk/ai/providers/simple-options.js +0 -22
- package/dist/sdk/ai/providers/transform-messages.d.ts.map +1 -1
- package/dist/sdk/ai/providers/transform-messages.js +52 -1
- package/dist/sdk/ai/types.d.ts +91 -10
- package/dist/sdk/ai/types.d.ts.map +1 -1
- package/dist/sdk/ai/video-models.d.ts +10 -0
- package/dist/sdk/ai/video-models.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.d.ts +440 -0
- package/dist/sdk/ai/video-models.generated.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.js +441 -0
- package/dist/sdk/ai/video-models.js +22 -0
- package/dist/sdk/ai/videos-api-registry.d.ts +14 -0
- package/dist/sdk/ai/videos-api-registry.d.ts.map +1 -0
- package/dist/sdk/ai/videos-api-registry.js +21 -0
- package/dist/sdk/ai/videos.d.ts +4 -0
- package/dist/sdk/ai/videos.d.ts.map +1 -0
- package/dist/sdk/ai/videos.js +13 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts +8 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/agent-session.js +11 -0
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +6 -118
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/compaction/compaction.js +11 -733
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts +58 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/cut-points.js +191 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts +28 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/dedupe.js +156 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts +21 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/summarize.js +181 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts +47 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/compaction/tokens.js +224 -0
- package/dist/sdk/coding-agent/core/extensions/loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/loader.js +14 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts +26 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/native-extensions.js +23 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +157 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.js +13 -0
- package/dist/sdk/coding-agent/core/extensions/types.d.ts +10 -367
- package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/types.js +2 -10
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts +219 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/extensions/ui-types.js +4 -0
- package/dist/sdk/coding-agent/core/messages.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/messages.js +42 -2
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts +115 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/default-package-manager.js +1184 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts +20 -0
- package/dist/sdk/coding-agent/core/package/discovery.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/discovery.js +283 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts +29 -0
- package/dist/sdk/coding-agent/core/package/ignore.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/ignore.js +235 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts +128 -0
- package/dist/sdk/coding-agent/core/package/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/types.js +18 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts +43 -0
- package/dist/sdk/coding-agent/core/package/update-check.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/package/update-check.js +253 -0
- package/dist/sdk/coding-agent/core/package-manager.d.ts +2 -188
- package/dist/sdk/coding-agent/core/package-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/package-manager.js +1 -1940
- package/dist/sdk/coding-agent/core/resource-loader.d.ts +11 -0
- package/dist/sdk/coding-agent/core/resource-loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/resource-loader.js +23 -6
- package/dist/sdk/coding-agent/core/sdk.d.ts +24 -2
- package/dist/sdk/coding-agent/core/sdk.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/sdk.js +15 -3
- package/dist/sdk/coding-agent/core/session/migrate.d.ts +18 -0
- package/dist/sdk/coding-agent/core/session/migrate.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/migrate.js +78 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts +165 -0
- package/dist/sdk/coding-agent/core/session/types.d.ts.map +1 -0
- package/dist/sdk/coding-agent/core/session/types.js +4 -0
- package/dist/sdk/coding-agent/core/session-manager.d.ts +3 -161
- package/dist/sdk/coding-agent/core/session-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/session-manager.js +4 -72
- package/dist/sdk/coding-agent/core/settings-manager.d.ts +0 -8
- package/dist/sdk/coding-agent/core/settings-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/settings-manager.js +3 -3
- package/dist/sdk/coding-agent/index.d.ts +2 -2
- package/dist/sdk/coding-agent/index.d.ts.map +1 -1
- package/dist/sdk/coding-agent/index.js +1 -1
- package/dist/sdk-public.d.ts +96 -0
- package/dist/sdk-public.d.ts.map +1 -0
- package/dist/sdk-public.js +109 -0
- package/dist/server/agent-bridge/rehydrate.d.ts +2 -2
- package/dist/server/agent-bridge/rehydrate.d.ts.map +1 -1
- package/dist/server/agent-bridge/rehydrate.js +14 -0
- package/dist/server/agent-bridge.d.ts +8 -2
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +25 -2
- package/dist/server/session-stream.d.ts +19 -0
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +35 -0
- package/dist/server/wire.d.ts +13 -0
- package/dist/server/wire.d.ts.map +1 -1
- package/package.json +8 -2
- package/dist/generated/parser/lexer.d.ts.map +0 -1
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
* Agent loop that works with AgentMessage throughout.
|
|
3
3
|
* Transforms to Message[] only at the LLM call boundary.
|
|
4
4
|
*/
|
|
5
|
-
import { EventStream, formatPaymentRequiredMessage, formatRateLimitRetryMessage, getRateLimitRetryDelayMs, isPaymentRequiredError, MAX_RATE_LIMIT_RETRIES, streamSimple, isRateLimitError, isTransientApiError,
|
|
5
|
+
import { EventStream, formatPaymentRequiredMessage, formatRateLimitRetryMessage, getRateLimitRetryDelayMs, isPaymentRequiredError, MAX_RATE_LIMIT_RETRIES, streamSimple, isRateLimitError, isTransientApiError, } from "../ai/index.js";
|
|
6
|
+
import { executeToolCalls } from "./tool-execution.js";
|
|
7
|
+
// Re-exported for backwards compatibility (moved to tool-execution.ts).
|
|
8
|
+
export { hasMissingRequiredArguments } from "./tool-execution.js";
|
|
6
9
|
/** Maximum consecutive tool call errors before terminating the loop. */
|
|
7
10
|
const MAX_CONSECUTIVE_TOOL_ERRORS = 10;
|
|
8
11
|
/** Maximum retries for transient provider API errors. */
|
|
@@ -264,13 +267,21 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
264
267
|
newMessages.push(result);
|
|
265
268
|
}
|
|
266
269
|
// Fix 1: Track consecutive tool call errors; terminate after threshold.
|
|
267
|
-
|
|
270
|
+
// User-stopped results (`stoppedByUser`) are deliberate user actions,
|
|
271
|
+
// not tool failures — they must not count toward the threshold, or a
|
|
272
|
+
// run where the user stops every tool call dies as "10 consecutive
|
|
273
|
+
// tool call errors" (defeating the per-call stop feature). A batch of
|
|
274
|
+
// only user-stopped results leaves the counter unchanged; normal
|
|
275
|
+
// results still reset it.
|
|
276
|
+
const turnHasError = toolResults.some((r) => r.isError && !r.stoppedByUser);
|
|
277
|
+
const batchAllUserStopped = toolResults.length > 0 &&
|
|
278
|
+
toolResults.every((r) => r.isError && r.stoppedByUser === true);
|
|
268
279
|
if (turnHasError) {
|
|
269
280
|
consecutiveToolErrors++;
|
|
270
281
|
if (consecutiveToolErrors >= MAX_CONSECUTIVE_TOOL_ERRORS) {
|
|
271
282
|
const lastErrorResult = [...toolResults]
|
|
272
283
|
.reverse()
|
|
273
|
-
.find((r) => r.isError);
|
|
284
|
+
.find((r) => r.isError && !r.stoppedByUser);
|
|
274
285
|
const lastErrorMsg = lastErrorResult?.content.find((c) => c.type === "text")?.text ||
|
|
275
286
|
"Unknown tool error";
|
|
276
287
|
const finalMessage = {
|
|
@@ -300,7 +311,9 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
300
311
|
return;
|
|
301
312
|
}
|
|
302
313
|
}
|
|
303
|
-
else {
|
|
314
|
+
else if (!batchAllUserStopped) {
|
|
315
|
+
// Pure success/normal batch: reset as today. An all-user-stopped
|
|
316
|
+
// batch is neither a real error nor a success — counter unchanged.
|
|
304
317
|
consecutiveToolErrors = 0;
|
|
305
318
|
}
|
|
306
319
|
}
|
|
@@ -432,290 +445,3 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
|
|
|
432
445
|
await emit({ type: "message_end", message: finalMessage });
|
|
433
446
|
return finalMessage;
|
|
434
447
|
}
|
|
435
|
-
/**
|
|
436
|
-
* Execute tool calls from an assistant message.
|
|
437
|
-
*/
|
|
438
|
-
async function executeToolCalls(currentContext, assistantMessage, config, signal, emit) {
|
|
439
|
-
const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
|
|
440
|
-
const hasSequentialToolCall = toolCalls.some((tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode ===
|
|
441
|
-
"sequential");
|
|
442
|
-
if (config.toolExecution === "sequential" || hasSequentialToolCall) {
|
|
443
|
-
return executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);
|
|
444
|
-
}
|
|
445
|
-
return executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);
|
|
446
|
-
}
|
|
447
|
-
async function executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit) {
|
|
448
|
-
const finalizedCalls = [];
|
|
449
|
-
const messages = [];
|
|
450
|
-
for (const toolCall of toolCalls) {
|
|
451
|
-
await emit({
|
|
452
|
-
type: "tool_execution_start",
|
|
453
|
-
toolCallId: toolCall.id,
|
|
454
|
-
toolName: toolCall.name,
|
|
455
|
-
args: toolCall.arguments,
|
|
456
|
-
});
|
|
457
|
-
const preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);
|
|
458
|
-
let finalized;
|
|
459
|
-
if (preparation.kind === "immediate") {
|
|
460
|
-
finalized = {
|
|
461
|
-
toolCall,
|
|
462
|
-
result: preparation.result,
|
|
463
|
-
isError: preparation.isError,
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
else {
|
|
467
|
-
const executed = await executePreparedToolCall(preparation, signal, emit);
|
|
468
|
-
finalized = await finalizeExecutedToolCall(currentContext, assistantMessage, preparation, executed, config, signal);
|
|
469
|
-
}
|
|
470
|
-
await emitToolExecutionEnd(finalized, emit);
|
|
471
|
-
const toolResultMessage = createToolResultMessage(finalized);
|
|
472
|
-
await emitToolResultMessage(toolResultMessage, emit);
|
|
473
|
-
finalizedCalls.push(finalized);
|
|
474
|
-
messages.push(toolResultMessage);
|
|
475
|
-
if (signal?.aborted) {
|
|
476
|
-
break;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
return {
|
|
480
|
-
messages,
|
|
481
|
-
terminate: shouldTerminateToolBatch(finalizedCalls),
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
async function executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit) {
|
|
485
|
-
const finalizedCalls = [];
|
|
486
|
-
for (const toolCall of toolCalls) {
|
|
487
|
-
await emit({
|
|
488
|
-
type: "tool_execution_start",
|
|
489
|
-
toolCallId: toolCall.id,
|
|
490
|
-
toolName: toolCall.name,
|
|
491
|
-
args: toolCall.arguments,
|
|
492
|
-
});
|
|
493
|
-
const preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);
|
|
494
|
-
if (preparation.kind === "immediate") {
|
|
495
|
-
const finalized = {
|
|
496
|
-
toolCall,
|
|
497
|
-
result: preparation.result,
|
|
498
|
-
isError: preparation.isError,
|
|
499
|
-
};
|
|
500
|
-
await emitToolExecutionEnd(finalized, emit);
|
|
501
|
-
finalizedCalls.push(finalized);
|
|
502
|
-
if (signal?.aborted) {
|
|
503
|
-
break;
|
|
504
|
-
}
|
|
505
|
-
continue;
|
|
506
|
-
}
|
|
507
|
-
finalizedCalls.push(async () => {
|
|
508
|
-
const executed = await executePreparedToolCall(preparation, signal, emit);
|
|
509
|
-
const finalized = await finalizeExecutedToolCall(currentContext, assistantMessage, preparation, executed, config, signal);
|
|
510
|
-
await emitToolExecutionEnd(finalized, emit);
|
|
511
|
-
return finalized;
|
|
512
|
-
});
|
|
513
|
-
if (signal?.aborted) {
|
|
514
|
-
break;
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
const orderedFinalizedCalls = await Promise.all(finalizedCalls.map((entry) => typeof entry === "function" ? entry() : Promise.resolve(entry)));
|
|
518
|
-
const messages = [];
|
|
519
|
-
for (const finalized of orderedFinalizedCalls) {
|
|
520
|
-
const toolResultMessage = createToolResultMessage(finalized);
|
|
521
|
-
await emitToolResultMessage(toolResultMessage, emit);
|
|
522
|
-
messages.push(toolResultMessage);
|
|
523
|
-
}
|
|
524
|
-
return {
|
|
525
|
-
messages,
|
|
526
|
-
terminate: shouldTerminateToolBatch(orderedFinalizedCalls),
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
function shouldTerminateToolBatch(finalizedCalls) {
|
|
530
|
-
return (finalizedCalls.length > 0 &&
|
|
531
|
-
finalizedCalls.every((finalized) => finalized.result.terminate === true));
|
|
532
|
-
}
|
|
533
|
-
function prepareToolCallArguments(tool, toolCall) {
|
|
534
|
-
if (!tool.prepareArguments) {
|
|
535
|
-
return toolCall;
|
|
536
|
-
}
|
|
537
|
-
const preparedArguments = tool.prepareArguments(toolCall.arguments);
|
|
538
|
-
if (preparedArguments === toolCall.arguments) {
|
|
539
|
-
return toolCall;
|
|
540
|
-
}
|
|
541
|
-
return {
|
|
542
|
-
...toolCall,
|
|
543
|
-
arguments: preparedArguments,
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
async function prepareToolCall(currentContext, assistantMessage, toolCall, config, signal) {
|
|
547
|
-
const tool = currentContext.tools?.find((t) => t.name === toolCall.name);
|
|
548
|
-
if (!tool) {
|
|
549
|
-
return {
|
|
550
|
-
kind: "immediate",
|
|
551
|
-
result: createErrorToolResult(`Tool ${toolCall.name} not found`),
|
|
552
|
-
isError: true,
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
// If the provider truncated the response mid tool-call (stopReason "length"),
|
|
556
|
-
// the streaming JSON parser may have produced an empty or incomplete arguments
|
|
557
|
-
// object. Validating it would surface a raw `Validation failed ... You provided:
|
|
558
|
-
// {}` error to the model. Instead, return a soft error so the agent-session
|
|
559
|
-
// length-continuation path (which treats truncated tool calls as visible output)
|
|
560
|
-
// can resubmit and let the model re-emit the full tool call.
|
|
561
|
-
if (assistantMessage.stopReason === "length" && hasMissingRequiredArguments(tool, toolCall)) {
|
|
562
|
-
return {
|
|
563
|
-
kind: "immediate",
|
|
564
|
-
result: createErrorToolResult(`Tool "${toolCall.name}" was truncated before its arguments were fully emitted. ` +
|
|
565
|
-
`Retrying: please re-emit the complete tool call with all required parameters.`),
|
|
566
|
-
isError: true,
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
try {
|
|
570
|
-
const preparedToolCall = prepareToolCallArguments(tool, toolCall);
|
|
571
|
-
const validatedArgs = validateToolArguments(tool, preparedToolCall);
|
|
572
|
-
if (config.beforeToolCall) {
|
|
573
|
-
const beforeResult = await config.beforeToolCall({
|
|
574
|
-
assistantMessage,
|
|
575
|
-
toolCall,
|
|
576
|
-
args: validatedArgs,
|
|
577
|
-
context: currentContext,
|
|
578
|
-
}, signal);
|
|
579
|
-
if (signal?.aborted) {
|
|
580
|
-
return {
|
|
581
|
-
kind: "immediate",
|
|
582
|
-
result: createErrorToolResult("Operation aborted"),
|
|
583
|
-
isError: true,
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
if (beforeResult?.block) {
|
|
587
|
-
return {
|
|
588
|
-
kind: "immediate",
|
|
589
|
-
result: createErrorToolResult(beforeResult.reason || "Tool execution was blocked"),
|
|
590
|
-
isError: true,
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
if (signal?.aborted) {
|
|
595
|
-
return {
|
|
596
|
-
kind: "immediate",
|
|
597
|
-
result: createErrorToolResult("Operation aborted"),
|
|
598
|
-
isError: true,
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
return {
|
|
602
|
-
kind: "prepared",
|
|
603
|
-
toolCall,
|
|
604
|
-
tool,
|
|
605
|
-
args: validatedArgs,
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
catch (error) {
|
|
609
|
-
return {
|
|
610
|
-
kind: "immediate",
|
|
611
|
-
result: createErrorToolResult(error instanceof Error ? error.message : String(error)),
|
|
612
|
-
isError: true,
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
async function executePreparedToolCall(prepared, signal, emit) {
|
|
617
|
-
const updateEvents = [];
|
|
618
|
-
try {
|
|
619
|
-
const result = await prepared.tool.execute(prepared.toolCall.id, prepared.args, signal, (partialResult) => {
|
|
620
|
-
updateEvents.push(Promise.resolve(emit({
|
|
621
|
-
type: "tool_execution_update",
|
|
622
|
-
toolCallId: prepared.toolCall.id,
|
|
623
|
-
toolName: prepared.toolCall.name,
|
|
624
|
-
args: prepared.toolCall.arguments,
|
|
625
|
-
partialResult,
|
|
626
|
-
})));
|
|
627
|
-
});
|
|
628
|
-
await Promise.all(updateEvents);
|
|
629
|
-
return { result, isError: false };
|
|
630
|
-
}
|
|
631
|
-
catch (error) {
|
|
632
|
-
await Promise.all(updateEvents);
|
|
633
|
-
return {
|
|
634
|
-
result: createErrorToolResult(error instanceof Error ? error.message : String(error)),
|
|
635
|
-
isError: true,
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
async function finalizeExecutedToolCall(currentContext, assistantMessage, prepared, executed, config, signal) {
|
|
640
|
-
let result = executed.result;
|
|
641
|
-
let isError = executed.isError;
|
|
642
|
-
if (config.afterToolCall) {
|
|
643
|
-
try {
|
|
644
|
-
const afterResult = await config.afterToolCall({
|
|
645
|
-
assistantMessage,
|
|
646
|
-
toolCall: prepared.toolCall,
|
|
647
|
-
args: prepared.args,
|
|
648
|
-
result,
|
|
649
|
-
isError,
|
|
650
|
-
context: currentContext,
|
|
651
|
-
}, signal);
|
|
652
|
-
if (afterResult) {
|
|
653
|
-
result = {
|
|
654
|
-
content: afterResult.content ?? result.content,
|
|
655
|
-
details: afterResult.details ?? result.details,
|
|
656
|
-
terminate: afterResult.terminate ?? result.terminate,
|
|
657
|
-
};
|
|
658
|
-
isError = afterResult.isError ?? isError;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
catch (error) {
|
|
662
|
-
result = createErrorToolResult(error instanceof Error ? error.message : String(error));
|
|
663
|
-
isError = true;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
return {
|
|
667
|
-
toolCall: prepared.toolCall,
|
|
668
|
-
result,
|
|
669
|
-
isError,
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
|
-
function createErrorToolResult(message) {
|
|
673
|
-
return {
|
|
674
|
-
content: [{ type: "text", text: message }],
|
|
675
|
-
details: {},
|
|
676
|
-
};
|
|
677
|
-
}
|
|
678
|
-
/**
|
|
679
|
-
* Detects whether a tool call is missing any required parameter, indicating the
|
|
680
|
-
* provider truncated the response before the tool arguments were fully emitted.
|
|
681
|
-
* Used together with `stopReason === "length"` to short-circuit tool validation
|
|
682
|
-
* when a streamed tool call is incomplete (which would otherwise throw
|
|
683
|
-
* `Validation failed ... You provided: {}`).
|
|
684
|
-
*/
|
|
685
|
-
export function hasMissingRequiredArguments(tool, toolCall) {
|
|
686
|
-
const schema = tool.parameters;
|
|
687
|
-
const required = schema.required;
|
|
688
|
-
if (!Array.isArray(required) || required.length === 0)
|
|
689
|
-
return false;
|
|
690
|
-
const args = toolCall.arguments;
|
|
691
|
-
if (!args || typeof args !== "object")
|
|
692
|
-
return true;
|
|
693
|
-
return required.some((key) => !(key in args) ||
|
|
694
|
-
args[key] === undefined ||
|
|
695
|
-
args[key] === null ||
|
|
696
|
-
(typeof args[key] === "string" && args[key].trim() === ""));
|
|
697
|
-
}
|
|
698
|
-
async function emitToolExecutionEnd(finalized, emit) {
|
|
699
|
-
await emit({
|
|
700
|
-
type: "tool_execution_end",
|
|
701
|
-
toolCallId: finalized.toolCall.id,
|
|
702
|
-
toolName: finalized.toolCall.name,
|
|
703
|
-
result: finalized.result,
|
|
704
|
-
isError: finalized.isError,
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
function createToolResultMessage(finalized) {
|
|
708
|
-
return {
|
|
709
|
-
role: "toolResult",
|
|
710
|
-
toolCallId: finalized.toolCall.id,
|
|
711
|
-
toolName: finalized.toolCall.name,
|
|
712
|
-
content: finalized.result.content,
|
|
713
|
-
details: finalized.result.details,
|
|
714
|
-
isError: finalized.isError,
|
|
715
|
-
timestamp: Date.now(),
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
async function emitToolResultMessage(toolResultMessage, emit) {
|
|
719
|
-
await emit({ type: "message_start", message: toolResultMessage });
|
|
720
|
-
await emit({ type: "message_end", message: toolResultMessage });
|
|
721
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ImageContent, type Message, type SimpleStreamOptions, type
|
|
1
|
+
import { type ImageContent, type Message, type SimpleStreamOptions, type Transport } from "../ai/index.js";
|
|
2
2
|
import type { AfterToolCallContext, AfterToolCallResult, AgentEvent, AgentLoopTurnUpdate, AgentMessage, AgentState, BeforeToolCallContext, BeforeToolCallResult, QueueMode, StreamFn, ToolExecutionMode } from "./types.js";
|
|
3
3
|
export type { QueueMode } from "./types.js";
|
|
4
4
|
/** Options for constructing an {@link Agent}. */
|
|
@@ -16,7 +16,6 @@ export interface AgentOptions {
|
|
|
16
16
|
steeringMode?: QueueMode;
|
|
17
17
|
followUpMode?: QueueMode;
|
|
18
18
|
sessionId?: string;
|
|
19
|
-
thinkingBudgets?: ThinkingBudgets;
|
|
20
19
|
transport?: Transport;
|
|
21
20
|
maxRetryDelayMs?: number;
|
|
22
21
|
toolExecution?: ToolExecutionMode;
|
|
@@ -32,6 +31,7 @@ export declare class Agent {
|
|
|
32
31
|
private readonly listeners;
|
|
33
32
|
private readonly steeringQueue;
|
|
34
33
|
private readonly followUpQueue;
|
|
34
|
+
private readonly toolCallRegistry;
|
|
35
35
|
convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;
|
|
36
36
|
transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
|
|
37
37
|
streamFn: StreamFn;
|
|
@@ -44,8 +44,6 @@ export declare class Agent {
|
|
|
44
44
|
private activeRun?;
|
|
45
45
|
/** Session identifier forwarded to providers for cache-aware backends. */
|
|
46
46
|
sessionId?: string;
|
|
47
|
-
/** Optional per-level thinking token budgets forwarded to the stream function. */
|
|
48
|
-
thinkingBudgets?: ThinkingBudgets;
|
|
49
47
|
/** Preferred transport forwarded to the stream function. */
|
|
50
48
|
transport: Transport;
|
|
51
49
|
/** Optional cap for provider-requested retry delays. */
|
|
@@ -92,6 +90,15 @@ export declare class Agent {
|
|
|
92
90
|
get signal(): AbortSignal | undefined;
|
|
93
91
|
/** Abort the current run, if one is active. */
|
|
94
92
|
abort(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Stop a single in-flight tool call (user-initiated per-call stop).
|
|
95
|
+
*
|
|
96
|
+
* Aborts only the targeted call's execution — siblings keep running and the
|
|
97
|
+
* agent loop CONTINUES the turn with a synthesized user-stop tool result
|
|
98
|
+
* ("Tool call stopped by user (was running too long)"). Returns false for
|
|
99
|
+
* unknown/finished toolCallIds (no-op).
|
|
100
|
+
*/
|
|
101
|
+
stopToolCall(toolCallId: string, reason?: string): Promise<boolean>;
|
|
95
102
|
/**
|
|
96
103
|
* Resolve when the current run and all awaited event listeners have finished.
|
|
97
104
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,OAAO,EAEZ,KAAK,mBAAmB,EAGxB,KAAK,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { streamSimple, } from "../ai/index.js";
|
|
2
2
|
import { runAgentLoop, runAgentLoopContinue } from "./agent-loop.js";
|
|
3
|
+
import { ToolCallRegistry } from "./tool-call-registry.js";
|
|
3
4
|
function defaultConvertToLlm(messages) {
|
|
4
5
|
return messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
|
|
5
6
|
}
|
|
@@ -88,6 +89,7 @@ export class Agent {
|
|
|
88
89
|
listeners = new Set();
|
|
89
90
|
steeringQueue;
|
|
90
91
|
followUpQueue;
|
|
92
|
+
toolCallRegistry = new ToolCallRegistry();
|
|
91
93
|
convertToLlm;
|
|
92
94
|
transformContext;
|
|
93
95
|
streamFn;
|
|
@@ -100,8 +102,6 @@ export class Agent {
|
|
|
100
102
|
activeRun;
|
|
101
103
|
/** Session identifier forwarded to providers for cache-aware backends. */
|
|
102
104
|
sessionId;
|
|
103
|
-
/** Optional per-level thinking token budgets forwarded to the stream function. */
|
|
104
|
-
thinkingBudgets;
|
|
105
105
|
/** Preferred transport forwarded to the stream function. */
|
|
106
106
|
transport;
|
|
107
107
|
/** Optional cap for provider-requested retry delays. */
|
|
@@ -122,7 +122,6 @@ export class Agent {
|
|
|
122
122
|
this.steeringQueue = new PendingMessageQueue(options.steeringMode ?? "one-at-a-time");
|
|
123
123
|
this.followUpQueue = new PendingMessageQueue(options.followUpMode ?? "one-at-a-time");
|
|
124
124
|
this.sessionId = options.sessionId;
|
|
125
|
-
this.thinkingBudgets = options.thinkingBudgets;
|
|
126
125
|
this.transport = options.transport ?? "auto";
|
|
127
126
|
this.maxRetryDelayMs = options.maxRetryDelayMs;
|
|
128
127
|
this.toolExecution = options.toolExecution ?? "parallel";
|
|
@@ -196,6 +195,17 @@ export class Agent {
|
|
|
196
195
|
abort() {
|
|
197
196
|
this.activeRun?.abortController.abort();
|
|
198
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Stop a single in-flight tool call (user-initiated per-call stop).
|
|
200
|
+
*
|
|
201
|
+
* Aborts only the targeted call's execution — siblings keep running and the
|
|
202
|
+
* agent loop CONTINUES the turn with a synthesized user-stop tool result
|
|
203
|
+
* ("Tool call stopped by user (was running too long)"). Returns false for
|
|
204
|
+
* unknown/finished toolCallIds (no-op).
|
|
205
|
+
*/
|
|
206
|
+
async stopToolCall(toolCallId, reason) {
|
|
207
|
+
return this.toolCallRegistry.stop(toolCallId, reason);
|
|
208
|
+
}
|
|
199
209
|
/**
|
|
200
210
|
* Resolve when the current run and all awaited event listeners have finished.
|
|
201
211
|
*
|
|
@@ -211,6 +221,7 @@ export class Agent {
|
|
|
211
221
|
this._state.streamingMessage = undefined;
|
|
212
222
|
this._state.pendingToolCalls = new Set();
|
|
213
223
|
this._state.errorMessage = undefined;
|
|
224
|
+
this.toolCallRegistry.clear();
|
|
214
225
|
this.clearFollowUpQueue();
|
|
215
226
|
this.clearSteeringQueue();
|
|
216
227
|
}
|
|
@@ -284,7 +295,6 @@ export class Agent {
|
|
|
284
295
|
onPayload: this.onPayload,
|
|
285
296
|
onResponse: this.onResponse,
|
|
286
297
|
transport: this.transport,
|
|
287
|
-
thinkingBudgets: this.thinkingBudgets,
|
|
288
298
|
maxRetryDelayMs: this.maxRetryDelayMs,
|
|
289
299
|
toolExecution: this.toolExecution,
|
|
290
300
|
beforeToolCall: this.beforeToolCall,
|
|
@@ -301,6 +311,7 @@ export class Agent {
|
|
|
301
311
|
return this.steeringQueue.drain();
|
|
302
312
|
},
|
|
303
313
|
getFollowUpMessages: async () => this.followUpQueue.drain(),
|
|
314
|
+
toolCallRegistry: this.toolCallRegistry,
|
|
304
315
|
};
|
|
305
316
|
}
|
|
306
317
|
async runWithLifecycle(executor) {
|
|
@@ -316,6 +327,7 @@ export class Agent {
|
|
|
316
327
|
this._state.isStreaming = true;
|
|
317
328
|
this._state.streamingMessage = undefined;
|
|
318
329
|
this._state.errorMessage = undefined;
|
|
330
|
+
this.toolCallRegistry.clear();
|
|
319
331
|
try {
|
|
320
332
|
await executor(abortController.signal);
|
|
321
333
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Killable registry of in-flight tool executions for one agent run.
|
|
3
|
+
*
|
|
4
|
+
* The agent loop hands every `tool.execute()` a run-level abort signal, which
|
|
5
|
+
* makes whole-turn cancellation the only kill path. This registry adds a
|
|
6
|
+
* per-call controller chained from the run signal so a single hung/long-running
|
|
7
|
+
* tool call can be aborted on its own (`stopToolCall`) while its siblings keep
|
|
8
|
+
* running and the agent loop continues the turn.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle:
|
|
11
|
+
* - `register()` is called by the tool executor right before execution and
|
|
12
|
+
* returns a handle carrying the per-call abort signal.
|
|
13
|
+
* - `settle()` is called by the executor when the call finishes (success or
|
|
14
|
+
* error) — it removes the entry and resolves the handle's `settled` promise,
|
|
15
|
+
* which is what `stop()` awaits.
|
|
16
|
+
* - `stop()` marks a user-initiated stop (so the caught abort error is
|
|
17
|
+
* replaced by the synthesized user-stop tool result), aborts only the
|
|
18
|
+
* targeted call's controller, and resolves once the call settles.
|
|
19
|
+
*
|
|
20
|
+
* Chaining: when the run-level signal aborts (turn cancel), every per-call
|
|
21
|
+
* controller aborts too, so existing whole-turn cancel behavior is preserved.
|
|
22
|
+
*/
|
|
23
|
+
/** Default reason recorded on the handle when the caller passes none. */
|
|
24
|
+
export declare const DEFAULT_USER_STOP_REASON = "stopped by user";
|
|
25
|
+
/**
|
|
26
|
+
* Exactly-matching synthesized toolResult content per the `stop_tool_call`
|
|
27
|
+
* wire contract. The wire tool_result frame carries `stoppedByUser: true`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const USER_STOP_TOOL_RESULT_TEXT = "Tool call stopped by user (was running too long)";
|
|
30
|
+
/** Handle for one in-flight tool call execution. */
|
|
31
|
+
export interface InFlightToolCallHandle {
|
|
32
|
+
readonly toolCallId: string;
|
|
33
|
+
readonly toolName: string;
|
|
34
|
+
/** Per-call abort signal source. `controller.signal` is what tools receive. */
|
|
35
|
+
readonly controller: AbortController;
|
|
36
|
+
/** Resolves when the executor settles this call (success or error). */
|
|
37
|
+
readonly settled: Promise<void>;
|
|
38
|
+
/** Set true when a user-initiated stop targets this call. */
|
|
39
|
+
userStopRequested: boolean;
|
|
40
|
+
/** Reason supplied by the caller of `stop()` (defaults to "stopped by user"). */
|
|
41
|
+
userStopReason?: string;
|
|
42
|
+
/** Resolve the `settled` promise. Called by the executor, not by callers. */
|
|
43
|
+
settle(): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Per-run killable registry of in-flight tool executions.
|
|
47
|
+
* Keyed by toolCallId; one Agent owns one registry per run.
|
|
48
|
+
*/
|
|
49
|
+
export declare class ToolCallRegistry {
|
|
50
|
+
private readonly calls;
|
|
51
|
+
/**
|
|
52
|
+
* Register an in-flight call and return its handle. The returned
|
|
53
|
+
* controller's signal aborts when this call is stopped individually OR
|
|
54
|
+
* when the run-level signal aborts (turn cancel propagates).
|
|
55
|
+
*/
|
|
56
|
+
register(toolCallId: string, toolName: string, runSignal?: AbortSignal): InFlightToolCallHandle;
|
|
57
|
+
/** Look up an in-flight call by id. Undefined for unknown/finished ids. */
|
|
58
|
+
get(toolCallId: string): InFlightToolCallHandle | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Mark a user-initiated stop and abort only this call's controller.
|
|
61
|
+
* Returns false for unknown/finished ids (no-op). Idempotent: a second
|
|
62
|
+
* stop for the same id keeps the first marker and reason.
|
|
63
|
+
*/
|
|
64
|
+
markUserStop(toolCallId: string, reason?: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Abort only the targeted call and resolve once it settles.
|
|
67
|
+
* Returns false for unknown/finished ids (no-op).
|
|
68
|
+
*/
|
|
69
|
+
stop(toolCallId: string, reason?: string): Promise<boolean>;
|
|
70
|
+
/** Settle an in-flight call. Called by the executor when execution ends. */
|
|
71
|
+
settle(toolCallId: string): void;
|
|
72
|
+
/** Settle and drop every tracked call. Called when a run starts/ends. */
|
|
73
|
+
clear(): void;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=tool-call-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-registry.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/tool-call-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,0BAA0B,qDACY,CAAC;AAEpD,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,6DAA6D;IAC7D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,MAAM,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IAEnE;;;;OAIG;IACH,QAAQ,CACP,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,WAAW,GACrB,sBAAsB;IA+CzB,2EAA2E;IAC3E,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAI3D;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IAe1D;;;OAGG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMjE,4EAA4E;IAC5E,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,yEAAyE;IACzE,KAAK,IAAI,IAAI;CAIb"}
|