@aexol/spectral 0.9.229 → 0.9.231
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/auth-helper.d.ts.map +1 -1
- package/dist/auth-helper.js +14 -8
- package/dist/commands/login.d.ts +12 -4
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +36 -15
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +3 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -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/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 +21 -0
- package/dist/generated/zeus/index.d.ts +98 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/mcp/glimpse-ui.js +9 -1
- package/dist/relay/dispatcher.d.ts +11 -104
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +10 -1130
- package/dist/relay/registration.d.ts +10 -2
- package/dist/relay/registration.d.ts.map +1 -1
- package/dist/relay/registration.js +32 -3
- 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 +4 -288
- 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 +300 -0
- package/dist/sdk/ai/env-api-keys.js +9 -1
- 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 +1 -203
- 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/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 +6 -365
- 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/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/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/package.json +2 -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. */
|
|
@@ -432,290 +435,3 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
|
|
|
432
435
|
await emit({ type: "message_end", message: finalMessage });
|
|
433
436
|
return finalMessage;
|
|
434
437
|
}
|
|
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
|
-
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool call execution for the agent loop.
|
|
3
|
+
*
|
|
4
|
+
* `executeToolCalls` runs every tool call of an assistant message —
|
|
5
|
+
* sequentially (`toolExecution: "sequential"` or any tool declaring
|
|
6
|
+
* `executionMode: "sequential"`) or in parallel — and returns the
|
|
7
|
+
* `ToolResultMessage`s plus a `terminate` flag for the loop.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from `sdk/agent-core/agent-loop.ts` — the loop module
|
|
10
|
+
* re-exports `hasMissingRequiredArguments` so existing imports keep
|
|
11
|
+
* working.
|
|
12
|
+
*/
|
|
13
|
+
import { type AssistantMessage, type ToolResultMessage } from "../ai/index.js";
|
|
14
|
+
import type { AgentContext, AgentLoopConfig, AgentTool, AgentToolCall } from "./types.js";
|
|
15
|
+
import type { AgentEventSink } from "./agent-loop.js";
|
|
16
|
+
/**
|
|
17
|
+
* Execute tool calls from an assistant message.
|
|
18
|
+
*/
|
|
19
|
+
export declare function executeToolCalls(currentContext: AgentContext, assistantMessage: AssistantMessage, config: AgentLoopConfig, signal: AbortSignal | undefined, emit: AgentEventSink): Promise<ExecutedToolCallBatch>;
|
|
20
|
+
type ExecutedToolCallBatch = {
|
|
21
|
+
messages: ToolResultMessage[];
|
|
22
|
+
terminate: boolean;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Detects whether a tool call is missing any required parameter, indicating the
|
|
26
|
+
* provider truncated the response before the tool arguments were fully emitted.
|
|
27
|
+
* Used together with `stopReason === "length"` to short-circuit tool validation
|
|
28
|
+
* when a streamed tool call is incomplete (which would otherwise throw
|
|
29
|
+
* `Validation failed ... You provided: {}`).
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasMissingRequiredArguments(tool: AgentTool<any>, toolCall: AgentToolCall): boolean;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=tool-execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/tool-execution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,SAAS,EACT,aAAa,EAEd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,cAAc,EAAE,YAAY,EAC5B,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,qBAAqB,CAAC,CA2BhC;AAED,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAmXF;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAYlG"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool call execution for the agent loop.
|
|
3
|
+
*
|
|
4
|
+
* `executeToolCalls` runs every tool call of an assistant message —
|
|
5
|
+
* sequentially (`toolExecution: "sequential"` or any tool declaring
|
|
6
|
+
* `executionMode: "sequential"`) or in parallel — and returns the
|
|
7
|
+
* `ToolResultMessage`s plus a `terminate` flag for the loop.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from `sdk/agent-core/agent-loop.ts` — the loop module
|
|
10
|
+
* re-exports `hasMissingRequiredArguments` so existing imports keep
|
|
11
|
+
* working.
|
|
12
|
+
*/
|
|
13
|
+
import { validateToolArguments, } from "../ai/index.js";
|
|
14
|
+
/**
|
|
15
|
+
* Execute tool calls from an assistant message.
|
|
16
|
+
*/
|
|
17
|
+
export async function executeToolCalls(currentContext, assistantMessage, config, signal, emit) {
|
|
18
|
+
const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
|
|
19
|
+
const hasSequentialToolCall = toolCalls.some((tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode ===
|
|
20
|
+
"sequential");
|
|
21
|
+
if (config.toolExecution === "sequential" || hasSequentialToolCall) {
|
|
22
|
+
return executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);
|
|
23
|
+
}
|
|
24
|
+
return executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);
|
|
25
|
+
}
|
|
26
|
+
async function executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit) {
|
|
27
|
+
const finalizedCalls = [];
|
|
28
|
+
const messages = [];
|
|
29
|
+
for (const toolCall of toolCalls) {
|
|
30
|
+
await emit({
|
|
31
|
+
type: "tool_execution_start",
|
|
32
|
+
toolCallId: toolCall.id,
|
|
33
|
+
toolName: toolCall.name,
|
|
34
|
+
args: toolCall.arguments,
|
|
35
|
+
});
|
|
36
|
+
const preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);
|
|
37
|
+
let finalized;
|
|
38
|
+
if (preparation.kind === "immediate") {
|
|
39
|
+
finalized = {
|
|
40
|
+
toolCall,
|
|
41
|
+
result: preparation.result,
|
|
42
|
+
isError: preparation.isError,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const executed = await executePreparedToolCall(preparation, signal, emit);
|
|
47
|
+
finalized = await finalizeExecutedToolCall(currentContext, assistantMessage, preparation, executed, config, signal);
|
|
48
|
+
}
|
|
49
|
+
await emitToolExecutionEnd(finalized, emit);
|
|
50
|
+
const toolResultMessage = createToolResultMessage(finalized);
|
|
51
|
+
await emitToolResultMessage(toolResultMessage, emit);
|
|
52
|
+
finalizedCalls.push(finalized);
|
|
53
|
+
messages.push(toolResultMessage);
|
|
54
|
+
if (signal?.aborted) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
messages,
|
|
60
|
+
terminate: shouldTerminateToolBatch(finalizedCalls),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit) {
|
|
64
|
+
const finalizedCalls = [];
|
|
65
|
+
for (const toolCall of toolCalls) {
|
|
66
|
+
await emit({
|
|
67
|
+
type: "tool_execution_start",
|
|
68
|
+
toolCallId: toolCall.id,
|
|
69
|
+
toolName: toolCall.name,
|
|
70
|
+
args: toolCall.arguments,
|
|
71
|
+
});
|
|
72
|
+
const preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);
|
|
73
|
+
if (preparation.kind === "immediate") {
|
|
74
|
+
const finalized = {
|
|
75
|
+
toolCall,
|
|
76
|
+
result: preparation.result,
|
|
77
|
+
isError: preparation.isError,
|
|
78
|
+
};
|
|
79
|
+
await emitToolExecutionEnd(finalized, emit);
|
|
80
|
+
finalizedCalls.push(finalized);
|
|
81
|
+
if (signal?.aborted) {
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
finalizedCalls.push(async () => {
|
|
87
|
+
const executed = await executePreparedToolCall(preparation, signal, emit);
|
|
88
|
+
const finalized = await finalizeExecutedToolCall(currentContext, assistantMessage, preparation, executed, config, signal);
|
|
89
|
+
await emitToolExecutionEnd(finalized, emit);
|
|
90
|
+
return finalized;
|
|
91
|
+
});
|
|
92
|
+
if (signal?.aborted) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const orderedFinalizedCalls = await Promise.all(finalizedCalls.map((entry) => typeof entry === "function" ? entry() : Promise.resolve(entry)));
|
|
97
|
+
const messages = [];
|
|
98
|
+
for (const finalized of orderedFinalizedCalls) {
|
|
99
|
+
const toolResultMessage = createToolResultMessage(finalized);
|
|
100
|
+
await emitToolResultMessage(toolResultMessage, emit);
|
|
101
|
+
messages.push(toolResultMessage);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
messages,
|
|
105
|
+
terminate: shouldTerminateToolBatch(orderedFinalizedCalls),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function shouldTerminateToolBatch(finalizedCalls) {
|
|
109
|
+
return (finalizedCalls.length > 0 &&
|
|
110
|
+
finalizedCalls.every((finalized) => finalized.result.terminate === true));
|
|
111
|
+
}
|
|
112
|
+
function prepareToolCallArguments(tool, toolCall) {
|
|
113
|
+
if (!tool.prepareArguments) {
|
|
114
|
+
return toolCall;
|
|
115
|
+
}
|
|
116
|
+
const preparedArguments = tool.prepareArguments(toolCall.arguments);
|
|
117
|
+
if (preparedArguments === toolCall.arguments) {
|
|
118
|
+
return toolCall;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
...toolCall,
|
|
122
|
+
arguments: preparedArguments,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function prepareToolCall(currentContext, assistantMessage, toolCall, config, signal) {
|
|
126
|
+
const tool = currentContext.tools?.find((t) => t.name === toolCall.name);
|
|
127
|
+
if (!tool) {
|
|
128
|
+
return {
|
|
129
|
+
kind: "immediate",
|
|
130
|
+
result: createErrorToolResult(`Tool ${toolCall.name} not found`),
|
|
131
|
+
isError: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// If the provider truncated the response mid tool-call (stopReason "length"),
|
|
135
|
+
// the streaming JSON parser may have produced an empty or incomplete arguments
|
|
136
|
+
// object. Validating it would surface a raw `Validation failed ... You provided:
|
|
137
|
+
// {}` error to the model. Instead, return a soft error so the agent-session
|
|
138
|
+
// length-continuation path (which treats truncated tool calls as visible output)
|
|
139
|
+
// can resubmit and let the model re-emit the full tool call.
|
|
140
|
+
if (assistantMessage.stopReason === "length" && hasMissingRequiredArguments(tool, toolCall)) {
|
|
141
|
+
return {
|
|
142
|
+
kind: "immediate",
|
|
143
|
+
result: createErrorToolResult(`Tool "${toolCall.name}" was truncated before its arguments were fully emitted. ` +
|
|
144
|
+
`Retrying: please re-emit the complete tool call with all required parameters.`),
|
|
145
|
+
isError: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const preparedToolCall = prepareToolCallArguments(tool, toolCall);
|
|
150
|
+
const validatedArgs = validateToolArguments(tool, preparedToolCall);
|
|
151
|
+
if (config.beforeToolCall) {
|
|
152
|
+
const beforeResult = await config.beforeToolCall({
|
|
153
|
+
assistantMessage,
|
|
154
|
+
toolCall,
|
|
155
|
+
args: validatedArgs,
|
|
156
|
+
context: currentContext,
|
|
157
|
+
}, signal);
|
|
158
|
+
if (signal?.aborted) {
|
|
159
|
+
return {
|
|
160
|
+
kind: "immediate",
|
|
161
|
+
result: createErrorToolResult("Operation aborted"),
|
|
162
|
+
isError: true,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
if (beforeResult?.block) {
|
|
166
|
+
return {
|
|
167
|
+
kind: "immediate",
|
|
168
|
+
result: createErrorToolResult(beforeResult.reason || "Tool execution was blocked"),
|
|
169
|
+
isError: true,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (signal?.aborted) {
|
|
174
|
+
return {
|
|
175
|
+
kind: "immediate",
|
|
176
|
+
result: createErrorToolResult("Operation aborted"),
|
|
177
|
+
isError: true,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
kind: "prepared",
|
|
182
|
+
toolCall,
|
|
183
|
+
tool,
|
|
184
|
+
args: validatedArgs,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
kind: "immediate",
|
|
190
|
+
result: createErrorToolResult(error instanceof Error ? error.message : String(error)),
|
|
191
|
+
isError: true,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function executePreparedToolCall(prepared, signal, emit) {
|
|
196
|
+
const updateEvents = [];
|
|
197
|
+
try {
|
|
198
|
+
const result = await prepared.tool.execute(prepared.toolCall.id, prepared.args, signal, (partialResult) => {
|
|
199
|
+
updateEvents.push(Promise.resolve(emit({
|
|
200
|
+
type: "tool_execution_update",
|
|
201
|
+
toolCallId: prepared.toolCall.id,
|
|
202
|
+
toolName: prepared.toolCall.name,
|
|
203
|
+
args: prepared.toolCall.arguments,
|
|
204
|
+
partialResult,
|
|
205
|
+
})));
|
|
206
|
+
});
|
|
207
|
+
await Promise.all(updateEvents);
|
|
208
|
+
return { result, isError: false };
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
await Promise.all(updateEvents);
|
|
212
|
+
return {
|
|
213
|
+
result: createErrorToolResult(error instanceof Error ? error.message : String(error)),
|
|
214
|
+
isError: true,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function finalizeExecutedToolCall(currentContext, assistantMessage, prepared, executed, config, signal) {
|
|
219
|
+
let result = executed.result;
|
|
220
|
+
let isError = executed.isError;
|
|
221
|
+
if (config.afterToolCall) {
|
|
222
|
+
try {
|
|
223
|
+
const afterResult = await config.afterToolCall({
|
|
224
|
+
assistantMessage,
|
|
225
|
+
toolCall: prepared.toolCall,
|
|
226
|
+
args: prepared.args,
|
|
227
|
+
result,
|
|
228
|
+
isError,
|
|
229
|
+
context: currentContext,
|
|
230
|
+
}, signal);
|
|
231
|
+
if (afterResult) {
|
|
232
|
+
result = {
|
|
233
|
+
content: afterResult.content ?? result.content,
|
|
234
|
+
details: afterResult.details ?? result.details,
|
|
235
|
+
terminate: afterResult.terminate ?? result.terminate,
|
|
236
|
+
};
|
|
237
|
+
isError = afterResult.isError ?? isError;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
result = createErrorToolResult(error instanceof Error ? error.message : String(error));
|
|
242
|
+
isError = true;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
toolCall: prepared.toolCall,
|
|
247
|
+
result,
|
|
248
|
+
isError,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function createErrorToolResult(message) {
|
|
252
|
+
return {
|
|
253
|
+
content: [{ type: "text", text: message }],
|
|
254
|
+
details: {},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Detects whether a tool call is missing any required parameter, indicating the
|
|
259
|
+
* provider truncated the response before the tool arguments were fully emitted.
|
|
260
|
+
* Used together with `stopReason === "length"` to short-circuit tool validation
|
|
261
|
+
* when a streamed tool call is incomplete (which would otherwise throw
|
|
262
|
+
* `Validation failed ... You provided: {}`).
|
|
263
|
+
*/
|
|
264
|
+
export function hasMissingRequiredArguments(tool, toolCall) {
|
|
265
|
+
const schema = tool.parameters;
|
|
266
|
+
const required = schema.required;
|
|
267
|
+
if (!Array.isArray(required) || required.length === 0)
|
|
268
|
+
return false;
|
|
269
|
+
const args = toolCall.arguments;
|
|
270
|
+
if (!args || typeof args !== "object")
|
|
271
|
+
return true;
|
|
272
|
+
return required.some((key) => !(key in args) ||
|
|
273
|
+
args[key] === undefined ||
|
|
274
|
+
args[key] === null ||
|
|
275
|
+
(typeof args[key] === "string" && args[key].trim() === ""));
|
|
276
|
+
}
|
|
277
|
+
async function emitToolExecutionEnd(finalized, emit) {
|
|
278
|
+
await emit({
|
|
279
|
+
type: "tool_execution_end",
|
|
280
|
+
toolCallId: finalized.toolCall.id,
|
|
281
|
+
toolName: finalized.toolCall.name,
|
|
282
|
+
result: finalized.result,
|
|
283
|
+
isError: finalized.isError,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function createToolResultMessage(finalized) {
|
|
287
|
+
return {
|
|
288
|
+
role: "toolResult",
|
|
289
|
+
toolCallId: finalized.toolCall.id,
|
|
290
|
+
toolName: finalized.toolCall.name,
|
|
291
|
+
content: finalized.result.content,
|
|
292
|
+
details: finalized.result.details,
|
|
293
|
+
isError: finalized.isError,
|
|
294
|
+
timestamp: Date.now(),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
async function emitToolResultMessage(toolResultMessage, emit) {
|
|
298
|
+
await emit({ type: "message_start", message: toolResultMessage });
|
|
299
|
+
await emit({ type: "message_end", message: toolResultMessage });
|
|
300
|
+
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
// NEVER convert to top-level imports - breaks browser/Vite builds
|
|
2
10
|
let _existsSync = null;
|
|
3
11
|
let _homedir = null;
|
|
4
12
|
let _join = null;
|
|
5
|
-
const dynamicImport = (specifier) => import(specifier);
|
|
13
|
+
const dynamicImport = (specifier) => import(__rewriteRelativeImportExtension(specifier));
|
|
6
14
|
const NODE_FS_SPECIFIER = "node:" + "fs";
|
|
7
15
|
const NODE_OS_SPECIFIER = "node:" + "os";
|
|
8
16
|
const NODE_PATH_SPECIFIER = "node:" + "path";
|