@tanstack/ai 0.59.0 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +1 -0
  2. package/dist/esm/activities/chat/adapter.d.ts +9 -0
  3. package/dist/esm/activities/chat/adapter.js +1 -0
  4. package/dist/esm/activities/chat/adapter.js.map +1 -1
  5. package/dist/esm/activities/chat/agents/define-agent.d.ts +17 -5
  6. package/dist/esm/activities/chat/agents/define-agent.js.map +1 -1
  7. package/dist/esm/activities/chat/agents/spawn.d.ts +2 -0
  8. package/dist/esm/activities/chat/agents/spawn.js +8 -5
  9. package/dist/esm/activities/chat/agents/spawn.js.map +1 -1
  10. package/dist/esm/activities/chat/index.js +289 -78
  11. package/dist/esm/activities/chat/index.js.map +1 -1
  12. package/dist/esm/activities/chat/messages.js +35 -19
  13. package/dist/esm/activities/chat/messages.js.map +1 -1
  14. package/dist/esm/activities/chat/middleware/types.d.ts +1 -0
  15. package/dist/esm/activities/chat/middleware/types.js.map +1 -1
  16. package/dist/esm/activities/chat/stream/message-updaters.d.ts +2 -2
  17. package/dist/esm/activities/chat/stream/message-updaters.js +11 -3
  18. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
  19. package/dist/esm/activities/chat/stream/processor.d.ts +11 -10
  20. package/dist/esm/activities/chat/stream/processor.js +51 -28
  21. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  22. package/dist/esm/activities/chat/tools/tool-calls.d.ts +16 -2
  23. package/dist/esm/activities/chat/tools/tool-calls.js +57 -16
  24. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  25. package/dist/esm/activities/chat/tools/tool-definition.d.ts +4 -0
  26. package/dist/esm/activities/chat/tools/tool-definition.js +4 -0
  27. package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
  28. package/dist/esm/activities/embed/adapter.d.ts +7 -0
  29. package/dist/esm/activities/embed/adapter.js +1 -0
  30. package/dist/esm/activities/embed/adapter.js.map +1 -1
  31. package/dist/esm/activities/embed/index.js +2 -0
  32. package/dist/esm/activities/embed/index.js.map +1 -1
  33. package/dist/esm/activities/evaluate/adapter.d.ts +4 -0
  34. package/dist/esm/activities/evaluate/adapter.js.map +1 -1
  35. package/dist/esm/activities/evaluate/index.d.ts +4 -0
  36. package/dist/esm/activities/evaluate/index.js +3 -1
  37. package/dist/esm/activities/evaluate/index.js.map +1 -1
  38. package/dist/esm/activities/files/adapter.d.ts +97 -0
  39. package/dist/esm/activities/files/adapter.js +45 -0
  40. package/dist/esm/activities/files/adapter.js.map +1 -0
  41. package/dist/esm/activities/files/index.d.ts +66 -0
  42. package/dist/esm/activities/files/index.js +78 -0
  43. package/dist/esm/activities/files/index.js.map +1 -0
  44. package/dist/esm/activities/generateImage/adapter.d.ts +8 -0
  45. package/dist/esm/activities/generateImage/adapter.js +1 -0
  46. package/dist/esm/activities/generateImage/adapter.js.map +1 -1
  47. package/dist/esm/activities/generateImage/index.js +2 -0
  48. package/dist/esm/activities/generateImage/index.js.map +1 -1
  49. package/dist/esm/activities/generateVideo/adapter.d.ts +8 -0
  50. package/dist/esm/activities/generateVideo/adapter.js +1 -0
  51. package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
  52. package/dist/esm/activities/generateVideo/index.js +3 -0
  53. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  54. package/dist/esm/activities/generateWorld/adapter.d.ts +4 -2
  55. package/dist/esm/activities/generateWorld/adapter.js.map +1 -1
  56. package/dist/esm/activities/generateWorld/index.d.ts +4 -3
  57. package/dist/esm/activities/generateWorld/index.js +5 -4
  58. package/dist/esm/activities/generateWorld/index.js.map +1 -1
  59. package/dist/esm/activities/index.d.ts +6 -3
  60. package/dist/esm/activities/index.js +13 -11
  61. package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +2 -0
  62. package/dist/esm/activities/summarize/chat-stream-summarize.js +8 -8
  63. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
  64. package/dist/esm/client.d.ts +3 -1
  65. package/dist/esm/client.js +2 -1
  66. package/dist/esm/client.js.map +1 -1
  67. package/dist/esm/index.d.ts +4 -3
  68. package/dist/esm/index.js +5 -3
  69. package/dist/esm/interrupt-resume.js +29 -4
  70. package/dist/esm/interrupt-resume.js.map +1 -1
  71. package/dist/esm/middlewares/otel.d.ts +5 -2
  72. package/dist/esm/middlewares/otel.js +114 -0
  73. package/dist/esm/middlewares/otel.js.map +1 -1
  74. package/dist/esm/types.d.ts +114 -14
  75. package/dist/esm/utilities/ag-ui-wire.js +39 -16
  76. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  77. package/dist/esm/utilities/content-source.d.ts +60 -0
  78. package/dist/esm/utilities/content-source.js +85 -0
  79. package/dist/esm/utilities/content-source.js.map +1 -0
  80. package/dist/esm/utilities/provider-executed.d.ts +7 -0
  81. package/dist/esm/utilities/provider-executed.js +10 -1
  82. package/dist/esm/utilities/provider-executed.js.map +1 -1
  83. package/dist/esm/utilities/tool-result.d.ts +14 -3
  84. package/dist/esm/utilities/tool-result.js +26 -3
  85. package/dist/esm/utilities/tool-result.js.map +1 -1
  86. package/package.json +4 -4
  87. package/skills/ai-core/adapter-configuration/SKILL.md +62 -0
  88. package/skills/ai-core/chat-experience/SKILL.md +134 -0
  89. package/skills/ai-core/media-generation/SKILL.md +8 -0
  90. package/skills/ai-core/tool-calling/SKILL.md +103 -0
  91. package/src/activities/chat/adapter.ts +10 -0
  92. package/src/activities/chat/agents/define-agent.ts +20 -3
  93. package/src/activities/chat/agents/spawn.ts +20 -12
  94. package/src/activities/chat/index.ts +458 -99
  95. package/src/activities/chat/messages.ts +52 -6
  96. package/src/activities/chat/middleware/types.ts +1 -0
  97. package/src/activities/chat/stream/message-updaters.ts +27 -2
  98. package/src/activities/chat/stream/processor.ts +81 -49
  99. package/src/activities/chat/tools/tool-calls.ts +104 -9
  100. package/src/activities/chat/tools/tool-definition.ts +8 -0
  101. package/src/activities/embed/adapter.ts +7 -0
  102. package/src/activities/embed/index.ts +5 -0
  103. package/src/activities/evaluate/adapter.ts +4 -0
  104. package/src/activities/evaluate/index.ts +6 -0
  105. package/src/activities/files/adapter.ts +120 -0
  106. package/src/activities/files/index.ts +113 -0
  107. package/src/activities/generateImage/adapter.ts +8 -0
  108. package/src/activities/generateImage/index.ts +4 -0
  109. package/src/activities/generateVideo/adapter.ts +8 -0
  110. package/src/activities/generateVideo/index.ts +7 -0
  111. package/src/activities/generateWorld/adapter.ts +4 -2
  112. package/src/activities/generateWorld/index.ts +7 -6
  113. package/src/activities/index.ts +25 -1
  114. package/src/activities/summarize/chat-stream-summarize.ts +22 -12
  115. package/src/client.ts +8 -0
  116. package/src/index.ts +17 -0
  117. package/src/interrupt-resume.ts +55 -4
  118. package/src/middlewares/otel.ts +161 -3
  119. package/src/types.ts +114 -14
  120. package/src/utilities/ag-ui-wire.ts +72 -17
  121. package/src/utilities/content-source.ts +138 -0
  122. package/src/utilities/provider-executed.ts +13 -0
  123. package/src/utilities/tool-result.ts +45 -3
package/README.md CHANGED
@@ -240,6 +240,7 @@ Official adapters include:
240
240
  | [`@tanstack/ai-byteplus`](https://tanstack.com/ai/latest/docs/adapters/byteplus) | BytePlus Seed chat, Seedance video, Seedream image, and Seed Speech TTS/ASR |
241
241
  | [`@tanstack/ai-fal`](https://tanstack.com/ai/latest/docs/adapters/fal) | fal.ai image, video, audio, speech, and transcription models |
242
242
  | [`@tanstack/ai-reactor`](https://tanstack.com/ai/latest/docs/adapters/reactor) | Reactor live world and video generation (Orbis, Happy Oyster, LingBot, Helios, FastH3) |
243
+ | [`@tanstack/ai-worldlabs`](https://tanstack.com/ai/latest/docs/adapters/worldlabs) | World Labs Marble persistent 3D world generation |
243
244
  | [`@tanstack/ai-cloudflare`](https://tanstack.com/ai/latest/docs/adapters/cloudflare) | Cloudflare Workers AI chat, embeddings, image, speech, transcription, and AI Gateway |
244
245
 
245
246
  The adapter system is tree-shakeable by activity. Import `openaiText` for chat,
@@ -69,6 +69,14 @@ export interface TextAdapter<TModel extends string, TProviderOptions extends Rec
69
69
  * this is the declaration/validation surface only.
70
70
  */
71
71
  readonly requires?: ReadonlyArray<CapabilityHandle>;
72
+ /**
73
+ * Declares that this adapter can consume `{ type: 'file' }` content sources
74
+ * (provider Files API references). `chat()` rejects file sources in preflight
75
+ * for adapters that don't declare this, so an adapter written before the
76
+ * file arm existed fails closed instead of silently mis-mapping a reference
77
+ * onto its URL/data branch.
78
+ */
79
+ readonly supportsFileSources?: boolean;
72
80
  /**
73
81
  * @internal Type-only properties for inference. Not assigned at runtime.
74
82
  */
@@ -156,6 +164,7 @@ export declare abstract class BaseTextAdapter<TModel extends string, TProviderOp
156
164
  abstract readonly name: string;
157
165
  readonly model: TModel;
158
166
  readonly requires?: ReadonlyArray<CapabilityHandle>;
167
+ readonly supportsFileSources: boolean;
159
168
  '~types': {
160
169
  providerOptions: TProviderOptions;
161
170
  inputModalities: TInputModalities;
@@ -9,6 +9,7 @@ var BaseTextAdapter = class {
9
9
  kind = "text";
10
10
  model;
11
11
  requires = void 0;
12
+ supportsFileSources = false;
12
13
  config;
13
14
  constructor(config = {}, model) {
14
15
  this.config = config;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":[],"sources":["../../../../src/activities/chat/adapter.ts"],"sourcesContent":["import type {\n DefaultMessageMetadataByModality,\n JSONSchema,\n Modality,\n TextOptions,\n TokenUsage,\n} from '../../types'\nimport type { AdapterYieldChunk } from '../../utilities/adapter-yield-chunk'\nimport type { CapabilityHandle } from './middleware/capabilities'\n\n/**\n * Configuration for adapter instances\n */\nexport interface TextAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Options for structured output generation.\n *\n * The internal logger is threaded through `chatOptions.logger` (inherited from\n * `TextOptions`). Adapter implementations must call `logger.request()` before\n * SDK calls, `logger.provider()` for each chunk received, and `logger.errors()`\n * in catch blocks.\n */\nexport interface StructuredOutputOptions<TProviderOptions extends object> {\n /** Text options for the request */\n chatOptions: TextOptions<TProviderOptions>\n /** JSON Schema for structured output - already converted from Zod in the ai layer */\n outputSchema: JSONSchema\n}\n\n/**\n * Result from structured output generation\n */\nexport interface StructuredOutputResult<T = unknown> {\n /** The parsed data conforming to the schema */\n data: T\n /** The raw text response from the model before parsing */\n rawText: string\n /** Token usage information (if provided by the adapter) */\n usage?: TokenUsage\n}\n\n/**\n * Text adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'gpt-4o')\n * - TProviderOptions: Provider-specific options for this model (already resolved)\n * - TInputModalities: Supported input modalities for this model (already resolved)\n * - TMessageMetadata: Metadata types for content parts (already resolved)\n * - TToolCapabilities: Tuple of tool-kind strings supported by this model, resolved from `supports.tools`\n * - TToolCallMetadata: Metadata type that round-trips with tool calls (e.g. Gemini's `thoughtSignature`)\n * - TSystemPromptMetadata: Provider-typed metadata accepted on each\n * `systemPrompts[i]` entry (e.g. Anthropic `cache_control`). Defaults to\n * `never` — adapters without per-prompt metadata reject the `metadata`\n * field at the call site.\n */\nexport interface TextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> {\n /** Discriminator for adapter kind */\n readonly kind: 'text'\n /** Provider name identifier (e.g., 'openai', 'anthropic') */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * Capabilities this adapter requires at runtime. `chat()` validates that the\n * configured middleware provides each one. Model adapters omit this; harness\n * adapters (e.g. a future `claudeCode()`) declare e.g. `[sandboxCapability]`.\n * Runtime access to capabilities from inside the adapter is not yet wired —\n * this is the declaration/validation surface only.\n */\n readonly requires?: ReadonlyArray<CapabilityHandle>\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n /**\n * Stream text completions from the model\n */\n chatStream: (\n options: TextOptions<TProviderOptions>,\n ) => AsyncIterable<AdapterYieldChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * This method uses stream: false and sends the JSON schema to the provider\n * to ensure the response conforms to the expected structure.\n *\n * @param options - Structured output options containing chat options and JSON schema\n * @returns Promise with the raw data (validation is done in the chat function)\n */\n structuredOutput: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => Promise<StructuredOutputResult<unknown>>\n\n /**\n * Stream structured output using the provider's native streaming structured\n * output API (stream + response_format json_schema in a single request).\n *\n * Optional — adapters without native streaming JSON omit this method and the\n * activity layer synthesizes a stream around the non-streaming\n * `structuredOutput` call.\n *\n * Implementations must emit standard AG-UI lifecycle events (RUN_STARTED,\n * TEXT_MESSAGE_*, RUN_FINISHED) carrying raw JSON text deltas, plus a final\n * `CUSTOM` event named `structured-output.complete` whose `value` is\n * `{ object, raw, reasoning? }`. Events must be timestamped when emitted so\n * their timestamps follow stream order.\n */\n structuredOutputStream?: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => AsyncIterable<AdapterYieldChunk>\n\n /**\n * Declares whether the adapter supports combining `tools` and a\n * schema-constrained final answer in a single streaming request.\n *\n * When `true`, the engine wires `outputSchema` into the regular\n * `chatStream()` call and skips the separate `runStructuredFinalization`\n * round-trip. The model's natural final turn carries the\n * schema-constrained JSON text and the engine harvests it from the agent\n * loop's accumulated content.\n *\n * When `false`, `undefined`, or the method is omitted, the engine runs\n * the agent loop without `outputSchema` and then issues a separate\n * `structuredOutput` / `structuredOutputStream` call against the JSON\n * schema for finalization (the legacy path).\n *\n * The method receives the per-call `modelOptions` so providers whose\n * support depends on the resolved upstream model (e.g. OpenRouter) can\n * answer per-request. Most adapters can return a constant.\n */\n supportsCombinedToolsAndSchema?: (\n modelOptions?: TProviderOptions | undefined,\n ) => boolean\n\n /**\n * Where native-combined structured output is taken from.\n *\n * - `'text'` (default when omitted): the agent loop's accumulated\n * assistant text is schema JSON. The engine parses it after the loop.\n * HTTP adapters use this.\n * - `'event'`: the adapter emits `structured-output.complete` during\n * `chatStream`. The engine must not parse accumulated prose. Harness\n * adapters use this.\n */\n combinedStructuredOutputSource?: (\n modelOptions?: TProviderOptions | undefined,\n ) => 'text' | 'event'\n}\n\n/**\n * A TextAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTextAdapter = TextAdapter<any, any, any, any, any, any, any>\n\n/**\n * Abstract base class for text adapters.\n * Extend this class to implement a text adapter for a specific provider.\n *\n * Generic parameters match TextAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> implements TextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n TMessageMetadataByModality,\n TToolCapabilities,\n TToolCallMetadata,\n TSystemPromptMetadata\n> {\n readonly kind = 'text' as const\n abstract readonly name: string\n readonly model: TModel\n readonly requires?: ReadonlyArray<CapabilityHandle> = undefined\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n protected config: TextAdapterConfig\n\n constructor(config: TextAdapterConfig = {}, model: TModel) {\n this.config = config\n this.model = model\n }\n\n abstract chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<AdapterYieldChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * Concrete implementations should override this to use provider-specific structured output.\n */\n abstract structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"mappings":";;;;;;;AA8LA,IAAsB,kBAAtB,MAgBE;CACA,OAAgB;CAEhB;CACA,WAAsD,KAAA;CAYtD;CAEA,YAAY,SAA4B,CAAC,GAAG,OAAe;EACzD,KAAK,SAAS;EACd,KAAK,QAAQ;CACf;CAcA,aAA+B;EAC7B,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7E;AACF"}
1
+ {"version":3,"file":"adapter.js","names":[],"sources":["../../../../src/activities/chat/adapter.ts"],"sourcesContent":["import type {\n DefaultMessageMetadataByModality,\n JSONSchema,\n Modality,\n TextOptions,\n TokenUsage,\n} from '../../types'\nimport type { AdapterYieldChunk } from '../../utilities/adapter-yield-chunk'\nimport type { CapabilityHandle } from './middleware/capabilities'\n\n/**\n * Configuration for adapter instances\n */\nexport interface TextAdapterConfig {\n apiKey?: string\n baseUrl?: string\n timeout?: number\n maxRetries?: number\n headers?: Record<string, string>\n}\n\n/**\n * Options for structured output generation.\n *\n * The internal logger is threaded through `chatOptions.logger` (inherited from\n * `TextOptions`). Adapter implementations must call `logger.request()` before\n * SDK calls, `logger.provider()` for each chunk received, and `logger.errors()`\n * in catch blocks.\n */\nexport interface StructuredOutputOptions<TProviderOptions extends object> {\n /** Text options for the request */\n chatOptions: TextOptions<TProviderOptions>\n /** JSON Schema for structured output - already converted from Zod in the ai layer */\n outputSchema: JSONSchema\n}\n\n/**\n * Result from structured output generation\n */\nexport interface StructuredOutputResult<T = unknown> {\n /** The parsed data conforming to the schema */\n data: T\n /** The raw text response from the model before parsing */\n rawText: string\n /** Token usage information (if provided by the adapter) */\n usage?: TokenUsage\n}\n\n/**\n * Text adapter interface with pre-resolved generics.\n *\n * An adapter is created by a provider function: `provider('model')` → `adapter`\n * All type resolution happens at the provider call site, not in this interface.\n *\n * Generic parameters:\n * - TModel: The specific model name (e.g., 'gpt-4o')\n * - TProviderOptions: Provider-specific options for this model (already resolved)\n * - TInputModalities: Supported input modalities for this model (already resolved)\n * - TMessageMetadata: Metadata types for content parts (already resolved)\n * - TToolCapabilities: Tuple of tool-kind strings supported by this model, resolved from `supports.tools`\n * - TToolCallMetadata: Metadata type that round-trips with tool calls (e.g. Gemini's `thoughtSignature`)\n * - TSystemPromptMetadata: Provider-typed metadata accepted on each\n * `systemPrompts[i]` entry (e.g. Anthropic `cache_control`). Defaults to\n * `never` — adapters without per-prompt metadata reject the `metadata`\n * field at the call site.\n */\nexport interface TextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> {\n /** Discriminator for adapter kind */\n readonly kind: 'text'\n /** Provider name identifier (e.g., 'openai', 'anthropic') */\n readonly name: string\n /** The model this adapter is configured for */\n readonly model: TModel\n\n /**\n * Capabilities this adapter requires at runtime. `chat()` validates that the\n * configured middleware provides each one. Model adapters omit this; harness\n * adapters (e.g. a future `claudeCode()`) declare e.g. `[sandboxCapability]`.\n * Runtime access to capabilities from inside the adapter is not yet wired —\n * this is the declaration/validation surface only.\n */\n readonly requires?: ReadonlyArray<CapabilityHandle>\n\n /**\n * Declares that this adapter can consume `{ type: 'file' }` content sources\n * (provider Files API references). `chat()` rejects file sources in preflight\n * for adapters that don't declare this, so an adapter written before the\n * file arm existed fails closed instead of silently mis-mapping a reference\n * onto its URL/data branch.\n */\n readonly supportsFileSources?: boolean\n\n /**\n * @internal Type-only properties for inference. Not assigned at runtime.\n */\n '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n /**\n * Stream text completions from the model\n */\n chatStream: (\n options: TextOptions<TProviderOptions>,\n ) => AsyncIterable<AdapterYieldChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * This method uses stream: false and sends the JSON schema to the provider\n * to ensure the response conforms to the expected structure.\n *\n * @param options - Structured output options containing chat options and JSON schema\n * @returns Promise with the raw data (validation is done in the chat function)\n */\n structuredOutput: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => Promise<StructuredOutputResult<unknown>>\n\n /**\n * Stream structured output using the provider's native streaming structured\n * output API (stream + response_format json_schema in a single request).\n *\n * Optional — adapters without native streaming JSON omit this method and the\n * activity layer synthesizes a stream around the non-streaming\n * `structuredOutput` call.\n *\n * Implementations must emit standard AG-UI lifecycle events (RUN_STARTED,\n * TEXT_MESSAGE_*, RUN_FINISHED) carrying raw JSON text deltas, plus a final\n * `CUSTOM` event named `structured-output.complete` whose `value` is\n * `{ object, raw, reasoning? }`. Events must be timestamped when emitted so\n * their timestamps follow stream order.\n */\n structuredOutputStream?: (\n options: StructuredOutputOptions<TProviderOptions>,\n ) => AsyncIterable<AdapterYieldChunk>\n\n /**\n * Declares whether the adapter supports combining `tools` and a\n * schema-constrained final answer in a single streaming request.\n *\n * When `true`, the engine wires `outputSchema` into the regular\n * `chatStream()` call and skips the separate `runStructuredFinalization`\n * round-trip. The model's natural final turn carries the\n * schema-constrained JSON text and the engine harvests it from the agent\n * loop's accumulated content.\n *\n * When `false`, `undefined`, or the method is omitted, the engine runs\n * the agent loop without `outputSchema` and then issues a separate\n * `structuredOutput` / `structuredOutputStream` call against the JSON\n * schema for finalization (the legacy path).\n *\n * The method receives the per-call `modelOptions` so providers whose\n * support depends on the resolved upstream model (e.g. OpenRouter) can\n * answer per-request. Most adapters can return a constant.\n */\n supportsCombinedToolsAndSchema?: (\n modelOptions?: TProviderOptions | undefined,\n ) => boolean\n\n /**\n * Where native-combined structured output is taken from.\n *\n * - `'text'` (default when omitted): the agent loop's accumulated\n * assistant text is schema JSON. The engine parses it after the loop.\n * HTTP adapters use this.\n * - `'event'`: the adapter emits `structured-output.complete` during\n * `chatStream`. The engine must not parse accumulated prose. Harness\n * adapters use this.\n */\n combinedStructuredOutputSource?: (\n modelOptions?: TProviderOptions | undefined,\n ) => 'text' | 'event'\n}\n\n/**\n * A TextAdapter with any/unknown type parameters.\n * Useful as a constraint in generic functions and interfaces.\n */\nexport type AnyTextAdapter = TextAdapter<any, any, any, any, any, any, any>\n\n/**\n * Abstract base class for text adapters.\n * Extend this class to implement a text adapter for a specific provider.\n *\n * Generic parameters match TextAdapter - all pre-resolved by the provider function.\n */\nexport abstract class BaseTextAdapter<\n TModel extends string,\n TProviderOptions extends Record<string, any>,\n TInputModalities extends ReadonlyArray<Modality>,\n TMessageMetadataByModality extends DefaultMessageMetadataByModality,\n TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,\n TToolCallMetadata = unknown,\n TSystemPromptMetadata = never,\n> implements TextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n TMessageMetadataByModality,\n TToolCapabilities,\n TToolCallMetadata,\n TSystemPromptMetadata\n> {\n readonly kind = 'text' as const\n abstract readonly name: string\n readonly model: TModel\n readonly requires?: ReadonlyArray<CapabilityHandle> = undefined\n readonly supportsFileSources: boolean = false\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: TProviderOptions\n inputModalities: TInputModalities\n messageMetadataByModality: TMessageMetadataByModality\n toolCapabilities: TToolCapabilities\n toolCallMetadata: TToolCallMetadata\n systemPromptMetadata: TSystemPromptMetadata\n }\n\n protected config: TextAdapterConfig\n\n constructor(config: TextAdapterConfig = {}, model: TModel) {\n this.config = config\n this.model = model\n }\n\n abstract chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<AdapterYieldChunk>\n\n /**\n * Generate structured output using the provider's native structured output API.\n * Concrete implementations should override this to use provider-specific structured output.\n */\n abstract structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>>\n\n protected generateId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n }\n}\n"],"mappings":";;;;;;;AAuMA,IAAsB,kBAAtB,MAgBE;CACA,OAAgB;CAEhB;CACA,WAAsD,KAAA;CACtD,sBAAwC;CAYxC;CAEA,YAAY,SAA4B,CAAC,GAAG,OAAe;EACzD,KAAK,SAAS;EACd,KAAK,QAAQ;CACf;CAcA,aAA+B;EAC7B,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,CAAC;CAC7E;AACF"}
@@ -1,11 +1,17 @@
1
1
  import { SubagentInfo as AGUISubagentInfo } from '@ag-ui/core';
2
2
  import { InterruptDefinition } from '../../../interrupt-definition.js';
3
- import { AnyTool, ModelMessage, RunAgentResumeItem, SchemaInput, StreamChunk, UIMessage } from '../../../types.js';
3
+ import { AnyTool, InferSchemaType, ModelMessage, RunAgentResumeItem, SchemaInput, StreamChunk, UIMessage } from '../../../types.js';
4
4
  import { AnyClientTool } from '../tools/tool-definition.js';
5
5
  /**
6
6
  * Context the library passes into {@link defineAgent} `run`.
7
+ * `TInput` is the agent's `inputSchema`.
7
8
  */
8
- export interface SubagentRunContext {
9
+ export interface SubagentRunContext<TInput extends SchemaInput | undefined = any> {
10
+ /**
11
+ * The input the parent model wrote for this child, checked against
12
+ * `inputSchema`. `undefined` when the agent has no `inputSchema`.
13
+ */
14
+ input: TInput extends SchemaInput ? InferSchemaType<TInput> : undefined;
9
15
  messages: Array<UIMessage | ModelMessage>;
10
16
  abortSignal?: AbortSignal;
11
17
  threadId: string;
@@ -37,11 +43,17 @@ export type SubagentTool = AnyTool | AnyClientTool;
37
43
  * `TTools` and `TSchema` stay on the object so `useChat({ subagents })` can
38
44
  * type that child's parts.
39
45
  */
40
- export interface DefinedAgent<TName extends string = string, TTools extends ReadonlyArray<SubagentTool> = ReadonlyArray<SubagentTool>, TSchema extends SchemaInput | undefined = SchemaInput | undefined, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = ReadonlyArray<InterruptDefinition<any, any, any, any>>> extends AGUISubagentInfo {
46
+ export interface DefinedAgent<TName extends string = string, TTools extends ReadonlyArray<SubagentTool> = ReadonlyArray<SubagentTool>, TSchema extends SchemaInput | undefined = SchemaInput | undefined, TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = ReadonlyArray<InterruptDefinition<any, any, any, any>>, TInput extends SchemaInput | undefined = any> extends AGUISubagentInfo {
41
47
  name: TName;
42
48
  /** Required here: the router and the synthetic tool both read it. */
43
49
  description: string;
44
- run: (ctx: SubagentRunContext) => AsyncIterable<StreamChunk> | Promise<AsyncIterable<StreamChunk>>;
50
+ run: (ctx: SubagentRunContext<TInput>) => AsyncIterable<StreamChunk> | Promise<AsyncIterable<StreamChunk>>;
51
+ /**
52
+ * The input the parent model writes when it calls this agent's tool, such
53
+ * as a short brief. `run` reads it as `ctx.input`. Tool mode only: a
54
+ * `subagents.router` cannot start an agent that has `inputSchema`.
55
+ */
56
+ inputSchema?: TInput;
45
57
  tools?: TTools;
46
58
  interrupts?: TInterrupts;
47
59
  outputSchema?: TSchema;
@@ -78,4 +90,4 @@ export type SubagentChoiceOptions<TAgents extends ReadonlyArray<DefinedAgent>> =
78
90
  * })
79
91
  * ```
80
92
  */
81
- export declare function defineAgent<const TName extends string, const TTools extends ReadonlyArray<SubagentTool> = readonly [], TSchema extends SchemaInput | undefined = undefined, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly []>(agent: DefinedAgent<TName, TTools, TSchema, TInterrupts>): DefinedAgent<TName, TTools, TSchema, TInterrupts>;
93
+ export declare function defineAgent<const TName extends string, const TTools extends ReadonlyArray<SubagentTool> = readonly [], TSchema extends SchemaInput | undefined = undefined, const TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> = readonly [], TInput extends SchemaInput | undefined = undefined>(agent: DefinedAgent<TName, TTools, TSchema, TInterrupts, TInput>): DefinedAgent<TName, TTools, TSchema, TInterrupts, TInput>;
@@ -1 +1 @@
1
- {"version":3,"file":"define-agent.js","names":[],"sources":["../../../../../src/activities/chat/agents/define-agent.ts"],"sourcesContent":["import type { SubagentInfo as AGUISubagentInfo } from '@ag-ui/core'\nimport type { InterruptDefinition } from '../../../interrupt-definition'\nimport type {\n AnyTool,\n ModelMessage,\n RunAgentResumeItem,\n SchemaInput,\n StreamChunk,\n UIMessage,\n} from '../../../types'\nimport type { AnyClientTool } from '../tools/tool-definition'\n\n/**\n * Context the library passes into {@link defineAgent} `run`.\n */\nexport interface SubagentRunContext {\n messages: Array<UIMessage | ModelMessage>\n abortSignal?: AbortSignal\n threadId: string\n /** Run id for the child `chat()`. */\n runId: string\n /**\n * The run this child run continues. It is the parent chat run on the first\n * run, and the interrupted parent run on a resume. Pass it to the child\n * `chat()`.\n */\n parentRunId: string\n /** Answers to this child's interrupts. Pass it to the child `chat()`. */\n resume?: Array<RunAgentResumeItem>\n /**\n * The child's AG-UI run id. Stays the same when an interrupted child\n * continues. Pass it to the child `chat()` so its middleware sees\n * `ctx.subagentRunId`.\n */\n subagentRunId: string\n parentSubagentRunId?: string\n}\n\n/**\n * A tool a child agent can carry into client part types.\n * Server tools and client tools both qualify.\n */\nexport type SubagentTool = AnyTool | AnyClientTool\n\n/**\n * A named child agent. `run` is a `chat()` call (or any stream of AG-UI chunks).\n * `TTools` and `TSchema` stay on the object so `useChat({ subagents })` can\n * type that child's parts.\n */\nexport interface DefinedAgent<\n TName extends string = string,\n TTools extends ReadonlyArray<SubagentTool> = ReadonlyArray<SubagentTool>,\n TSchema extends SchemaInput | undefined = SchemaInput | undefined,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =\n ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> extends AGUISubagentInfo {\n name: TName\n /** Required here: the router and the synthetic tool both read it. */\n description: string\n run: (\n ctx: SubagentRunContext,\n ) => AsyncIterable<StreamChunk> | Promise<AsyncIterable<StreamChunk>>\n tools?: TTools\n interrupts?: TInterrupts\n outputSchema?: TSchema\n subagents?: unknown\n}\n\n/**\n * Choice options for a `decide()` router. `main` is required plus every agent name.\n */\nexport type SubagentChoiceOptions<TAgents extends ReadonlyArray<DefinedAgent>> =\n { main: string } & {\n [K in TAgents[number]['name']]: string\n }\n\n/**\n * Define a named child agent. Pass the same object to `chat({ subagents })`.\n * Pass the agents array to `useChat({ subagents })` when you render parts\n * yourself. The hook uses it for types only. It does not call `run`.\n *\n * @example\n * ```ts\n * const researcher = defineAgent({\n * name: 'researcher',\n * description: 'Looks up facts',\n * run: (ctx) =>\n * chat({\n * adapter: openaiText('gpt-5.6'),\n * messages: ctx.messages,\n * threadId: ctx.threadId,\n * runId: ctx.runId,\n * parentRunId: ctx.parentRunId,\n * subagentRunId: ctx.subagentRunId,\n * resume: ctx.resume,\n * }),\n * })\n * ```\n */\nexport function defineAgent<\n const TName extends string,\n const TTools extends ReadonlyArray<SubagentTool> = readonly [],\n TSchema extends SchemaInput | undefined = undefined,\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = readonly [],\n>(agent: DefinedAgent<TName, TTools, TSchema, TInterrupts>) {\n if (agent.name.trim() === '') {\n throw new Error('defineAgent requires a non-empty name')\n }\n // A router returns 'main' to keep the turn on the parent.\n if (agent.name.trim() === 'main') {\n throw new Error(\n \"defineAgent cannot use the name 'main'. A router uses it for the parent.\",\n )\n }\n if (agent.description.trim() === '') {\n throw new Error('defineAgent requires a non-empty description')\n }\n return agent\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmGA,SAAgB,YAOd,OAA0D;CAC1D,IAAI,MAAM,KAAK,KAAK,MAAM,IACxB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,IAAI,MAAM,KAAK,KAAK,MAAM,QACxB,MAAM,IAAI,MACR,0EACF;CAEF,IAAI,MAAM,YAAY,KAAK,MAAM,IAC/B,MAAM,IAAI,MAAM,8CAA8C;CAEhE,OAAO;AACT"}
1
+ {"version":3,"file":"define-agent.js","names":[],"sources":["../../../../../src/activities/chat/agents/define-agent.ts"],"sourcesContent":["import type { SubagentInfo as AGUISubagentInfo } from '@ag-ui/core'\nimport type { InterruptDefinition } from '../../../interrupt-definition'\nimport type {\n AnyTool,\n InferSchemaType,\n ModelMessage,\n RunAgentResumeItem,\n SchemaInput,\n StreamChunk,\n UIMessage,\n} from '../../../types'\nimport type { AnyClientTool } from '../tools/tool-definition'\n\n/**\n * Context the library passes into {@link defineAgent} `run`.\n * `TInput` is the agent's `inputSchema`.\n */\nexport interface SubagentRunContext<\n TInput extends SchemaInput | undefined = any,\n> {\n /**\n * The input the parent model wrote for this child, checked against\n * `inputSchema`. `undefined` when the agent has no `inputSchema`.\n */\n input: TInput extends SchemaInput ? InferSchemaType<TInput> : undefined\n messages: Array<UIMessage | ModelMessage>\n abortSignal?: AbortSignal\n threadId: string\n /** Run id for the child `chat()`. */\n runId: string\n /**\n * The run this child run continues. It is the parent chat run on the first\n * run, and the interrupted parent run on a resume. Pass it to the child\n * `chat()`.\n */\n parentRunId: string\n /** Answers to this child's interrupts. Pass it to the child `chat()`. */\n resume?: Array<RunAgentResumeItem>\n /**\n * The child's AG-UI run id. Stays the same when an interrupted child\n * continues. Pass it to the child `chat()` so its middleware sees\n * `ctx.subagentRunId`.\n */\n subagentRunId: string\n parentSubagentRunId?: string\n}\n\n/**\n * A tool a child agent can carry into client part types.\n * Server tools and client tools both qualify.\n */\nexport type SubagentTool = AnyTool | AnyClientTool\n\n/**\n * A named child agent. `run` is a `chat()` call (or any stream of AG-UI chunks).\n * `TTools` and `TSchema` stay on the object so `useChat({ subagents })` can\n * type that child's parts.\n */\nexport interface DefinedAgent<\n TName extends string = string,\n TTools extends ReadonlyArray<SubagentTool> = ReadonlyArray<SubagentTool>,\n TSchema extends SchemaInput | undefined = SchemaInput | undefined,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =\n ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TInput extends SchemaInput | undefined = any,\n> extends AGUISubagentInfo {\n name: TName\n /** Required here: the router and the synthetic tool both read it. */\n description: string\n run: (\n ctx: SubagentRunContext<TInput>,\n ) => AsyncIterable<StreamChunk> | Promise<AsyncIterable<StreamChunk>>\n /**\n * The input the parent model writes when it calls this agent's tool, such\n * as a short brief. `run` reads it as `ctx.input`. Tool mode only: a\n * `subagents.router` cannot start an agent that has `inputSchema`.\n */\n inputSchema?: TInput\n tools?: TTools\n interrupts?: TInterrupts\n outputSchema?: TSchema\n subagents?: unknown\n}\n\n/**\n * Choice options for a `decide()` router. `main` is required plus every agent name.\n */\nexport type SubagentChoiceOptions<TAgents extends ReadonlyArray<DefinedAgent>> =\n { main: string } & {\n [K in TAgents[number]['name']]: string\n }\n\n/**\n * Define a named child agent. Pass the same object to `chat({ subagents })`.\n * Pass the agents array to `useChat({ subagents })` when you render parts\n * yourself. The hook uses it for types only. It does not call `run`.\n *\n * @example\n * ```ts\n * const researcher = defineAgent({\n * name: 'researcher',\n * description: 'Looks up facts',\n * run: (ctx) =>\n * chat({\n * adapter: openaiText('gpt-5.6'),\n * messages: ctx.messages,\n * threadId: ctx.threadId,\n * runId: ctx.runId,\n * parentRunId: ctx.parentRunId,\n * subagentRunId: ctx.subagentRunId,\n * resume: ctx.resume,\n * }),\n * })\n * ```\n */\nexport function defineAgent<\n const TName extends string,\n const TTools extends ReadonlyArray<SubagentTool> = readonly [],\n TSchema extends SchemaInput | undefined = undefined,\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = readonly [],\n TInput extends SchemaInput | undefined = undefined,\n>(agent: DefinedAgent<TName, TTools, TSchema, TInterrupts, TInput>) {\n if (agent.name.trim() === '') {\n throw new Error('defineAgent requires a non-empty name')\n }\n // A router returns 'main' to keep the turn on the parent.\n if (agent.name.trim() === 'main') {\n throw new Error(\n \"defineAgent cannot use the name 'main'. A router uses it for the parent.\",\n )\n }\n if (agent.description.trim() === '') {\n throw new Error('defineAgent requires a non-empty description')\n }\n return agent\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmHA,SAAgB,YAQd,OAAkE;CAClE,IAAI,MAAM,KAAK,KAAK,MAAM,IACxB,MAAM,IAAI,MAAM,uCAAuC;CAGzD,IAAI,MAAM,KAAK,KAAK,MAAM,QACxB,MAAM,IAAI,MACR,0EACF;CAEF,IAAI,MAAM,YAAY,KAAK,MAAM,IAC/B,MAAM,IAAI,MAAM,8CAA8C;CAEhE,OAAO;AACT"}
@@ -49,6 +49,8 @@ export declare function createSubagentSink(): SubagentSink;
49
49
  /** One child to start, or a suspended child to continue. */
50
50
  export interface SpawnEntry {
51
51
  name: string;
52
+ /** The checked tool input for an agent with `inputSchema`. */
53
+ input?: unknown;
52
54
  resume?: {
53
55
  subagentRunId: string;
54
56
  /** The child's own messages from the interrupted run. */
@@ -112,6 +112,7 @@ function openAgentStream(entry, bag, ctx, sink, parentToolCallId) {
112
112
  resume: resume.entries
113
113
  } : void 0;
114
114
  return spawnAgentStream(agent, {
115
+ input: entry.input,
115
116
  messages: resumed?.messages ?? ctx.messages,
116
117
  ...ctx.abortSignal ? { abortSignal: ctx.abortSignal } : {},
117
118
  threadId: childThreadId(bag.sandbox, ctx.threadId, entry.name),
@@ -438,20 +439,22 @@ function createSyntheticSubagentTools(bag, parent) {
438
439
  return bag.agents.map((agent) => ({
439
440
  name: agent.name,
440
441
  description: agent.description,
442
+ ...agent.inputSchema !== void 0 && { inputSchema: agent.inputSchema },
441
443
  [SUBAGENT_TOOL]: true,
442
- execute: async (_input, context) => {
444
+ execute: async (input, context) => {
443
445
  const toolContext = context;
444
446
  const toolCallId = toolContext?.toolCallId;
445
447
  const suspended = parent.turn?.children.find((child) => child.status === "suspended" && child.parentToolCallId !== void 0 && child.parentToolCallId === toolCallId);
446
- const entry = suspended ? {
448
+ const entry = {
447
449
  name: agent.name,
448
- resume: {
450
+ ...agent.inputSchema !== void 0 && { input },
451
+ ...suspended && { resume: {
449
452
  subagentRunId: suspended.subagentRunId,
450
453
  messages: suspended.messages,
451
454
  entries: suspended.resume,
452
455
  text: suspended.text
453
- }
454
- } : { name: agent.name };
456
+ } }
457
+ };
455
458
  const sink = createSubagentSink();
456
459
  const link = linkAbort(parent.abortSignal);
457
460
  let subagentRunId = suspended?.subagentRunId ?? "";
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.js","names":[],"sources":["../../../../../src/activities/chat/agents/spawn.ts"],"sourcesContent":["import { EventType } from '../../../types'\nimport {\n addTokenUsage,\n isTanstackUsage,\n rebuildTokenUsage,\n toSpecTokenUsage,\n} from '../../../utilities/ag-ui-usage'\nimport {\n tanstackMetadata,\n withTanstackMetadata,\n} from '../../../utilities/merge-metadata'\nimport { INTERRUPT_BINDING_METADATA_KEY } from '../../../interrupt-resume'\nimport { EMIT_STREAM_CHUNK, SUBAGENT_TOOL } from '../tools/tool-calls'\nimport type { SubagentToolOutcome } from '../tools/tool-calls'\nimport type { SpecTokenUsage } from '../../../utilities/ag-ui-usage'\nimport type {\n Interrupt,\n ModelMessage,\n RunAgentResumeItem,\n StreamChunk,\n SubagentErrorEvent,\n SubagentFinishedEvent,\n SubagentStartedEvent,\n TokenUsage,\n Tool,\n UIMessage,\n} from '../../../types'\nimport type { DefinedAgent, SubagentRunContext } from './define-agent'\nimport type { ChatMiddleware } from '../middleware/types'\nimport type { SubagentTurn } from './turn'\n\nexport const SUBAGENT_STARTED = EventType.SUBAGENT_STARTED\nexport const SUBAGENT_FINISHED = EventType.SUBAGENT_FINISHED\nexport const SUBAGENT_ERROR = EventType.SUBAGENT_ERROR\n\nexport type SubagentOrder = 'parallel' | 'sequence'\n\nexport interface SubagentRouterPlan {\n names: ReadonlyArray<string>\n /** Overrides `subagents.order` for this turn. */\n order?: SubagentOrder\n}\n\nexport interface SubagentStep {\n names: ReadonlyArray<string>\n /** Overrides `subagents.order` for this step. */\n order?: SubagentOrder\n}\n\nexport interface SubagentStepsPlan {\n steps: ReadonlyArray<SubagentStep>\n}\n\nexport type SubagentRouterPick =\n | 'main'\n | string\n | ReadonlyArray<string>\n | SubagentRouterPlan\n | SubagentStepsPlan\n\nexport interface SubagentsBag<\n TAgents extends ReadonlyArray<DefinedAgent> = ReadonlyArray<DefinedAgent>,\n> {\n agents: TAgents\n router?: (ctx: {\n messages: SubagentRunContext['messages']\n agents: NoInfer<TAgents>\n abortSignal?: AbortSignal\n }) => SubagentRouterPick | Promise<SubagentRouterPick>\n strategy?: 'exclusive' | 'handoff'\n /**\n * How a router list runs. `parallel` starts every name together.\n * `sequence` runs each name after the previous one finishes, and passes\n * that child's text to the next child.\n */\n order?: 'parallel' | 'sequence'\n sandbox?: 'own' | 'inherit'\n}\n\n/** What the children of one parent run left behind for the parent terminal. */\nexport interface SubagentSink {\n interrupts: Array<Interrupt>\n /** One AG-UI entry per child model call. */\n usage: Array<SpecTokenUsage>\n /** Summed full usage of the children, including cost. */\n total?: TokenUsage\n}\n\nexport function createSubagentSink(): SubagentSink {\n return { interrupts: [], usage: [] }\n}\n\n/** One child to start, or a suspended child to continue. */\nexport interface SpawnEntry {\n name: string\n resume?: {\n subagentRunId: string\n /** The child's own messages from the interrupted run. */\n messages: Array<UIMessage | ModelMessage>\n entries: Array<RunAgentResumeItem>\n /** Text the child wrote before it stopped. */\n text: string\n }\n}\n\ninterface SpawnContext {\n messages: SubagentRunContext['messages']\n abortSignal?: AbortSignal\n threadId: string\n /** The parent chat run. */\n parentRunId: string\n /** The interrupted parent run, on a resume. */\n interruptedRunId?: string\n}\n\nexport function createSubagentId() {\n return `subagent-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\nfunction childRunId(parentRunId: string, subagentRunId: string) {\n return `${parentRunId}:${subagentRunId}`\n}\n\n/**\n * Bind child interrupts to the parent run. The client resumes the parent run,\n * so each binding must name that run. The resumed child then validates with\n * the parent's interrupted run id.\n */\nexport function rebindInterrupts(\n interrupts: ReadonlyArray<Interrupt>,\n runId: string,\n): Array<Interrupt> {\n return interrupts.map((interrupt) => {\n const binding = interrupt.metadata?.[INTERRUPT_BINDING_METADATA_KEY]\n if (typeof binding !== 'object' || binding === null) return interrupt\n return {\n ...interrupt,\n metadata: {\n ...interrupt.metadata,\n [INTERRUPT_BINDING_METADATA_KEY]: {\n ...binding,\n interruptedRunId: runId,\n generation: 0,\n },\n },\n }\n })\n}\n\nfunction createAbortError() {\n const error = new Error('Aborted')\n error.name = 'AbortError'\n return error\n}\n\nfunction isAbortError(error: unknown, signal?: AbortSignal) {\n if (signal?.aborted) return true\n return (\n error instanceof Error &&\n (error.name === 'AbortError' || error.message === 'Aborted')\n )\n}\n\nfunction stoppedEvent(subagentRunId: string) {\n return {\n type: SUBAGENT_ERROR,\n subagentRunId,\n message: 'Stopped',\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n}\n\nfunction childThreadId(\n sandbox: SubagentsBag['sandbox'],\n parentThreadId: string,\n name: string,\n) {\n return sandbox === 'inherit' ? parentThreadId : `${parentThreadId}:${name}`\n}\n\nfunction linkAbort(parent?: AbortSignal) {\n const controller = new AbortController()\n if (!parent) return { controller, dispose: () => {} }\n if (parent.aborted) {\n controller.abort()\n return { controller, dispose: () => {} }\n }\n const onAbort = () => controller.abort()\n parent.addEventListener('abort', onAbort, { once: true })\n return {\n controller,\n dispose: () => parent.removeEventListener('abort', onAbort),\n }\n}\n\nfunction orAbort<T>(promise: Promise<T>, signal?: AbortSignal) {\n if (!signal) return promise\n if (signal.aborted) return Promise.reject(createAbortError())\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(createAbortError())\n signal.addEventListener('abort', onAbort, { once: true })\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort)\n resolve(value)\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort)\n reject(error)\n },\n )\n })\n}\n\nfunction agentByName(agents: ReadonlyArray<DefinedAgent>, name: string) {\n const agent = agents.find((entry) => entry.name === name)\n if (!agent) {\n throw new Error(`Unknown subagent: ${name}`)\n }\n return agent\n}\n\nfunction openAgentStream(\n entry: SpawnEntry,\n bag: SubagentsBag,\n ctx: SpawnContext,\n sink?: SubagentSink,\n parentToolCallId?: string,\n) {\n const agent = agentByName(bag.agents, entry.name)\n const resume = entry.resume\n const subagentRunId = resume?.subagentRunId ?? createSubagentId()\n // The parent binds child interrupts to its own run (see rebindInterrupts),\n // so the resumed child continues from the interrupted parent run id.\n if (resume !== undefined && ctx.interruptedRunId === undefined) {\n throw new Error(\n `Subagent \"${entry.name}\" has interrupt answers, but the run has no parentRunId. Pass the interrupted run id as parentRunId.`,\n )\n }\n const resumed =\n resume !== undefined\n ? {\n messages: [...ctx.messages, ...resume.messages],\n parentRunId: ctx.interruptedRunId,\n resume: resume.entries,\n }\n : undefined\n return spawnAgentStream(\n agent,\n {\n messages: resumed?.messages ?? ctx.messages,\n ...(ctx.abortSignal ? { abortSignal: ctx.abortSignal } : {}),\n threadId: childThreadId(bag.sandbox, ctx.threadId, entry.name),\n runId: childRunId(ctx.parentRunId, subagentRunId),\n parentRunId: resumed?.parentRunId ?? ctx.parentRunId,\n subagentRunId,\n ...(resumed ? { resume: resumed.resume } : {}),\n },\n sink,\n parentToolCallId,\n )\n}\n\nconst ROUTER_PICK_ERROR =\n 'subagents.router must return main, a name, a list of names, { names, order }, or { steps }.'\n\nfunction assertOrder(order: SubagentOrder | undefined) {\n if (order !== undefined && order !== 'parallel' && order !== 'sequence') {\n throw new Error('subagents.router order must be parallel or sequence.')\n }\n}\n\nfunction normalizeNames(\n names: ReadonlyArray<string>,\n agents: ReadonlyArray<DefinedAgent>,\n): ReadonlyArray<string> {\n if (names.length === 0) throw new Error(ROUTER_PICK_ERROR)\n const hasMain = names.includes('main')\n if (hasMain && names.length > 1) {\n throw new Error('Do not mix main into a subagent list.')\n }\n if (hasMain) return ['main']\n for (const name of names) agentByName(agents, name)\n return [...names]\n}\n\nfunction isStringList(pick: SubagentRouterPick): pick is ReadonlyArray<string> {\n return Array.isArray(pick)\n}\n\nexport function normalizeRouterPick(\n pick: SubagentRouterPick,\n agents: ReadonlyArray<DefinedAgent>,\n): { steps: ReadonlyArray<SubagentStep> } {\n if (pick === 'main' || typeof pick === 'string') {\n return { steps: [{ names: normalizeNames([pick], agents) }] }\n }\n if (isStringList(pick)) {\n return { steps: [{ names: normalizeNames(pick, agents) }] }\n }\n if ('steps' in pick) {\n if (pick.steps.length === 0) throw new Error(ROUTER_PICK_ERROR)\n const steps = pick.steps.map((step) => {\n assertOrder(step.order)\n const names = normalizeNames(step.names, agents)\n return step.order === undefined ? { names } : { names, order: step.order }\n })\n const flat = steps.flatMap((step) => step.names)\n if (flat.includes('main') && flat.length > 1) {\n throw new Error('Do not mix main into a subagent list.')\n }\n return { steps }\n }\n assertOrder(pick.order)\n const names = normalizeNames(pick.names, agents)\n return {\n steps: [\n pick.order === undefined ? { names } : { names, order: pick.order },\n ],\n }\n}\n\n/**\n * Tag a child chunk with its subagent. A chunk that a nested child already\n * tagged keeps its own id, and a nested child's start names this child as\n * its parent.\n */\nfunction attributeChunk(\n chunk: StreamChunk,\n subagentRunId: string,\n): StreamChunk {\n if (chunk.type === SUBAGENT_STARTED) {\n return chunk.parentSubagentRunId !== undefined\n ? chunk\n : { ...chunk, parentSubagentRunId: subagentRunId }\n }\n if (chunk.type === SUBAGENT_FINISHED || chunk.type === SUBAGENT_ERROR) {\n return chunk\n }\n if ('subagentRunId' in chunk && typeof chunk.subagentRunId === 'string') {\n return chunk\n }\n // RUN_* and MESSAGES_SNAPSHOT never get here (spawnAgentStream drops them).\n // Everything else is tagged.\n return { ...chunk, subagentRunId } as StreamChunk\n}\n\nfunction runUsage(chunk: StreamChunk | undefined): Array<SpecTokenUsage> {\n if (chunk?.type !== EventType.RUN_FINISHED) return []\n if (Array.isArray(chunk.usage)) return chunk.usage\n return isTanstackUsage(chunk.usage) ? toSpecTokenUsage(chunk.usage).usage : []\n}\n\n/** The full usage of a run: token counts plus cost and the other fields. */\nfunction fullUsage(chunk: StreamChunk | undefined): TokenUsage | undefined {\n if (chunk?.type !== EventType.RUN_FINISHED) return undefined\n return rebuildTokenUsage(chunk.usage, tanstackMetadata(chunk)?.usage)\n}\n\n/** Add a finished child run's usage to the sink. */\nexport function collectUsage(sink: SubagentSink, finished?: StreamChunk) {\n sink.usage.push(...runUsage(finished))\n const full = fullUsage(finished)\n if (full) sink.total = sink.total ? addTokenUsage(sink.total, full) : full\n}\n\n/** A parent run's last chunk: it completed, or it failed. */\ntype ParentTerminal = Extract<\n StreamChunk,\n { type: 'RUN_FINISHED' | 'RUN_ERROR' }\n>\n\n/**\n * Put the children's usage on a parent terminal. `usage[]` keeps one entry per\n * model call. `metadata.tanstack.usage` holds the summed cost and the other\n * TanStack fields, so `fromSpecTokenUsage` reads the full total. Empties the\n * sink, so the next parent terminal does not count it again.\n *\n * `RUN_ERROR` is accepted too: a turn that failed still spent whatever its\n * children spent. Such a chunk carries no usage of its own, so `runUsage` and\n * `fullUsage` return empty for it and the children's total stands alone.\n */\nexport function withChildUsage(\n chunk: ParentTerminal,\n sink: SubagentSink,\n): ParentTerminal {\n if (sink.usage.length === 0 && !sink.total) return chunk\n const own = fullUsage(chunk)\n const total =\n own && sink.total ? addTokenUsage(own, sink.total) : (own ?? sink.total)\n const usage = [...runUsage(chunk), ...sink.usage.splice(0)]\n sink.total = undefined\n const leftover = total ? toSpecTokenUsage(total).leftover : undefined\n const next = { ...chunk, usage }\n if (!leftover) return next\n // `withTanstackMetadata` runs the value through `Omit`, which collapses this\n // union and widens `type` back to `RUN_FINISHED | RUN_ERROR`. It only adds a\n // metadata key, so the runtime shape is the input's: restore that type.\n return withTanstackMetadata(next, { usage: leftover }) as ParentTerminal\n}\n\nexport async function* spawnAgentStream(\n agent: DefinedAgent,\n ctx: SubagentRunContext,\n sink?: SubagentSink,\n parentToolCallId?: string,\n): AsyncIterable<StreamChunk> {\n const id = ctx.subagentRunId\n yield {\n type: SUBAGENT_STARTED,\n subagentRunId: id,\n name: agent.name,\n description: agent.description,\n ...(ctx.parentSubagentRunId !== undefined\n ? { parentSubagentRunId: ctx.parentSubagentRunId }\n : {}),\n ...(parentToolCallId !== undefined ? { parentToolCallId } : {}),\n timestamp: Date.now(),\n } satisfies SubagentStartedEvent\n\n let iterator: AsyncIterator<StreamChunk> | undefined\n let finished: StreamChunk | undefined\n try {\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const stream = await orAbort(\n Promise.resolve(agent.run(ctx)),\n ctx.abortSignal,\n )\n iterator = stream[Symbol.asyncIterator]()\n while (true) {\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const result = await orAbort(iterator.next(), ctx.abortSignal)\n if (result.done) break\n const chunk = result.value\n // Run-scoped events describe the child run. The SUBAGENT_* events carry\n // that information for the parent stream.\n if (\n chunk.type === EventType.RUN_STARTED ||\n chunk.type === EventType.MESSAGES_SNAPSHOT\n ) {\n continue\n }\n if (chunk.type === EventType.RUN_FINISHED) {\n // The engine yields one RUN_FINISHED per model call. Add each one.\n if (sink) collectUsage(sink, chunk)\n finished = chunk\n continue\n }\n if (chunk.type === EventType.RUN_ERROR) {\n yield {\n type: SUBAGENT_ERROR,\n subagentRunId: id,\n message: chunk.message || 'Subagent failed',\n ...(chunk.code ? { code: chunk.code } : {}),\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n return\n }\n yield attributeChunk(chunk, id)\n }\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const outcome =\n finished?.type === EventType.RUN_FINISHED ? finished.outcome : undefined\n if (outcome?.type === 'cancelled') {\n yield stoppedEvent(id)\n return\n }\n if (outcome?.type === 'interrupt') {\n const interrupts = outcome.interrupts.map((interrupt) =>\n interrupt.subagentRunId\n ? interrupt\n : { ...interrupt, subagentRunId: id },\n )\n sink?.interrupts.push(...interrupts)\n yield {\n type: SUBAGENT_FINISHED,\n subagentRunId: id,\n outcome: {\n type: 'suspended',\n interruptIds: interrupts\n .filter((interrupt) => interrupt.subagentRunId === id)\n .map((interrupt) => interrupt.id),\n },\n timestamp: Date.now(),\n } satisfies SubagentFinishedEvent\n return\n }\n const result =\n finished?.type === EventType.RUN_FINISHED ? finished.result : undefined\n yield {\n type: SUBAGENT_FINISHED,\n subagentRunId: id,\n ...(result !== undefined ? { result } : {}),\n timestamp: Date.now(),\n } satisfies SubagentFinishedEvent\n } catch (error) {\n yield {\n type: SUBAGENT_ERROR,\n subagentRunId: id,\n message: isAbortError(error, ctx.abortSignal)\n ? 'Stopped'\n : error instanceof Error\n ? error.message\n : String(error),\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n } finally {\n try {\n await iterator?.return?.()\n } catch {\n // Child stream may already be closed or aborted.\n }\n }\n}\n\nasync function* mergeAgentStreams(streams: Array<AsyncIterable<StreamChunk>>) {\n const readers = streams.map((stream) => {\n const iterator = stream[Symbol.asyncIterator]()\n return {\n iterator,\n next: iterator.next(),\n }\n })\n\n try {\n while (readers.length > 0) {\n const indexed = readers.map((reader, index) =>\n reader.next.then((result) => ({ index, result, reader })),\n )\n const winner = await Promise.race(indexed)\n if (winner.result.done) {\n readers.splice(winner.index, 1)\n continue\n }\n yield winner.result.value\n winner.reader.next = winner.reader.iterator.next()\n }\n } finally {\n // The reader stopped early. Close every child so its finally runs.\n for (const reader of readers) {\n void reader.iterator.return?.().catch(() => {})\n }\n }\n}\n\n/** True when a child in these chunks failed or stopped for outside input. */\nfunction stopsSequence(chunks: ReadonlyArray<StreamChunk>, id: string) {\n return chunks.some(\n (chunk) =>\n (chunk.type === SUBAGENT_ERROR && chunk.subagentRunId === id) ||\n (chunk.type === SUBAGENT_FINISHED &&\n chunk.subagentRunId === id &&\n chunk.outcome?.type === 'suspended'),\n )\n}\n\nexport async function* spawnNamedAgents(\n entries: ReadonlyArray<SpawnEntry>,\n bag: SubagentsBag,\n ctx: SpawnContext,\n sink?: SubagentSink,\n) {\n if (bag.sandbox === 'inherit' && entries.length > 1) {\n throw new Error(\n \"subagents.sandbox 'inherit' cannot start two children in one turn\",\n )\n }\n // One signal for the group. The finally stops every child that still runs\n // when the reader stops early.\n const group = linkAbort(ctx.abortSignal)\n const groupCtx = { ...ctx, abortSignal: group.controller.signal }\n try {\n if (bag.order === 'sequence') {\n let messages = ctx.messages\n for (const entry of entries) {\n const chunks: Array<StreamChunk> = []\n let id: string | undefined\n for await (const chunk of openAgentStream(\n entry,\n bag,\n { ...groupCtx, messages },\n sink,\n )) {\n if (chunk.type === SUBAGENT_STARTED && id === undefined) {\n id = chunk.subagentRunId\n }\n chunks.push(chunk)\n yield chunk\n }\n if (id !== undefined && stopsSequence(chunks, id)) return\n const text = [\n entry.resume?.text,\n collectNamedText(chunks, [entry.name]),\n ]\n .filter((part) => part !== undefined && part !== '')\n .join('')\n if (text) {\n messages = [...messages, { role: 'assistant', content: text }]\n }\n }\n return\n }\n const streams = entries.map((entry) =>\n openAgentStream(entry, bag, groupCtx, sink),\n )\n const onlyStream = streams.length === 1 ? streams[0] : undefined\n if (onlyStream) {\n yield* onlyStream\n return\n }\n yield* mergeAgentStreams(streams)\n } finally {\n group.controller.abort()\n group.dispose()\n }\n}\n\n/**\n * Text of the named direct children, in `names` order. Text from nested\n * children stays out: their chunks carry their own id.\n */\nexport function collectNamedText(\n chunks: Array<StreamChunk>,\n names: ReadonlyArray<string>,\n) {\n const nameByRunId = new Map<string, string>()\n const textByName = new Map<string, string>()\n for (const chunk of chunks) {\n if (chunk.type === SUBAGENT_STARTED) {\n if (chunk.parentSubagentRunId === undefined) {\n nameByRunId.set(chunk.subagentRunId, chunk.name)\n }\n continue\n }\n if (chunk.type !== EventType.TEXT_MESSAGE_CONTENT) continue\n if (!('subagentRunId' in chunk) || typeof chunk.subagentRunId !== 'string')\n continue\n const name = nameByRunId.get(chunk.subagentRunId)\n if (!name) continue\n textByName.set(name, `${textByName.get(name) ?? ''}${chunk.delta}`)\n }\n return names\n .map((name) => textByName.get(name)?.trim() ?? '')\n .filter((text) => text.length > 0)\n .join('\\n\\n')\n}\n\n/**\n * The parent conversation up to the message that carries this tool call, with\n * that message's tool calls removed. Its string text stays; array content is\n * dropped.\n */\nfunction messagesBeforeCall(\n messages: ReadonlyArray<ModelMessage>,\n toolCallId: string,\n): Array<ModelMessage> {\n const index = messages.findIndex((message) =>\n message.toolCalls?.some((call) => call.id === toolCallId),\n )\n if (index === -1) return [...messages]\n const host = messages[index]\n const kept = messages.slice(0, index)\n if (host && typeof host.content === 'string' && host.content !== '') {\n const { toolCalls: _calls, ...text } = host\n void _calls\n kept.push(text)\n }\n return kept\n}\n\n/**\n * Record the parent messages when the model calls a subagent tool, so the\n * child reads the conversation as it is at that call.\n */\nexport function subagentCallMessages(names: ReadonlySet<string>) {\n const byCall = new Map<string, Array<ModelMessage>>()\n const middleware: ChatMiddleware = {\n name: 'subagent-call-messages',\n onBeforeToolCall(ctx, hook) {\n if (!names.has(hook.toolName)) return undefined\n byCall.set(\n hook.toolCallId,\n messagesBeforeCall(ctx.messages, hook.toolCallId),\n )\n return undefined\n },\n }\n return {\n middleware,\n messagesFor: (toolCallId: string | undefined) =>\n toolCallId === undefined ? undefined : byCall.get(toolCallId),\n }\n}\n\nexport function createSyntheticSubagentTools(\n bag: SubagentsBag,\n parent: {\n /** Messages the parent run started with. Used when no call was recorded. */\n messages: SubagentRunContext['messages']\n /** The parent messages at a tool call. See subagentCallMessages. */\n messagesFor?: (\n toolCallId: string | undefined,\n ) => SubagentRunContext['messages'] | undefined\n threadId: string\n runId: string\n interruptedRunId?: string\n abortSignal?: AbortSignal\n turn?: SubagentTurn\n sink: SubagentSink\n },\n): Array<Tool> {\n return bag.agents.map((agent) => ({\n name: agent.name,\n description: agent.description,\n [SUBAGENT_TOOL]: true,\n execute: async (_input: unknown, context?: unknown) => {\n const toolContext = context as\n | {\n toolCallId?: string\n [EMIT_STREAM_CHUNK]?: (chunk: StreamChunk) => void\n }\n | undefined\n const toolCallId = toolContext?.toolCallId\n const suspended = parent.turn?.children.find(\n (child) =>\n child.status === 'suspended' &&\n child.parentToolCallId !== undefined &&\n child.parentToolCallId === toolCallId,\n )\n const entry: SpawnEntry = suspended\n ? {\n name: agent.name,\n resume: {\n subagentRunId: suspended.subagentRunId,\n messages: suspended.messages,\n entries: suspended.resume,\n text: suspended.text,\n },\n }\n : { name: agent.name }\n const sink = createSubagentSink()\n const link = linkAbort(parent.abortSignal)\n let subagentRunId = suspended?.subagentRunId ?? ''\n let text = suspended?.text ?? ''\n let error: string | undefined\n try {\n for await (const chunk of openAgentStream(\n entry,\n bag,\n {\n messages: parent.messagesFor?.(toolCallId) ?? parent.messages,\n abortSignal: link.controller.signal,\n threadId: parent.threadId,\n parentRunId: parent.runId,\n ...(parent.interruptedRunId !== undefined\n ? { interruptedRunId: parent.interruptedRunId }\n : {}),\n },\n sink,\n toolCallId,\n )) {\n if (chunk.type === SUBAGENT_STARTED && subagentRunId === '') {\n subagentRunId = chunk.subagentRunId\n }\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT &&\n 'subagentRunId' in chunk &&\n chunk.subagentRunId === subagentRunId\n ) {\n text += chunk.delta\n }\n if (\n chunk.type === SUBAGENT_ERROR &&\n chunk.subagentRunId === subagentRunId\n ) {\n error = chunk.message\n }\n toolContext?.[EMIT_STREAM_CHUNK]?.(chunk)\n }\n } finally {\n link.dispose()\n }\n parent.sink.usage.push(...sink.usage)\n if (sink.total) {\n parent.sink.total = parent.sink.total\n ? addTokenUsage(parent.sink.total, sink.total)\n : sink.total\n }\n return {\n subagentRunId,\n text,\n ...(error !== undefined ? { error } : {}),\n ...(sink.interrupts.length > 0 ? { interrupts: sink.interrupts } : {}),\n } satisfies SubagentToolOutcome\n },\n }))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"spawn.js","names":[],"sources":["../../../../../src/activities/chat/agents/spawn.ts"],"sourcesContent":["import { EventType } from '../../../types'\nimport {\n addTokenUsage,\n isTanstackUsage,\n rebuildTokenUsage,\n toSpecTokenUsage,\n} from '../../../utilities/ag-ui-usage'\nimport {\n tanstackMetadata,\n withTanstackMetadata,\n} from '../../../utilities/merge-metadata'\nimport { INTERRUPT_BINDING_METADATA_KEY } from '../../../interrupt-resume'\nimport { EMIT_STREAM_CHUNK, SUBAGENT_TOOL } from '../tools/tool-calls'\nimport type { SubagentToolOutcome } from '../tools/tool-calls'\nimport type { SpecTokenUsage } from '../../../utilities/ag-ui-usage'\nimport type {\n Interrupt,\n ModelMessage,\n RunAgentResumeItem,\n StreamChunk,\n SubagentErrorEvent,\n SubagentFinishedEvent,\n SubagentStartedEvent,\n TokenUsage,\n Tool,\n UIMessage,\n} from '../../../types'\nimport type { DefinedAgent, SubagentRunContext } from './define-agent'\nimport type { ChatMiddleware } from '../middleware/types'\nimport type { SubagentTurn } from './turn'\n\nexport const SUBAGENT_STARTED = EventType.SUBAGENT_STARTED\nexport const SUBAGENT_FINISHED = EventType.SUBAGENT_FINISHED\nexport const SUBAGENT_ERROR = EventType.SUBAGENT_ERROR\n\nexport type SubagentOrder = 'parallel' | 'sequence'\n\nexport interface SubagentRouterPlan {\n names: ReadonlyArray<string>\n /** Overrides `subagents.order` for this turn. */\n order?: SubagentOrder\n}\n\nexport interface SubagentStep {\n names: ReadonlyArray<string>\n /** Overrides `subagents.order` for this step. */\n order?: SubagentOrder\n}\n\nexport interface SubagentStepsPlan {\n steps: ReadonlyArray<SubagentStep>\n}\n\nexport type SubagentRouterPick =\n | 'main'\n | string\n | ReadonlyArray<string>\n | SubagentRouterPlan\n | SubagentStepsPlan\n\nexport interface SubagentsBag<\n TAgents extends ReadonlyArray<DefinedAgent> = ReadonlyArray<DefinedAgent>,\n> {\n agents: TAgents\n router?: (ctx: {\n messages: SubagentRunContext['messages']\n agents: NoInfer<TAgents>\n abortSignal?: AbortSignal\n }) => SubagentRouterPick | Promise<SubagentRouterPick>\n strategy?: 'exclusive' | 'handoff'\n /**\n * How a router list runs. `parallel` starts every name together.\n * `sequence` runs each name after the previous one finishes, and passes\n * that child's text to the next child.\n */\n order?: 'parallel' | 'sequence'\n sandbox?: 'own' | 'inherit'\n}\n\n/** What the children of one parent run left behind for the parent terminal. */\nexport interface SubagentSink {\n interrupts: Array<Interrupt>\n /** One AG-UI entry per child model call. */\n usage: Array<SpecTokenUsage>\n /** Summed full usage of the children, including cost. */\n total?: TokenUsage\n}\n\nexport function createSubagentSink(): SubagentSink {\n return { interrupts: [], usage: [] }\n}\n\n/** One child to start, or a suspended child to continue. */\nexport interface SpawnEntry {\n name: string\n /** The checked tool input for an agent with `inputSchema`. */\n input?: unknown\n resume?: {\n subagentRunId: string\n /** The child's own messages from the interrupted run. */\n messages: Array<UIMessage | ModelMessage>\n entries: Array<RunAgentResumeItem>\n /** Text the child wrote before it stopped. */\n text: string\n }\n}\n\ninterface SpawnContext {\n messages: SubagentRunContext['messages']\n abortSignal?: AbortSignal\n threadId: string\n /** The parent chat run. */\n parentRunId: string\n /** The interrupted parent run, on a resume. */\n interruptedRunId?: string\n}\n\nexport function createSubagentId() {\n return `subagent-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\nfunction childRunId(parentRunId: string, subagentRunId: string) {\n return `${parentRunId}:${subagentRunId}`\n}\n\n/**\n * Bind child interrupts to the parent run. The client resumes the parent run,\n * so each binding must name that run. The resumed child then validates with\n * the parent's interrupted run id.\n */\nexport function rebindInterrupts(\n interrupts: ReadonlyArray<Interrupt>,\n runId: string,\n): Array<Interrupt> {\n return interrupts.map((interrupt) => {\n const binding = interrupt.metadata?.[INTERRUPT_BINDING_METADATA_KEY]\n if (typeof binding !== 'object' || binding === null) return interrupt\n return {\n ...interrupt,\n metadata: {\n ...interrupt.metadata,\n [INTERRUPT_BINDING_METADATA_KEY]: {\n ...binding,\n interruptedRunId: runId,\n generation: 0,\n },\n },\n }\n })\n}\n\nfunction createAbortError() {\n const error = new Error('Aborted')\n error.name = 'AbortError'\n return error\n}\n\nfunction isAbortError(error: unknown, signal?: AbortSignal) {\n if (signal?.aborted) return true\n return (\n error instanceof Error &&\n (error.name === 'AbortError' || error.message === 'Aborted')\n )\n}\n\nfunction stoppedEvent(subagentRunId: string) {\n return {\n type: SUBAGENT_ERROR,\n subagentRunId,\n message: 'Stopped',\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n}\n\nfunction childThreadId(\n sandbox: SubagentsBag['sandbox'],\n parentThreadId: string,\n name: string,\n) {\n return sandbox === 'inherit' ? parentThreadId : `${parentThreadId}:${name}`\n}\n\nfunction linkAbort(parent?: AbortSignal) {\n const controller = new AbortController()\n if (!parent) return { controller, dispose: () => {} }\n if (parent.aborted) {\n controller.abort()\n return { controller, dispose: () => {} }\n }\n const onAbort = () => controller.abort()\n parent.addEventListener('abort', onAbort, { once: true })\n return {\n controller,\n dispose: () => parent.removeEventListener('abort', onAbort),\n }\n}\n\nfunction orAbort<T>(promise: Promise<T>, signal?: AbortSignal) {\n if (!signal) return promise\n if (signal.aborted) return Promise.reject(createAbortError())\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => reject(createAbortError())\n signal.addEventListener('abort', onAbort, { once: true })\n promise.then(\n (value) => {\n signal.removeEventListener('abort', onAbort)\n resolve(value)\n },\n (error: unknown) => {\n signal.removeEventListener('abort', onAbort)\n reject(error)\n },\n )\n })\n}\n\nfunction agentByName(agents: ReadonlyArray<DefinedAgent>, name: string) {\n const agent = agents.find((entry) => entry.name === name)\n if (!agent) {\n throw new Error(`Unknown subagent: ${name}`)\n }\n return agent\n}\n\nfunction openAgentStream(\n entry: SpawnEntry,\n bag: SubagentsBag,\n ctx: SpawnContext,\n sink?: SubagentSink,\n parentToolCallId?: string,\n) {\n const agent = agentByName(bag.agents, entry.name)\n const resume = entry.resume\n const subagentRunId = resume?.subagentRunId ?? createSubagentId()\n // The parent binds child interrupts to its own run (see rebindInterrupts),\n // so the resumed child continues from the interrupted parent run id.\n if (resume !== undefined && ctx.interruptedRunId === undefined) {\n throw new Error(\n `Subagent \"${entry.name}\" has interrupt answers, but the run has no parentRunId. Pass the interrupted run id as parentRunId.`,\n )\n }\n const resumed =\n resume !== undefined\n ? {\n messages: [...ctx.messages, ...resume.messages],\n parentRunId: ctx.interruptedRunId,\n resume: resume.entries,\n }\n : undefined\n return spawnAgentStream(\n agent,\n {\n input: entry.input,\n messages: resumed?.messages ?? ctx.messages,\n ...(ctx.abortSignal ? { abortSignal: ctx.abortSignal } : {}),\n threadId: childThreadId(bag.sandbox, ctx.threadId, entry.name),\n runId: childRunId(ctx.parentRunId, subagentRunId),\n parentRunId: resumed?.parentRunId ?? ctx.parentRunId,\n subagentRunId,\n ...(resumed ? { resume: resumed.resume } : {}),\n },\n sink,\n parentToolCallId,\n )\n}\n\nconst ROUTER_PICK_ERROR =\n 'subagents.router must return main, a name, a list of names, { names, order }, or { steps }.'\n\nfunction assertOrder(order: SubagentOrder | undefined) {\n if (order !== undefined && order !== 'parallel' && order !== 'sequence') {\n throw new Error('subagents.router order must be parallel or sequence.')\n }\n}\n\nfunction normalizeNames(\n names: ReadonlyArray<string>,\n agents: ReadonlyArray<DefinedAgent>,\n): ReadonlyArray<string> {\n if (names.length === 0) throw new Error(ROUTER_PICK_ERROR)\n const hasMain = names.includes('main')\n if (hasMain && names.length > 1) {\n throw new Error('Do not mix main into a subagent list.')\n }\n if (hasMain) return ['main']\n for (const name of names) agentByName(agents, name)\n return [...names]\n}\n\nfunction isStringList(pick: SubagentRouterPick): pick is ReadonlyArray<string> {\n return Array.isArray(pick)\n}\n\nexport function normalizeRouterPick(\n pick: SubagentRouterPick,\n agents: ReadonlyArray<DefinedAgent>,\n): { steps: ReadonlyArray<SubagentStep> } {\n if (pick === 'main' || typeof pick === 'string') {\n return { steps: [{ names: normalizeNames([pick], agents) }] }\n }\n if (isStringList(pick)) {\n return { steps: [{ names: normalizeNames(pick, agents) }] }\n }\n if ('steps' in pick) {\n if (pick.steps.length === 0) throw new Error(ROUTER_PICK_ERROR)\n const steps = pick.steps.map((step) => {\n assertOrder(step.order)\n const names = normalizeNames(step.names, agents)\n return step.order === undefined ? { names } : { names, order: step.order }\n })\n const flat = steps.flatMap((step) => step.names)\n if (flat.includes('main') && flat.length > 1) {\n throw new Error('Do not mix main into a subagent list.')\n }\n return { steps }\n }\n assertOrder(pick.order)\n const names = normalizeNames(pick.names, agents)\n return {\n steps: [\n pick.order === undefined ? { names } : { names, order: pick.order },\n ],\n }\n}\n\n/**\n * Tag a child chunk with its subagent. A chunk that a nested child already\n * tagged keeps its own id, and a nested child's start names this child as\n * its parent.\n */\nfunction attributeChunk(\n chunk: StreamChunk,\n subagentRunId: string,\n): StreamChunk {\n if (chunk.type === SUBAGENT_STARTED) {\n return chunk.parentSubagentRunId !== undefined\n ? chunk\n : { ...chunk, parentSubagentRunId: subagentRunId }\n }\n if (chunk.type === SUBAGENT_FINISHED || chunk.type === SUBAGENT_ERROR) {\n return chunk\n }\n if ('subagentRunId' in chunk && typeof chunk.subagentRunId === 'string') {\n return chunk\n }\n // RUN_* and MESSAGES_SNAPSHOT never get here (spawnAgentStream drops them).\n // Everything else is tagged.\n return { ...chunk, subagentRunId } as StreamChunk\n}\n\nfunction runUsage(chunk: StreamChunk | undefined): Array<SpecTokenUsage> {\n if (chunk?.type !== EventType.RUN_FINISHED) return []\n if (Array.isArray(chunk.usage)) return chunk.usage\n return isTanstackUsage(chunk.usage) ? toSpecTokenUsage(chunk.usage).usage : []\n}\n\n/** The full usage of a run: token counts plus cost and the other fields. */\nfunction fullUsage(chunk: StreamChunk | undefined): TokenUsage | undefined {\n if (chunk?.type !== EventType.RUN_FINISHED) return undefined\n return rebuildTokenUsage(chunk.usage, tanstackMetadata(chunk)?.usage)\n}\n\n/** Add a finished child run's usage to the sink. */\nexport function collectUsage(sink: SubagentSink, finished?: StreamChunk) {\n sink.usage.push(...runUsage(finished))\n const full = fullUsage(finished)\n if (full) sink.total = sink.total ? addTokenUsage(sink.total, full) : full\n}\n\n/** A parent run's last chunk: it completed, or it failed. */\ntype ParentTerminal = Extract<\n StreamChunk,\n { type: 'RUN_FINISHED' | 'RUN_ERROR' }\n>\n\n/**\n * Put the children's usage on a parent terminal. `usage[]` keeps one entry per\n * model call. `metadata.tanstack.usage` holds the summed cost and the other\n * TanStack fields, so `fromSpecTokenUsage` reads the full total. Empties the\n * sink, so the next parent terminal does not count it again.\n *\n * `RUN_ERROR` is accepted too: a turn that failed still spent whatever its\n * children spent. Such a chunk carries no usage of its own, so `runUsage` and\n * `fullUsage` return empty for it and the children's total stands alone.\n */\nexport function withChildUsage(\n chunk: ParentTerminal,\n sink: SubagentSink,\n): ParentTerminal {\n if (sink.usage.length === 0 && !sink.total) return chunk\n const own = fullUsage(chunk)\n const total =\n own && sink.total ? addTokenUsage(own, sink.total) : (own ?? sink.total)\n const usage = [...runUsage(chunk), ...sink.usage.splice(0)]\n sink.total = undefined\n const leftover = total ? toSpecTokenUsage(total).leftover : undefined\n const next = { ...chunk, usage }\n if (!leftover) return next\n // `withTanstackMetadata` runs the value through `Omit`, which collapses this\n // union and widens `type` back to `RUN_FINISHED | RUN_ERROR`. It only adds a\n // metadata key, so the runtime shape is the input's: restore that type.\n return withTanstackMetadata(next, { usage: leftover }) as ParentTerminal\n}\n\nexport async function* spawnAgentStream(\n agent: DefinedAgent,\n ctx: SubagentRunContext,\n sink?: SubagentSink,\n parentToolCallId?: string,\n): AsyncIterable<StreamChunk> {\n const id = ctx.subagentRunId\n yield {\n type: SUBAGENT_STARTED,\n subagentRunId: id,\n name: agent.name,\n description: agent.description,\n ...(ctx.parentSubagentRunId !== undefined\n ? { parentSubagentRunId: ctx.parentSubagentRunId }\n : {}),\n ...(parentToolCallId !== undefined ? { parentToolCallId } : {}),\n timestamp: Date.now(),\n } satisfies SubagentStartedEvent\n\n let iterator: AsyncIterator<StreamChunk> | undefined\n let finished: StreamChunk | undefined\n try {\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const stream = await orAbort(\n Promise.resolve(agent.run(ctx)),\n ctx.abortSignal,\n )\n iterator = stream[Symbol.asyncIterator]()\n while (true) {\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const result = await orAbort(iterator.next(), ctx.abortSignal)\n if (result.done) break\n const chunk = result.value\n // Run-scoped events describe the child run. The SUBAGENT_* events carry\n // that information for the parent stream.\n if (\n chunk.type === EventType.RUN_STARTED ||\n chunk.type === EventType.MESSAGES_SNAPSHOT\n ) {\n continue\n }\n if (chunk.type === EventType.RUN_FINISHED) {\n // The engine yields one RUN_FINISHED per model call. Add each one.\n if (sink) collectUsage(sink, chunk)\n finished = chunk\n continue\n }\n if (chunk.type === EventType.RUN_ERROR) {\n yield {\n type: SUBAGENT_ERROR,\n subagentRunId: id,\n message: chunk.message || 'Subagent failed',\n ...(chunk.code ? { code: chunk.code } : {}),\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n return\n }\n yield attributeChunk(chunk, id)\n }\n if (ctx.abortSignal?.aborted) {\n yield stoppedEvent(id)\n return\n }\n const outcome =\n finished?.type === EventType.RUN_FINISHED ? finished.outcome : undefined\n if (outcome?.type === 'cancelled') {\n yield stoppedEvent(id)\n return\n }\n if (outcome?.type === 'interrupt') {\n const interrupts = outcome.interrupts.map((interrupt) =>\n interrupt.subagentRunId\n ? interrupt\n : { ...interrupt, subagentRunId: id },\n )\n sink?.interrupts.push(...interrupts)\n yield {\n type: SUBAGENT_FINISHED,\n subagentRunId: id,\n outcome: {\n type: 'suspended',\n interruptIds: interrupts\n .filter((interrupt) => interrupt.subagentRunId === id)\n .map((interrupt) => interrupt.id),\n },\n timestamp: Date.now(),\n } satisfies SubagentFinishedEvent\n return\n }\n const result =\n finished?.type === EventType.RUN_FINISHED ? finished.result : undefined\n yield {\n type: SUBAGENT_FINISHED,\n subagentRunId: id,\n ...(result !== undefined ? { result } : {}),\n timestamp: Date.now(),\n } satisfies SubagentFinishedEvent\n } catch (error) {\n yield {\n type: SUBAGENT_ERROR,\n subagentRunId: id,\n message: isAbortError(error, ctx.abortSignal)\n ? 'Stopped'\n : error instanceof Error\n ? error.message\n : String(error),\n timestamp: Date.now(),\n } satisfies SubagentErrorEvent\n } finally {\n try {\n await iterator?.return?.()\n } catch {\n // Child stream may already be closed or aborted.\n }\n }\n}\n\nasync function* mergeAgentStreams(streams: Array<AsyncIterable<StreamChunk>>) {\n const readers = streams.map((stream) => {\n const iterator = stream[Symbol.asyncIterator]()\n return {\n iterator,\n next: iterator.next(),\n }\n })\n\n try {\n while (readers.length > 0) {\n const indexed = readers.map((reader, index) =>\n reader.next.then((result) => ({ index, result, reader })),\n )\n const winner = await Promise.race(indexed)\n if (winner.result.done) {\n readers.splice(winner.index, 1)\n continue\n }\n yield winner.result.value\n winner.reader.next = winner.reader.iterator.next()\n }\n } finally {\n // The reader stopped early. Close every child so its finally runs.\n for (const reader of readers) {\n void reader.iterator.return?.().catch(() => {})\n }\n }\n}\n\n/** True when a child in these chunks failed or stopped for outside input. */\nfunction stopsSequence(chunks: ReadonlyArray<StreamChunk>, id: string) {\n return chunks.some(\n (chunk) =>\n (chunk.type === SUBAGENT_ERROR && chunk.subagentRunId === id) ||\n (chunk.type === SUBAGENT_FINISHED &&\n chunk.subagentRunId === id &&\n chunk.outcome?.type === 'suspended'),\n )\n}\n\nexport async function* spawnNamedAgents(\n entries: ReadonlyArray<SpawnEntry>,\n bag: SubagentsBag,\n ctx: SpawnContext,\n sink?: SubagentSink,\n) {\n if (bag.sandbox === 'inherit' && entries.length > 1) {\n throw new Error(\n \"subagents.sandbox 'inherit' cannot start two children in one turn\",\n )\n }\n // One signal for the group. The finally stops every child that still runs\n // when the reader stops early.\n const group = linkAbort(ctx.abortSignal)\n const groupCtx = { ...ctx, abortSignal: group.controller.signal }\n try {\n if (bag.order === 'sequence') {\n let messages = ctx.messages\n for (const entry of entries) {\n const chunks: Array<StreamChunk> = []\n let id: string | undefined\n for await (const chunk of openAgentStream(\n entry,\n bag,\n { ...groupCtx, messages },\n sink,\n )) {\n if (chunk.type === SUBAGENT_STARTED && id === undefined) {\n id = chunk.subagentRunId\n }\n chunks.push(chunk)\n yield chunk\n }\n if (id !== undefined && stopsSequence(chunks, id)) return\n const text = [\n entry.resume?.text,\n collectNamedText(chunks, [entry.name]),\n ]\n .filter((part) => part !== undefined && part !== '')\n .join('')\n if (text) {\n messages = [...messages, { role: 'assistant', content: text }]\n }\n }\n return\n }\n const streams = entries.map((entry) =>\n openAgentStream(entry, bag, groupCtx, sink),\n )\n const onlyStream = streams.length === 1 ? streams[0] : undefined\n if (onlyStream) {\n yield* onlyStream\n return\n }\n yield* mergeAgentStreams(streams)\n } finally {\n group.controller.abort()\n group.dispose()\n }\n}\n\n/**\n * Text of the named direct children, in `names` order. Text from nested\n * children stays out: their chunks carry their own id.\n */\nexport function collectNamedText(\n chunks: Array<StreamChunk>,\n names: ReadonlyArray<string>,\n) {\n const nameByRunId = new Map<string, string>()\n const textByName = new Map<string, string>()\n for (const chunk of chunks) {\n if (chunk.type === SUBAGENT_STARTED) {\n if (chunk.parentSubagentRunId === undefined) {\n nameByRunId.set(chunk.subagentRunId, chunk.name)\n }\n continue\n }\n if (chunk.type !== EventType.TEXT_MESSAGE_CONTENT) continue\n if (!('subagentRunId' in chunk) || typeof chunk.subagentRunId !== 'string')\n continue\n const name = nameByRunId.get(chunk.subagentRunId)\n if (!name) continue\n textByName.set(name, `${textByName.get(name) ?? ''}${chunk.delta}`)\n }\n return names\n .map((name) => textByName.get(name)?.trim() ?? '')\n .filter((text) => text.length > 0)\n .join('\\n\\n')\n}\n\n/**\n * The parent conversation up to the message that carries this tool call, with\n * that message's tool calls removed. Its string text stays; array content is\n * dropped.\n */\nfunction messagesBeforeCall(\n messages: ReadonlyArray<ModelMessage>,\n toolCallId: string,\n): Array<ModelMessage> {\n const index = messages.findIndex((message) =>\n message.toolCalls?.some((call) => call.id === toolCallId),\n )\n if (index === -1) return [...messages]\n const host = messages[index]\n const kept = messages.slice(0, index)\n if (host && typeof host.content === 'string' && host.content !== '') {\n const { toolCalls: _calls, ...text } = host\n void _calls\n kept.push(text)\n }\n return kept\n}\n\n/**\n * Record the parent messages when the model calls a subagent tool, so the\n * child reads the conversation as it is at that call.\n */\nexport function subagentCallMessages(names: ReadonlySet<string>) {\n const byCall = new Map<string, Array<ModelMessage>>()\n const middleware: ChatMiddleware = {\n name: 'subagent-call-messages',\n onBeforeToolCall(ctx, hook) {\n if (!names.has(hook.toolName)) return undefined\n byCall.set(\n hook.toolCallId,\n messagesBeforeCall(ctx.messages, hook.toolCallId),\n )\n return undefined\n },\n }\n return {\n middleware,\n messagesFor: (toolCallId: string | undefined) =>\n toolCallId === undefined ? undefined : byCall.get(toolCallId),\n }\n}\n\nexport function createSyntheticSubagentTools(\n bag: SubagentsBag,\n parent: {\n /** Messages the parent run started with. Used when no call was recorded. */\n messages: SubagentRunContext['messages']\n /** The parent messages at a tool call. See subagentCallMessages. */\n messagesFor?: (\n toolCallId: string | undefined,\n ) => SubagentRunContext['messages'] | undefined\n threadId: string\n runId: string\n interruptedRunId?: string\n abortSignal?: AbortSignal\n turn?: SubagentTurn\n sink: SubagentSink\n },\n): Array<Tool> {\n return bag.agents.map((agent) => ({\n name: agent.name,\n description: agent.description,\n ...(agent.inputSchema !== undefined && { inputSchema: agent.inputSchema }),\n [SUBAGENT_TOOL]: true,\n // The tool loop checks `input` against `inputSchema` before this runs.\n execute: async (input: unknown, context?: unknown) => {\n const toolContext = context as\n | {\n toolCallId?: string\n [EMIT_STREAM_CHUNK]?: (chunk: StreamChunk) => void\n }\n | undefined\n const toolCallId = toolContext?.toolCallId\n const suspended = parent.turn?.children.find(\n (child) =>\n child.status === 'suspended' &&\n child.parentToolCallId !== undefined &&\n child.parentToolCallId === toolCallId,\n )\n // An agent without `inputSchema` still gets `{}` from the model. Its\n // `ctx.input` stays undefined.\n const entry: SpawnEntry = {\n name: agent.name,\n ...(agent.inputSchema !== undefined && { input }),\n ...(suspended && {\n resume: {\n subagentRunId: suspended.subagentRunId,\n messages: suspended.messages,\n entries: suspended.resume,\n text: suspended.text,\n },\n }),\n }\n const sink = createSubagentSink()\n const link = linkAbort(parent.abortSignal)\n let subagentRunId = suspended?.subagentRunId ?? ''\n let text = suspended?.text ?? ''\n let error: string | undefined\n try {\n for await (const chunk of openAgentStream(\n entry,\n bag,\n {\n messages: parent.messagesFor?.(toolCallId) ?? parent.messages,\n abortSignal: link.controller.signal,\n threadId: parent.threadId,\n parentRunId: parent.runId,\n ...(parent.interruptedRunId !== undefined\n ? { interruptedRunId: parent.interruptedRunId }\n : {}),\n },\n sink,\n toolCallId,\n )) {\n if (chunk.type === SUBAGENT_STARTED && subagentRunId === '') {\n subagentRunId = chunk.subagentRunId\n }\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT &&\n 'subagentRunId' in chunk &&\n chunk.subagentRunId === subagentRunId\n ) {\n text += chunk.delta\n }\n if (\n chunk.type === SUBAGENT_ERROR &&\n chunk.subagentRunId === subagentRunId\n ) {\n error = chunk.message\n }\n toolContext?.[EMIT_STREAM_CHUNK]?.(chunk)\n }\n } finally {\n link.dispose()\n }\n parent.sink.usage.push(...sink.usage)\n if (sink.total) {\n parent.sink.total = parent.sink.total\n ? addTokenUsage(parent.sink.total, sink.total)\n : sink.total\n }\n return {\n subagentRunId,\n text,\n ...(error !== undefined ? { error } : {}),\n ...(sink.interrupts.length > 0 ? { interrupts: sink.interrupts } : {}),\n } satisfies SubagentToolOutcome\n },\n }))\n}\n"],"mappings":"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"}