@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.
Files changed (189) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/auth-helper.d.ts.map +1 -1
  3. package/dist/auth-helper.js +14 -8
  4. package/dist/commands/login.d.ts +12 -4
  5. package/dist/commands/login.d.ts.map +1 -1
  6. package/dist/commands/login.js +36 -15
  7. package/dist/commands/serve.d.ts.map +1 -1
  8. package/dist/commands/serve.js +3 -0
  9. package/dist/config.d.ts +15 -0
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +10 -1
  12. package/dist/designer/data/skills/blog-post.d.ts +3 -0
  13. package/dist/designer/data/skills/blog-post.d.ts.map +1 -0
  14. package/dist/designer/data/skills/blog-post.js +84 -0
  15. package/dist/designer/data/skills/blog-post.ts +87 -0
  16. package/dist/designer/data/skills/critique.d.ts +3 -0
  17. package/dist/designer/data/skills/critique.d.ts.map +1 -0
  18. package/dist/designer/data/skills/critique.js +109 -0
  19. package/dist/designer/data/skills/critique.ts +112 -0
  20. package/dist/designer/data/skills/dashboard.d.ts +3 -0
  21. package/dist/designer/data/skills/dashboard.d.ts.map +1 -0
  22. package/dist/designer/data/skills/dashboard.js +165 -0
  23. package/dist/designer/data/skills/dashboard.ts +168 -0
  24. package/dist/designer/data/skills/design-brief.d.ts +3 -0
  25. package/dist/designer/data/skills/design-brief.d.ts.map +1 -0
  26. package/dist/designer/data/skills/design-brief.js +141 -0
  27. package/dist/designer/data/skills/design-brief.ts +144 -0
  28. package/dist/designer/data/skills/design-skill.d.ts +10 -0
  29. package/dist/designer/data/skills/design-skill.d.ts.map +1 -0
  30. package/dist/designer/data/skills/design-skill.js +1 -0
  31. package/dist/designer/data/skills/design-skill.ts +9 -0
  32. package/dist/designer/data/skills/docs-page.d.ts +3 -0
  33. package/dist/designer/data/skills/docs-page.d.ts.map +1 -0
  34. package/dist/designer/data/skills/docs-page.js +68 -0
  35. package/dist/designer/data/skills/docs-page.ts +71 -0
  36. package/dist/designer/data/skills/index.d.ts +3 -0
  37. package/dist/designer/data/skills/index.d.ts.map +1 -0
  38. package/dist/designer/data/skills/index.js +28 -0
  39. package/dist/designer/data/skills/index.ts +30 -0
  40. package/dist/designer/data/skills/magazine-poster.d.ts +3 -0
  41. package/dist/designer/data/skills/magazine-poster.d.ts.map +1 -0
  42. package/dist/designer/data/skills/magazine-poster.js +70 -0
  43. package/dist/designer/data/skills/magazine-poster.ts +73 -0
  44. package/dist/designer/data/skills/mobile-app.d.ts +3 -0
  45. package/dist/designer/data/skills/mobile-app.d.ts.map +1 -0
  46. package/dist/designer/data/skills/mobile-app.js +229 -0
  47. package/dist/designer/data/skills/mobile-app.ts +232 -0
  48. package/dist/designer/data/skills/motion-frames.d.ts +3 -0
  49. package/dist/designer/data/skills/motion-frames.d.ts.map +1 -0
  50. package/dist/designer/data/skills/motion-frames.js +121 -0
  51. package/dist/designer/data/skills/motion-frames.ts +124 -0
  52. package/dist/designer/data/skills/pricing-page.d.ts +3 -0
  53. package/dist/designer/data/skills/pricing-page.d.ts.map +1 -0
  54. package/dist/designer/data/skills/pricing-page.js +76 -0
  55. package/dist/designer/data/skills/pricing-page.ts +79 -0
  56. package/dist/designer/data/skills/saas-landing.d.ts +3 -0
  57. package/dist/designer/data/skills/saas-landing.d.ts.map +1 -0
  58. package/dist/designer/data/skills/saas-landing.js +71 -0
  59. package/dist/designer/data/skills/saas-landing.ts +74 -0
  60. package/dist/designer/data/skills/slide-deck.d.ts +3 -0
  61. package/dist/designer/data/skills/slide-deck.d.ts.map +1 -0
  62. package/dist/designer/data/skills/slide-deck.js +213 -0
  63. package/dist/designer/data/skills/slide-deck.ts +216 -0
  64. package/dist/designer/data/skills/social-carousel.d.ts +3 -0
  65. package/dist/designer/data/skills/social-carousel.d.ts.map +1 -0
  66. package/dist/designer/data/skills/social-carousel.js +135 -0
  67. package/dist/designer/data/skills/social-carousel.ts +138 -0
  68. package/dist/designer/data/skills/web-prototype.d.ts +3 -0
  69. package/dist/designer/data/skills/web-prototype.d.ts.map +1 -0
  70. package/dist/designer/data/skills/web-prototype.js +159 -0
  71. package/dist/designer/data/skills/web-prototype.ts +162 -0
  72. package/dist/designer/skills.d.ts +4 -10
  73. package/dist/designer/skills.d.ts.map +1 -1
  74. package/dist/designer/skills.js +2 -1643
  75. package/dist/extensions/wizard/index.js +9 -1
  76. package/dist/generated/parser/ast/nodes.d.ts +115 -0
  77. package/dist/generated/parser/ast/nodes.d.ts.map +1 -0
  78. package/dist/generated/parser/ast/nodes.js +8 -0
  79. package/dist/generated/parser/lexer/lexer.d.ts +28 -0
  80. package/dist/generated/parser/lexer/lexer.d.ts.map +1 -0
  81. package/dist/generated/parser/{lexer.js → lexer/lexer.js} +1 -180
  82. package/dist/generated/parser/{lexer.d.ts → lexer/tokens.d.ts} +5 -24
  83. package/dist/generated/parser/lexer/tokens.d.ts.map +1 -0
  84. package/dist/generated/parser/lexer/tokens.js +187 -0
  85. package/dist/generated/parser/mod.d.ts +5 -7
  86. package/dist/generated/parser/mod.d.ts.map +1 -1
  87. package/dist/generated/parser/mod.js +2 -1
  88. package/dist/generated/parser/parser/cursor.d.ts +47 -0
  89. package/dist/generated/parser/parser/cursor.d.ts.map +1 -0
  90. package/dist/generated/parser/parser/cursor.js +12 -0
  91. package/dist/generated/parser/parser/definitions.d.ts +16 -0
  92. package/dist/generated/parser/parser/definitions.d.ts.map +1 -0
  93. package/dist/generated/parser/parser/definitions.js +353 -0
  94. package/dist/generated/parser/parser/expressions.d.ts +17 -0
  95. package/dist/generated/parser/parser/expressions.d.ts.map +1 -0
  96. package/dist/generated/parser/parser/expressions.js +165 -0
  97. package/dist/generated/parser/parser.d.ts +18 -133
  98. package/dist/generated/parser/parser.d.ts.map +1 -1
  99. package/dist/generated/parser/parser.js +9 -505
  100. package/dist/generated/parser/tokenizer.d.ts +1 -2
  101. package/dist/generated/parser/tokenizer.d.ts.map +1 -1
  102. package/dist/generated/parser/tokenizer.js +2 -1
  103. package/dist/generated/parser/validator.d.ts +1 -1
  104. package/dist/generated/parser/validator.d.ts.map +1 -1
  105. package/dist/generated/zeus/const.d.ts.map +1 -1
  106. package/dist/generated/zeus/const.js +21 -0
  107. package/dist/generated/zeus/index.d.ts +98 -0
  108. package/dist/generated/zeus/index.d.ts.map +1 -1
  109. package/dist/mcp/glimpse-ui.js +9 -1
  110. package/dist/relay/dispatcher.d.ts +11 -104
  111. package/dist/relay/dispatcher.d.ts.map +1 -1
  112. package/dist/relay/dispatcher.js +10 -1130
  113. package/dist/relay/registration.d.ts +10 -2
  114. package/dist/relay/registration.d.ts.map +1 -1
  115. package/dist/relay/registration.js +32 -3
  116. package/dist/relay/rest.d.ts +31 -0
  117. package/dist/relay/rest.d.ts.map +1 -0
  118. package/dist/relay/rest.js +85 -0
  119. package/dist/relay/routing.d.ts +109 -0
  120. package/dist/relay/routing.d.ts.map +1 -0
  121. package/dist/relay/routing.js +669 -0
  122. package/dist/relay/wizard-login.d.ts +17 -0
  123. package/dist/relay/wizard-login.d.ts.map +1 -0
  124. package/dist/relay/wizard-login.js +419 -0
  125. package/dist/sdk/agent-core/agent-loop.d.ts +2 -9
  126. package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
  127. package/dist/sdk/agent-core/agent-loop.js +4 -288
  128. package/dist/sdk/agent-core/tool-execution.d.ts +33 -0
  129. package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -0
  130. package/dist/sdk/agent-core/tool-execution.js +300 -0
  131. package/dist/sdk/ai/env-api-keys.js +9 -1
  132. package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts +48 -0
  133. package/dist/sdk/ai/providers/openai/reasoning-replay.d.ts.map +1 -0
  134. package/dist/sdk/ai/providers/openai/reasoning-replay.js +209 -0
  135. package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
  136. package/dist/sdk/ai/providers/openai-completions.js +1 -203
  137. package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +6 -118
  138. package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
  139. package/dist/sdk/coding-agent/core/compaction/compaction.js +11 -733
  140. package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts +58 -0
  141. package/dist/sdk/coding-agent/core/compaction/cut-points.d.ts.map +1 -0
  142. package/dist/sdk/coding-agent/core/compaction/cut-points.js +191 -0
  143. package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts +28 -0
  144. package/dist/sdk/coding-agent/core/compaction/dedupe.d.ts.map +1 -0
  145. package/dist/sdk/coding-agent/core/compaction/dedupe.js +156 -0
  146. package/dist/sdk/coding-agent/core/compaction/summarize.d.ts +21 -0
  147. package/dist/sdk/coding-agent/core/compaction/summarize.d.ts.map +1 -0
  148. package/dist/sdk/coding-agent/core/compaction/summarize.js +181 -0
  149. package/dist/sdk/coding-agent/core/compaction/tokens.d.ts +47 -0
  150. package/dist/sdk/coding-agent/core/compaction/tokens.d.ts.map +1 -0
  151. package/dist/sdk/coding-agent/core/compaction/tokens.js +224 -0
  152. package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +157 -0
  153. package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -0
  154. package/dist/sdk/coding-agent/core/extensions/session-events.js +13 -0
  155. package/dist/sdk/coding-agent/core/extensions/types.d.ts +6 -365
  156. package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
  157. package/dist/sdk/coding-agent/core/extensions/types.js +2 -10
  158. package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts +219 -0
  159. package/dist/sdk/coding-agent/core/extensions/ui-types.d.ts.map +1 -0
  160. package/dist/sdk/coding-agent/core/extensions/ui-types.js +4 -0
  161. package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts +115 -0
  162. package/dist/sdk/coding-agent/core/package/default-package-manager.d.ts.map +1 -0
  163. package/dist/sdk/coding-agent/core/package/default-package-manager.js +1184 -0
  164. package/dist/sdk/coding-agent/core/package/discovery.d.ts +20 -0
  165. package/dist/sdk/coding-agent/core/package/discovery.d.ts.map +1 -0
  166. package/dist/sdk/coding-agent/core/package/discovery.js +283 -0
  167. package/dist/sdk/coding-agent/core/package/ignore.d.ts +29 -0
  168. package/dist/sdk/coding-agent/core/package/ignore.d.ts.map +1 -0
  169. package/dist/sdk/coding-agent/core/package/ignore.js +235 -0
  170. package/dist/sdk/coding-agent/core/package/types.d.ts +128 -0
  171. package/dist/sdk/coding-agent/core/package/types.d.ts.map +1 -0
  172. package/dist/sdk/coding-agent/core/package/types.js +18 -0
  173. package/dist/sdk/coding-agent/core/package/update-check.d.ts +43 -0
  174. package/dist/sdk/coding-agent/core/package/update-check.d.ts.map +1 -0
  175. package/dist/sdk/coding-agent/core/package/update-check.js +253 -0
  176. package/dist/sdk/coding-agent/core/package-manager.d.ts +2 -188
  177. package/dist/sdk/coding-agent/core/package-manager.d.ts.map +1 -1
  178. package/dist/sdk/coding-agent/core/package-manager.js +1 -1940
  179. package/dist/sdk/coding-agent/core/session/migrate.d.ts +18 -0
  180. package/dist/sdk/coding-agent/core/session/migrate.d.ts.map +1 -0
  181. package/dist/sdk/coding-agent/core/session/migrate.js +78 -0
  182. package/dist/sdk/coding-agent/core/session/types.d.ts +165 -0
  183. package/dist/sdk/coding-agent/core/session/types.d.ts.map +1 -0
  184. package/dist/sdk/coding-agent/core/session/types.js +4 -0
  185. package/dist/sdk/coding-agent/core/session-manager.d.ts +3 -161
  186. package/dist/sdk/coding-agent/core/session-manager.d.ts.map +1 -1
  187. package/dist/sdk/coding-agent/core/session-manager.js +4 -72
  188. package/package.json +2 -2
  189. 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, validateToolArguments, } from "../ai/index.js";
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";