@tanstack/ai 0.58.0 → 0.61.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 (144) hide show
  1. package/dist/esm/activities/chat/adapter.d.ts +9 -0
  2. package/dist/esm/activities/chat/adapter.js +1 -0
  3. package/dist/esm/activities/chat/adapter.js.map +1 -1
  4. package/dist/esm/activities/chat/agents/define-agent.d.ts +81 -0
  5. package/dist/esm/activities/chat/agents/define-agent.js +34 -0
  6. package/dist/esm/activities/chat/agents/define-agent.js.map +1 -0
  7. package/dist/esm/activities/chat/agents/route.d.ts +53 -0
  8. package/dist/esm/activities/chat/agents/route.js +59 -0
  9. package/dist/esm/activities/chat/agents/route.js.map +1 -0
  10. package/dist/esm/activities/chat/agents/spawn.d.ts +124 -0
  11. package/dist/esm/activities/chat/agents/spawn.js +490 -0
  12. package/dist/esm/activities/chat/agents/spawn.js.map +1 -0
  13. package/dist/esm/activities/chat/agents/turn.d.ts +36 -0
  14. package/dist/esm/activities/chat/agents/turn.js +78 -0
  15. package/dist/esm/activities/chat/agents/turn.js.map +1 -0
  16. package/dist/esm/activities/chat/index.d.ts +13 -3
  17. package/dist/esm/activities/chat/index.js +462 -26
  18. package/dist/esm/activities/chat/index.js.map +1 -1
  19. package/dist/esm/activities/chat/messages.d.ts +7 -1
  20. package/dist/esm/activities/chat/messages.js +99 -19
  21. package/dist/esm/activities/chat/messages.js.map +1 -1
  22. package/dist/esm/activities/chat/middleware/run-store.d.ts +43 -7
  23. package/dist/esm/activities/chat/middleware/run-store.js +8 -1
  24. package/dist/esm/activities/chat/middleware/run-store.js.map +1 -1
  25. package/dist/esm/activities/chat/middleware/types.d.ts +47 -1
  26. package/dist/esm/activities/chat/middleware/types.js.map +1 -1
  27. package/dist/esm/activities/chat/stream/message-updaters.js +9 -2
  28. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
  29. package/dist/esm/activities/chat/stream/processor.d.ts +46 -1
  30. package/dist/esm/activities/chat/stream/processor.js +294 -18
  31. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  32. package/dist/esm/activities/chat/tools/tool-calls.d.ts +17 -3
  33. package/dist/esm/activities/chat/tools/tool-calls.js +56 -5
  34. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  35. package/dist/esm/activities/embed/adapter.d.ts +7 -0
  36. package/dist/esm/activities/embed/adapter.js +1 -0
  37. package/dist/esm/activities/embed/adapter.js.map +1 -1
  38. package/dist/esm/activities/embed/index.js +2 -0
  39. package/dist/esm/activities/embed/index.js.map +1 -1
  40. package/dist/esm/activities/files/adapter.d.ts +97 -0
  41. package/dist/esm/activities/files/adapter.js +45 -0
  42. package/dist/esm/activities/files/adapter.js.map +1 -0
  43. package/dist/esm/activities/files/index.d.ts +66 -0
  44. package/dist/esm/activities/files/index.js +78 -0
  45. package/dist/esm/activities/files/index.js.map +1 -0
  46. package/dist/esm/activities/generateAudio/index.js +1 -1
  47. package/dist/esm/activities/generateImage/adapter.d.ts +8 -0
  48. package/dist/esm/activities/generateImage/adapter.js +1 -0
  49. package/dist/esm/activities/generateImage/adapter.js.map +1 -1
  50. package/dist/esm/activities/generateImage/index.js +3 -1
  51. package/dist/esm/activities/generateImage/index.js.map +1 -1
  52. package/dist/esm/activities/generateLiveVideo/index.js +1 -1
  53. package/dist/esm/activities/generateSpeech/index.js +1 -1
  54. package/dist/esm/activities/generateTranscription/index.js +1 -1
  55. package/dist/esm/activities/generateVideo/adapter.d.ts +8 -0
  56. package/dist/esm/activities/generateVideo/adapter.js +1 -0
  57. package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
  58. package/dist/esm/activities/generateVideo/index.js +3 -0
  59. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  60. package/dist/esm/activities/generateVoice/index.js +1 -1
  61. package/dist/esm/activities/generateWorld/adapter.d.ts +4 -2
  62. package/dist/esm/activities/generateWorld/adapter.js.map +1 -1
  63. package/dist/esm/activities/generateWorld/index.d.ts +4 -3
  64. package/dist/esm/activities/generateWorld/index.js +6 -5
  65. package/dist/esm/activities/generateWorld/index.js.map +1 -1
  66. package/dist/esm/activities/index.d.ts +9 -3
  67. package/dist/esm/activities/index.js +17 -13
  68. package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +2 -0
  69. package/dist/esm/activities/summarize/chat-stream-summarize.js +8 -8
  70. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
  71. package/dist/esm/activities/summarize/index.js +1 -1
  72. package/dist/esm/client.d.ts +7 -36
  73. package/dist/esm/client.js +5 -37
  74. package/dist/esm/client.js.map +1 -1
  75. package/dist/esm/index.d.ts +8 -2
  76. package/dist/esm/index.js +9 -4
  77. package/dist/esm/middlewares/content-guard.js.map +1 -1
  78. package/dist/esm/types.d.ts +179 -98
  79. package/dist/esm/utilities/adapter-yield-chunk.d.ts +5 -1
  80. package/dist/esm/utilities/ag-ui-usage.d.ts +9 -9
  81. package/dist/esm/utilities/ag-ui-usage.js +66 -3
  82. package/dist/esm/utilities/ag-ui-usage.js.map +1 -1
  83. package/dist/esm/utilities/ag-ui-wire.js +90 -13
  84. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  85. package/dist/esm/utilities/content-source.d.ts +60 -0
  86. package/dist/esm/utilities/content-source.js +85 -0
  87. package/dist/esm/utilities/content-source.js.map +1 -0
  88. package/dist/esm/utilities/normalize-stream-chunk.js +7 -2
  89. package/dist/esm/utilities/normalize-stream-chunk.js.map +1 -1
  90. package/dist/esm/utilities/provider-executed.d.ts +7 -0
  91. package/dist/esm/utilities/provider-executed.js +10 -1
  92. package/dist/esm/utilities/provider-executed.js.map +1 -1
  93. package/dist/esm/utilities/spec-event-keys.js +13 -8
  94. package/dist/esm/utilities/spec-event-keys.js.map +1 -1
  95. package/dist/esm/utilities/subagent-wire.d.ts +36 -0
  96. package/dist/esm/utilities/subagent-wire.js +131 -0
  97. package/dist/esm/utilities/subagent-wire.js.map +1 -0
  98. package/dist/esm/utilities/tool-result.d.ts +12 -2
  99. package/dist/esm/utilities/tool-result.js +23 -3
  100. package/dist/esm/utilities/tool-result.js.map +1 -1
  101. package/package.json +3 -3
  102. package/skills/ai-core/adapter-configuration/SKILL.md +62 -0
  103. package/skills/ai-core/adapter-configuration/references/grok-adapter.md +1 -1
  104. package/skills/ai-core/chat-experience/SKILL.md +14 -0
  105. package/skills/ai-core/media-generation/SKILL.md +10 -2
  106. package/skills/ai-core/middleware/SKILL.md +7 -4
  107. package/src/activities/chat/adapter.ts +10 -0
  108. package/src/activities/chat/agents/define-agent.ts +121 -0
  109. package/src/activities/chat/agents/route.ts +115 -0
  110. package/src/activities/chat/agents/spawn.ts +806 -0
  111. package/src/activities/chat/agents/turn.ts +151 -0
  112. package/src/activities/chat/index.ts +734 -30
  113. package/src/activities/chat/messages.ts +137 -16
  114. package/src/activities/chat/middleware/run-store.ts +56 -7
  115. package/src/activities/chat/middleware/types.ts +47 -0
  116. package/src/activities/chat/stream/message-updaters.ts +24 -2
  117. package/src/activities/chat/stream/processor.ts +452 -30
  118. package/src/activities/chat/tools/tool-calls.ts +83 -11
  119. package/src/activities/embed/adapter.ts +7 -0
  120. package/src/activities/embed/index.ts +5 -0
  121. package/src/activities/files/adapter.ts +120 -0
  122. package/src/activities/files/index.ts +113 -0
  123. package/src/activities/generateImage/adapter.ts +8 -0
  124. package/src/activities/generateImage/index.ts +4 -0
  125. package/src/activities/generateVideo/adapter.ts +8 -0
  126. package/src/activities/generateVideo/index.ts +7 -0
  127. package/src/activities/generateWorld/adapter.ts +4 -2
  128. package/src/activities/generateWorld/index.ts +7 -6
  129. package/src/activities/index.ts +40 -1
  130. package/src/activities/summarize/chat-stream-summarize.ts +22 -12
  131. package/src/client.ts +29 -35
  132. package/src/index.ts +39 -0
  133. package/src/middlewares/content-guard.ts +7 -5
  134. package/src/types.ts +226 -103
  135. package/src/utilities/adapter-yield-chunk.ts +10 -2
  136. package/src/utilities/ag-ui-usage.test.ts +38 -0
  137. package/src/utilities/ag-ui-usage.ts +98 -11
  138. package/src/utilities/ag-ui-wire.ts +134 -16
  139. package/src/utilities/content-source.ts +138 -0
  140. package/src/utilities/normalize-stream-chunk.ts +10 -2
  141. package/src/utilities/provider-executed.ts +13 -0
  142. package/src/utilities/spec-event-keys.ts +34 -7
  143. package/src/utilities/subagent-wire.ts +184 -0
  144. package/src/utilities/tool-result.ts +38 -2
@@ -1,5 +1,7 @@
1
1
  import { tanstackMetadata } from "./merge-metadata.js";
2
+ import { isProviderExecutedToolCall } from "./provider-executed.js";
2
3
  import { normalizeToolResult } from "./tool-result.js";
4
+ import { wireSubagentInfo, wireSubagentRunId } from "./subagent-wire.js";
3
5
  import { coerceCreatedAt, modelMessageToUIMessage } from "../activities/chat/messages.js";
4
6
  //#region src/utilities/ag-ui-wire.ts
5
7
  function isRecord(value) {
@@ -65,21 +67,41 @@ function uiMessagesToWire(messages, options) {
65
67
  wire.push(toAnchor(uiMessage, "user", { content: parts.length > 0 ? collectUserContent(parts) : msg.content ?? "" }, parts, includeSnapshotStructuredOutput));
66
68
  continue;
67
69
  }
70
+ let current = {
71
+ thinking: [],
72
+ parts: []
73
+ };
74
+ const segments = [current];
68
75
  for (const part of parts) if (part.type === "thinking") {
69
- const reasoning = {
70
- role: "reasoning",
71
- id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),
72
- content: part.content
76
+ if (current.parts.some((p) => p.type === "tool-call" && isProviderExecutedToolCall(p))) {
77
+ current = {
78
+ thinking: [part],
79
+ parts: []
80
+ };
81
+ segments.push(current);
82
+ } else current.thinking.push(part);
83
+ } else current.parts.push(part);
84
+ segments.forEach((segment, index) => {
85
+ for (const part of segment.thinking) {
86
+ const reasoning = {
87
+ role: "reasoning",
88
+ id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),
89
+ content: part.content
90
+ };
91
+ if (part.signature) reasoning.encryptedValue = part.signature;
92
+ wire.push(reasoning);
93
+ }
94
+ const text = collectText(segment.parts);
95
+ const toolCalls = collectToolCalls(segment.parts);
96
+ const anchorMessage = index === 0 ? uiMessage : {
97
+ ...uiMessage,
98
+ id: uniqueWireId(`${uiMessage.id}-segment-${index}`, usedWireIds)
73
99
  };
74
- if (part.signature) reasoning.encryptedValue = part.signature;
75
- wire.push(reasoning);
76
- }
77
- const text = collectText(parts);
78
- const toolCalls = collectToolCalls(parts);
79
- wire.push(toAnchor(uiMessage, "assistant", {
80
- ...text !== "" && { content: text },
81
- ...toolCalls && { toolCalls }
82
- }, parts, includeSnapshotStructuredOutput));
100
+ wire.push(toAnchor(anchorMessage, "assistant", {
101
+ ...text !== "" && { content: text },
102
+ ...toolCalls && { toolCalls }
103
+ }, segment.parts, includeSnapshotStructuredOutput));
104
+ });
83
105
  const explicitToolResults = new Set(parts.flatMap((part) => part.type === "tool-result" ? [part.toolCallId] : []));
84
106
  for (const part of parts) if (part.type === "tool-result") {
85
107
  const id = uniqueToolWireId(part.id ?? deriveToolMessageId(part.toolCallId), usedWireIds);
@@ -110,6 +132,7 @@ function uiMessagesToWire(messages, options) {
110
132
  metadata: rebuiltToolMetadata(void 0, void 0, void 0, result)
111
133
  });
112
134
  }
135
+ for (const part of parts) if (part.type === "subagent") wire.push(...subagentToWire(part, options));
113
136
  }
114
137
  return wire;
115
138
  }
@@ -142,6 +165,7 @@ function messageMetadata(msg, parts, includeSnapshotStructuredOutput) {
142
165
  const previousTanstack = tanstackMetadata(msg);
143
166
  const tanstack = {};
144
167
  if (previousTanstack?.model !== void 0) tanstack.model = previousTanstack.model;
168
+ if (previousTanstack?.runId !== void 0) tanstack.runId = previousTanstack.runId;
145
169
  if (previousTanstack?.signature !== void 0) tanstack.signature = previousTanstack.signature;
146
170
  const createdAt = coerceCreatedAt(msg.createdAt);
147
171
  if (createdAt !== void 0) tanstack.createdAt = createdAt.toISOString();
@@ -175,6 +199,59 @@ function collectText(parts) {
175
199
  else if (p.type === "structured-output" && p.status === "complete" && p.raw !== "") out.push(p.raw);
176
200
  return out.join("");
177
201
  }
202
+ /**
203
+ * A child's messages, tagged with its AG-UI `subagentRunId`. The card data
204
+ * rides in `metadata.tanstack.subagent`, so the other side can rebuild the
205
+ * card and continue a suspended child.
206
+ */
207
+ function subagentToWire(part, options) {
208
+ const { subagent } = part;
209
+ const info = {
210
+ name: subagent.name,
211
+ status: subagent.status,
212
+ ...subagent.description !== void 0 && { description: subagent.description },
213
+ ...subagent.error !== void 0 && { error: subagent.error },
214
+ ...subagent.interruptIds !== void 0 && { interruptIds: subagent.interruptIds },
215
+ ...subagent.parentSubagentRunId !== void 0 && { parentSubagentRunId: subagent.parentSubagentRunId },
216
+ ...subagent.parentToolCallId !== void 0 && { parentToolCallId: subagent.parentToolCallId },
217
+ ...subagent.metadata !== void 0 && { metadata: subagent.metadata }
218
+ };
219
+ const child = uiMessagesToWire(subagent.messages, options);
220
+ const own = child.some((message) => wireSubagentRunId(message) === void 0);
221
+ return (own ? child : [{
222
+ id: `subagent:${subagent.id}`,
223
+ role: "assistant"
224
+ }, ...child]).map((message, index) => {
225
+ const nestedId = wireSubagentRunId(message);
226
+ if (nestedId !== void 0) {
227
+ const nested = wireSubagentInfo(message);
228
+ if (!nested || nested.parentSubagentRunId !== void 0) return message;
229
+ return withSubagentInfo(message, nestedId, {
230
+ ...nested,
231
+ parentSubagentRunId: subagent.id
232
+ });
233
+ }
234
+ return withSubagentInfo(message, subagent.id, !own && index === 0 ? {
235
+ ...info,
236
+ placeholder: true
237
+ } : info);
238
+ });
239
+ }
240
+ function withSubagentInfo(message, subagentRunId, info) {
241
+ const metadata = isRecord(message.metadata) ? message.metadata : {};
242
+ const tanstack = isRecord(metadata.tanstack) ? metadata.tanstack : {};
243
+ return {
244
+ ...message,
245
+ subagentRunId,
246
+ metadata: {
247
+ ...metadata,
248
+ tanstack: {
249
+ ...tanstack,
250
+ subagent: info
251
+ }
252
+ }
253
+ };
254
+ }
178
255
  function collectUserContent(parts) {
179
256
  if (!parts.some((p) => p.type === "image" || p.type === "audio" || p.type === "video" || p.type === "document")) return collectText(parts);
180
257
  const out = [];
@@ -1 +1 @@
1
- {"version":3,"file":"ag-ui-wire.js","names":[],"sources":["../../../src/utilities/ag-ui-wire.ts"],"sourcesContent":["import type {\n AssistantMessage,\n InputContent,\n ReasoningMessage,\n SystemMessage,\n ToolCall,\n ToolMessage,\n UserMessage,\n} from '@ag-ui/core'\nimport type {\n ContentPart,\n MessagePart,\n ModelMessage,\n StructuredOutputPart,\n TanStackMessageMetadata,\n UIMessage,\n UIResourcePart,\n} from '../types'\nimport type { MetadataRecord } from './merge-metadata'\nimport { tanstackMetadata } from './merge-metadata'\nimport { normalizeToolResult } from './tool-result'\nimport {\n coerceCreatedAt,\n modelMessageToUIMessage,\n} from '../activities/chat/messages'\n\ntype WithMetadata<T> = T & { metadata?: MetadataRecord }\ntype WireSystemMessage = WithMetadata<SystemMessage>\ntype WireUserMessage = WithMetadata<UserMessage>\ntype WireAssistantMessage = WithMetadata<AssistantMessage>\ntype WireToolMessage = WithMetadata<\n ToolMessage & {\n name?: string\n }\n>\ntype WireReasoningMessage = WithMetadata<ReasoningMessage>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction rebuiltToolMetadata(\n metadata: unknown,\n createdAt: unknown,\n id: string | undefined,\n content: string | null | Array<ContentPart>,\n anchorOwnsUiResources = false,\n): MetadataRecord | undefined {\n const source: MetadataRecord = isRecord(metadata) ? metadata : {}\n const tanstack = isRecord(source.tanstack) ? { ...source.tanstack } : {}\n if (anchorOwnsUiResources) delete tanstack.uiResources\n const date = coerceCreatedAt(createdAt)\n const toolResult: NonNullable<TanStackMessageMetadata['toolResult']> = {\n ...(id !== undefined ? { id } : {}),\n ...(date && { createdAt: date.toISOString() }),\n ...(Array.isArray(content) && { content }),\n }\n const result = {\n ...source,\n tanstack: { ...tanstack, toolResult },\n }\n return Object.keys(result).length ? result : undefined\n}\n\nexport type WireMessage =\n | WireSystemMessage\n | WireUserMessage\n | WireAssistantMessage\n | WireToolMessage\n | WireReasoningMessage\n\n/**\n * Serialize TanStack `UIMessage`s and `ModelMessage`s into the AG-UI\n * `RunAgentInput.messages` wire shape. Anchors are spec-only (`id`, `role`,\n * `name`, `content`, `toolCalls`, `metadata`). Tool results and thinking parts\n * on assistant messages are additionally emitted as fan-out\n * `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI\n * server consumers. Set `includeSnapshotStructuredOutput` to retain complete\n * structured-output metadata for UI snapshots.\n */\nexport function uiMessagesToWire(\n messages: Array<UIMessage | ModelMessage>,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const wire: Array<WireMessage> = []\n const usedWireIds = new Set<string>(\n messages.flatMap((message) =>\n 'id' in message && message.id && message.role !== 'tool'\n ? [message.id]\n : [],\n ),\n )\n const includeSnapshotStructuredOutput =\n options?.includeSnapshotStructuredOutput ?? false\n\n const assistantIds = new Set<string>()\n for (const msg of messages) {\n if (msg.role === 'assistant' && msg.id !== undefined) {\n assistantIds.add(msg.id)\n }\n }\n\n for (const msg of messages) {\n if (!('parts' in msg) && msg.role === 'tool' && msg.toolCallId) {\n const id = uniqueToolWireId(\n toolWireId(msg.id, msg.toolCallId, assistantIds),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n msg.metadata,\n msg.createdAt,\n msg.id,\n msg.content,\n )\n wire.push({\n role: 'tool',\n id,\n ...(msg.name !== undefined && { name: msg.name }),\n toolCallId: msg.toolCallId,\n content:\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content),\n ...(msg.error !== undefined && { error: msg.error }),\n ...(metadata !== undefined && { metadata }),\n })\n continue\n }\n\n const uiMessage: UIMessage =\n 'parts' in msg ? msg : modelMessageToUIMessage(msg, msg.id)\n const parts: ReadonlyArray<MessagePart> = uiMessage.parts\n usedWireIds.add(uiMessage.id)\n\n if (msg.role === 'system') {\n wire.push(\n toAnchor(\n uiMessage,\n 'system',\n {\n content:\n parts.length > 0\n ? collectText(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n if (msg.role === 'user') {\n wire.push(\n toAnchor(\n uiMessage,\n 'user',\n {\n content:\n parts.length > 0\n ? collectUserContent(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n // assistant: emit reasoning fan-outs first, then anchor, then tool fan-outs\n for (const part of parts) {\n if (part.type === 'thinking') {\n const reasoning: WireReasoningMessage = {\n role: 'reasoning',\n id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),\n content: part.content,\n }\n if (part.signature) {\n reasoning.encryptedValue = part.signature\n }\n wire.push(reasoning)\n }\n }\n\n const text = collectText(parts)\n const toolCalls = collectToolCalls(parts)\n wire.push(\n toAnchor(\n uiMessage,\n 'assistant',\n {\n ...(text !== '' && { content: text }),\n ...(toolCalls && { toolCalls }),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n\n const explicitToolResults = new Set(\n parts.flatMap((part) =>\n part.type === 'tool-result' ? [part.toolCallId] : [],\n ),\n )\n for (const part of parts) {\n if (part.type === 'tool-result') {\n const id = uniqueToolWireId(\n part.id ?? deriveToolMessageId(part.toolCallId),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n part.metadata,\n part.createdAt,\n part.id,\n part.content,\n true,\n )\n wire.push({\n role: 'tool',\n id,\n toolCallId: part.toolCallId,\n ...(part.name !== undefined && { name: part.name }),\n content:\n typeof part.content === 'string'\n ? part.content\n : JSON.stringify(part.content),\n ...(part.error !== undefined && { error: part.error }),\n ...(metadata !== undefined && { metadata }),\n })\n } else if (part.type === 'tool-call') {\n const approved = part.approval?.approved\n if (\n explicitToolResults.has(part.id) ||\n (part.output === undefined &&\n (part.state !== 'approval-responded' || approved === undefined))\n ) {\n continue\n }\n const result =\n part.output !== undefined\n ? normalizeToolResult(part.output)\n : JSON.stringify({\n approved,\n ...(approved && { pendingExecution: true }),\n message: approved\n ? 'User approved this action'\n : 'User denied this action',\n })\n const content =\n typeof result === 'string' ? result : JSON.stringify(result)\n wire.push({\n role: 'tool',\n id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),\n toolCallId: part.id,\n content,\n metadata: rebuiltToolMetadata(\n undefined,\n undefined,\n undefined,\n result,\n ),\n })\n }\n }\n }\n\n return wire\n}\n\nfunction toAnchor(\n msg: UIMessage,\n role: 'system',\n extras: { content: string },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'user',\n extras: { content: string | Array<InputContent> },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireUserMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'assistant',\n extras: {\n content?: string\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireAssistantMessage\nfunction toAnchor(\n msg: UIMessage,\n role: UIMessage['role'],\n extras: {\n content?: string | Array<InputContent>\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage | WireUserMessage | WireAssistantMessage {\n const metadata = messageMetadata(msg, parts, includeSnapshotStructuredOutput)\n const base = {\n id: msg.id,\n ...(msg.name !== undefined && { name: msg.name }),\n ...(metadata !== undefined && { metadata }),\n }\n if (role === 'system') {\n return { ...base, role, content: String(extras.content ?? '') }\n }\n if (role === 'user') {\n return { ...base, role, content: extras.content ?? '' }\n }\n return {\n ...base,\n role,\n ...(typeof extras.content === 'string' && { content: extras.content }),\n ...(extras.toolCalls !== undefined && { toolCalls: extras.toolCalls }),\n }\n}\n\nfunction messageMetadata(\n msg: UIMessage,\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): MetadataRecord | undefined {\n const base: MetadataRecord = { ...(msg.metadata ?? {}) }\n const previousTanstack = tanstackMetadata(msg)\n const tanstack: TanStackMessageMetadata = {}\n if (previousTanstack?.model !== undefined)\n tanstack.model = previousTanstack.model\n if (previousTanstack?.signature !== undefined)\n tanstack.signature = previousTanstack.signature\n const createdAt = coerceCreatedAt(msg.createdAt)\n if (createdAt !== undefined) tanstack.createdAt = createdAt.toISOString()\n\n const structuredOutput = serializedStructuredOutput(\n parts,\n includeSnapshotStructuredOutput,\n )\n if (structuredOutput) tanstack.structuredOutput = structuredOutput\n\n const toolCallMetadata: Record<string, unknown> = {}\n for (const part of parts) {\n if (part.type === 'tool-call' && part.metadata !== undefined) {\n toolCallMetadata[part.id] = part.metadata\n }\n }\n if (Object.keys(toolCallMetadata).length > 0) {\n tanstack.toolCallMetadata = toolCallMetadata\n }\n\n const uiResources = parts.filter(\n (p): p is UIResourcePart => p.type === 'ui-resource',\n )\n if (uiResources.length > 0) tanstack.uiResources = uiResources\n\n if (Object.keys(tanstack).length > 0) base.tanstack = tanstack\n else delete base.tanstack\n return Object.keys(base).length > 0 ? base : undefined\n}\n\nfunction serializedStructuredOutput(\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): TanStackMessageMetadata['structuredOutput'] | undefined {\n for (const p of parts) {\n if (\n p.type === 'structured-output' &&\n (includeSnapshotStructuredOutput || p.status !== 'complete')\n ) {\n return structuredOutputMetadata(p, includeSnapshotStructuredOutput)\n }\n }\n return undefined\n}\n\nfunction structuredOutputMetadata(\n part: StructuredOutputPart,\n includeSnapshotStructuredOutput: boolean,\n): NonNullable<TanStackMessageMetadata['structuredOutput']> {\n return {\n status: part.status,\n raw: part.raw,\n ...(includeSnapshotStructuredOutput && part.partial !== undefined\n ? { partial: part.partial }\n : {}),\n ...(includeSnapshotStructuredOutput && part.data !== undefined\n ? { data: part.data }\n : {}),\n ...(includeSnapshotStructuredOutput && part.reasoning\n ? { reasoning: part.reasoning }\n : {}),\n ...(part.errorMessage !== undefined && { errorMessage: part.errorMessage }),\n }\n}\n\nfunction collectText(parts: ReadonlyArray<MessagePart>): string {\n // The streamed JSON of a completed structured-output part is the source of\n // truth for multi-turn coherence — emitting it back as assistant content\n // lets the LLM see its own prior structured response. Streaming/errored\n // parts are skipped: they'd ship malformed JSON fragments and confuse the\n // model. `completeStructuredOutputPart` tries hard to populate `raw`\n // (caller → existing buffer → `JSON.stringify(data)`), but the stringify\n // fallback can leave it empty when `data` is unserializable (BigInt,\n // circular). The `p.raw !== ''` guard below is what enforces \"no malformed\n // round-trip\" in that case — without it we'd ship `''` and the model would\n // see an empty assistant turn.\n const out: Array<string> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push(p.content)\n } else if (\n p.type === 'structured-output' &&\n p.status === 'complete' &&\n p.raw !== ''\n ) {\n out.push(p.raw)\n }\n }\n return out.join('')\n}\n\nfunction collectUserContent(\n parts: ReadonlyArray<MessagePart>,\n): string | Array<InputContent> {\n const hasMultimodal = parts.some(\n (p) =>\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document',\n )\n if (!hasMultimodal) {\n return collectText(parts)\n }\n const out: Array<InputContent> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push({ type: 'text', text: p.content })\n } else if (\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document'\n ) {\n out.push(p)\n }\n }\n return out\n}\n\nfunction thoughtSignatureFromMetadata(metadata: unknown): string | undefined {\n if (\n metadata == null ||\n typeof metadata !== 'object' ||\n Array.isArray(metadata)\n ) {\n return undefined\n }\n if (!('thoughtSignature' in metadata)) return undefined\n const value = metadata.thoughtSignature\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction collectToolCalls(\n parts: ReadonlyArray<MessagePart>,\n): Array<ToolCall> | undefined {\n const calls: Array<ToolCall> = []\n for (const p of parts) {\n if (p.type === 'tool-call') {\n const encryptedValue = thoughtSignatureFromMetadata(p.metadata)\n calls.push({\n id: p.id,\n type: 'function',\n function: { name: p.name, arguments: p.arguments },\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n })\n }\n }\n return calls.length > 0 ? calls : undefined\n}\n\nfunction deriveReasoningId(messageId: string, part: MessagePart): string {\n return `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`\n}\n\nfunction deriveToolMessageId(toolCallId: string): string {\n return `tool-${toolCallId}`\n}\n\nfunction uniqueToolWireId(id: string, used: Set<string>): string {\n return uniqueWireId(id, used)\n}\n\nfunction uniqueWireId(id: string, used: Set<string>): string {\n if (!used.has(id)) {\n used.add(id)\n return id\n }\n let suffix = 2\n while (used.has(`${id}-${suffix}`)) suffix++\n const unique = `${id}-${suffix}`\n used.add(unique)\n return unique\n}\n\nfunction toolWireId(\n id: string | undefined,\n toolCallId: string,\n assistantIds: ReadonlySet<string>,\n): string {\n const derived = deriveToolMessageId(toolCallId)\n if (id === undefined || assistantIds.has(id)) return derived\n return id\n}\n\nfunction hashContent(s: string): string {\n // Cheap deterministic id suffix; collisions are tolerable since\n // reasoning ids only matter for AG-UI server consumers, not for our\n // own server's dedup logic (which keys on toolCallId, not reasoning id).\n let h = 0\n for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0\n return Math.abs(h).toString(36)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ag-ui-wire.js","names":[],"sources":["../../../src/utilities/ag-ui-wire.ts"],"sourcesContent":["import type {\n AssistantMessage,\n InputContent,\n ReasoningMessage,\n SystemMessage,\n ToolCall,\n ToolMessage,\n UserMessage,\n} from '@ag-ui/core'\nimport type {\n ContentPart,\n MessagePart,\n ModelMessage,\n StructuredOutputPart,\n SubagentPart,\n TanStackMessageMetadata,\n UIMessage,\n UIResourcePart,\n} from '../types'\nimport type { MetadataRecord } from './merge-metadata'\nimport { tanstackMetadata } from './merge-metadata'\nimport { isProviderExecutedToolCall } from './provider-executed'\nimport { normalizeToolResult } from './tool-result'\nimport { wireSubagentInfo, wireSubagentRunId } from './subagent-wire'\nimport type { SubagentWireInfo } from './subagent-wire'\nimport {\n coerceCreatedAt,\n modelMessageToUIMessage,\n} from '../activities/chat/messages'\n\ntype WithMetadata<T> = T & { metadata?: MetadataRecord }\ntype WireSystemMessage = WithMetadata<SystemMessage>\ntype WireUserMessage = WithMetadata<UserMessage>\ntype WireAssistantMessage = WithMetadata<AssistantMessage>\ntype WireToolMessage = WithMetadata<\n ToolMessage & {\n name?: string\n }\n>\ntype WireReasoningMessage = WithMetadata<ReasoningMessage>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction rebuiltToolMetadata(\n metadata: unknown,\n createdAt: unknown,\n id: string | undefined,\n content: string | null | Array<ContentPart>,\n anchorOwnsUiResources = false,\n): MetadataRecord | undefined {\n const source: MetadataRecord = isRecord(metadata) ? metadata : {}\n const tanstack = isRecord(source.tanstack) ? { ...source.tanstack } : {}\n if (anchorOwnsUiResources) delete tanstack.uiResources\n const date = coerceCreatedAt(createdAt)\n const toolResult: NonNullable<TanStackMessageMetadata['toolResult']> = {\n ...(id !== undefined ? { id } : {}),\n ...(date && { createdAt: date.toISOString() }),\n ...(Array.isArray(content) && { content }),\n }\n const result = {\n ...source,\n tanstack: { ...tanstack, toolResult },\n }\n return Object.keys(result).length ? result : undefined\n}\n\nexport type WireMessage =\n | WireSystemMessage\n | WireUserMessage\n | WireAssistantMessage\n | WireToolMessage\n | WireReasoningMessage\n\n/**\n * Serialize TanStack `UIMessage`s and `ModelMessage`s into the AG-UI\n * `RunAgentInput.messages` wire shape. Anchors are spec-only (`id`, `role`,\n * `name`, `content`, `toolCalls`, `metadata`). Tool results and thinking parts\n * on assistant messages are additionally emitted as fan-out\n * `{role:'tool',...}` and `{role:'reasoning',...}` entries for strict AG-UI\n * server consumers. Set `includeSnapshotStructuredOutput` to retain complete\n * structured-output metadata for UI snapshots.\n */\nexport function uiMessagesToWire(\n messages: Array<UIMessage | ModelMessage>,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const wire: Array<WireMessage> = []\n const usedWireIds = new Set<string>(\n messages.flatMap((message) =>\n 'id' in message && message.id && message.role !== 'tool'\n ? [message.id]\n : [],\n ),\n )\n const includeSnapshotStructuredOutput =\n options?.includeSnapshotStructuredOutput ?? false\n\n const assistantIds = new Set<string>()\n for (const msg of messages) {\n if (msg.role === 'assistant' && msg.id !== undefined) {\n assistantIds.add(msg.id)\n }\n }\n\n for (const msg of messages) {\n if (!('parts' in msg) && msg.role === 'tool' && msg.toolCallId) {\n const id = uniqueToolWireId(\n toolWireId(msg.id, msg.toolCallId, assistantIds),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n msg.metadata,\n msg.createdAt,\n msg.id,\n msg.content,\n )\n wire.push({\n role: 'tool',\n id,\n ...(msg.name !== undefined && { name: msg.name }),\n toolCallId: msg.toolCallId,\n content:\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content),\n ...(msg.error !== undefined && { error: msg.error }),\n ...(metadata !== undefined && { metadata }),\n })\n continue\n }\n\n const uiMessage: UIMessage =\n 'parts' in msg ? msg : modelMessageToUIMessage(msg, msg.id)\n const parts: ReadonlyArray<MessagePart> = uiMessage.parts\n usedWireIds.add(uiMessage.id)\n\n if (msg.role === 'system') {\n wire.push(\n toAnchor(\n uiMessage,\n 'system',\n {\n content:\n parts.length > 0\n ? collectText(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n if (msg.role === 'user') {\n wire.push(\n toAnchor(\n uiMessage,\n 'user',\n {\n content:\n parts.length > 0\n ? collectUserContent(parts)\n : ((msg as { content?: string }).content ?? ''),\n },\n parts,\n includeSnapshotStructuredOutput,\n ),\n )\n continue\n }\n\n // assistant: reasoning fan-outs, then anchor, then tool fan-outs.\n //\n // Provider-executed tools (Anthropic web_search / web_fetch) run inside one\n // provider response, and the provider signs every thinking block against\n // the blocks before it. Emitting all reasoning first and a single anchor\n // with the joined text and every tool call turns\n // \"thinking, tool, thinking, text, tool\" into\n // \"thinking, thinking, text, tool, tool\", and the provider rejects the next\n // turn (\"thinking blocks in the latest assistant message cannot be\n // modified\"). Split the message into ordered segments at each thinking\n // part that follows a provider-executed tool call, the same rule\n // buildAssistantMessages applies, so the wire keeps the signed order.\n // Segments after the first get derived anchor ids; strict AG-UI consumers\n // still see plain anchors.\n type Segment = {\n thinking: Array<Extract<MessagePart, { type: 'thinking' }>>\n parts: Array<MessagePart>\n }\n let current: Segment = { thinking: [], parts: [] }\n const segments: Array<Segment> = [current]\n for (const part of parts) {\n if (part.type === 'thinking') {\n if (\n current.parts.some(\n (p) => p.type === 'tool-call' && isProviderExecutedToolCall(p),\n )\n ) {\n current = { thinking: [part], parts: [] }\n segments.push(current)\n } else {\n current.thinking.push(part)\n }\n } else {\n current.parts.push(part)\n }\n }\n\n segments.forEach((segment, index) => {\n for (const part of segment.thinking) {\n const reasoning: WireReasoningMessage = {\n role: 'reasoning',\n id: uniqueWireId(deriveReasoningId(uiMessage.id, part), usedWireIds),\n content: part.content,\n }\n if (part.signature) {\n reasoning.encryptedValue = part.signature\n }\n wire.push(reasoning)\n }\n\n const text = collectText(segment.parts)\n const toolCalls = collectToolCalls(segment.parts)\n const anchorMessage: UIMessage =\n index === 0\n ? uiMessage\n : {\n ...uiMessage,\n id: uniqueWireId(`${uiMessage.id}-segment-${index}`, usedWireIds),\n }\n wire.push(\n toAnchor(\n anchorMessage,\n 'assistant',\n {\n ...(text !== '' && { content: text }),\n ...(toolCalls && { toolCalls }),\n },\n segment.parts,\n includeSnapshotStructuredOutput,\n ),\n )\n })\n\n const explicitToolResults = new Set(\n parts.flatMap((part) =>\n part.type === 'tool-result' ? [part.toolCallId] : [],\n ),\n )\n for (const part of parts) {\n if (part.type === 'tool-result') {\n const id = uniqueToolWireId(\n part.id ?? deriveToolMessageId(part.toolCallId),\n usedWireIds,\n )\n const metadata = rebuiltToolMetadata(\n part.metadata,\n part.createdAt,\n part.id,\n part.content,\n true,\n )\n wire.push({\n role: 'tool',\n id,\n toolCallId: part.toolCallId,\n ...(part.name !== undefined && { name: part.name }),\n content:\n typeof part.content === 'string'\n ? part.content\n : JSON.stringify(part.content),\n ...(part.error !== undefined && { error: part.error }),\n ...(metadata !== undefined && { metadata }),\n })\n } else if (part.type === 'tool-call') {\n const approved = part.approval?.approved\n if (\n explicitToolResults.has(part.id) ||\n (part.output === undefined &&\n (part.state !== 'approval-responded' || approved === undefined))\n ) {\n continue\n }\n const result =\n part.output !== undefined\n ? normalizeToolResult(part.output)\n : JSON.stringify({\n approved,\n ...(approved && { pendingExecution: true }),\n message: approved\n ? 'User approved this action'\n : 'User denied this action',\n })\n const content =\n typeof result === 'string' ? result : JSON.stringify(result)\n wire.push({\n role: 'tool',\n id: uniqueToolWireId(deriveToolMessageId(part.id), usedWireIds),\n toolCallId: part.id,\n content,\n metadata: rebuiltToolMetadata(\n undefined,\n undefined,\n undefined,\n result,\n ),\n })\n }\n }\n\n for (const part of parts) {\n if (part.type === 'subagent') wire.push(...subagentToWire(part, options))\n }\n }\n\n return wire\n}\n\nfunction toAnchor(\n msg: UIMessage,\n role: 'system',\n extras: { content: string },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'user',\n extras: { content: string | Array<InputContent> },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireUserMessage\nfunction toAnchor(\n msg: UIMessage,\n role: 'assistant',\n extras: {\n content?: string\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireAssistantMessage\nfunction toAnchor(\n msg: UIMessage,\n role: UIMessage['role'],\n extras: {\n content?: string | Array<InputContent>\n toolCalls?: Array<ToolCall>\n },\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): WireSystemMessage | WireUserMessage | WireAssistantMessage {\n const metadata = messageMetadata(msg, parts, includeSnapshotStructuredOutput)\n const base = {\n id: msg.id,\n ...(msg.name !== undefined && { name: msg.name }),\n ...(metadata !== undefined && { metadata }),\n }\n if (role === 'system') {\n return { ...base, role, content: String(extras.content ?? '') }\n }\n if (role === 'user') {\n return { ...base, role, content: extras.content ?? '' }\n }\n return {\n ...base,\n role,\n ...(typeof extras.content === 'string' && { content: extras.content }),\n ...(extras.toolCalls !== undefined && { toolCalls: extras.toolCalls }),\n }\n}\n\nfunction messageMetadata(\n msg: UIMessage,\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): MetadataRecord | undefined {\n const base: MetadataRecord = { ...(msg.metadata ?? {}) }\n const previousTanstack = tanstackMetadata(msg)\n const tanstack: TanStackMessageMetadata = {}\n if (previousTanstack?.model !== undefined)\n tanstack.model = previousTanstack.model\n if (previousTanstack?.runId !== undefined)\n tanstack.runId = previousTanstack.runId\n if (previousTanstack?.signature !== undefined)\n tanstack.signature = previousTanstack.signature\n const createdAt = coerceCreatedAt(msg.createdAt)\n if (createdAt !== undefined) tanstack.createdAt = createdAt.toISOString()\n\n const structuredOutput = serializedStructuredOutput(\n parts,\n includeSnapshotStructuredOutput,\n )\n if (structuredOutput) tanstack.structuredOutput = structuredOutput\n\n const toolCallMetadata: Record<string, unknown> = {}\n for (const part of parts) {\n if (part.type === 'tool-call' && part.metadata !== undefined) {\n toolCallMetadata[part.id] = part.metadata\n }\n }\n if (Object.keys(toolCallMetadata).length > 0) {\n tanstack.toolCallMetadata = toolCallMetadata\n }\n\n const uiResources = parts.filter(\n (p): p is UIResourcePart => p.type === 'ui-resource',\n )\n if (uiResources.length > 0) tanstack.uiResources = uiResources\n\n if (Object.keys(tanstack).length > 0) base.tanstack = tanstack\n else delete base.tanstack\n return Object.keys(base).length > 0 ? base : undefined\n}\n\nfunction serializedStructuredOutput(\n parts: ReadonlyArray<MessagePart>,\n includeSnapshotStructuredOutput: boolean,\n): TanStackMessageMetadata['structuredOutput'] | undefined {\n for (const p of parts) {\n if (\n p.type === 'structured-output' &&\n (includeSnapshotStructuredOutput || p.status !== 'complete')\n ) {\n return structuredOutputMetadata(p, includeSnapshotStructuredOutput)\n }\n }\n return undefined\n}\n\nfunction structuredOutputMetadata(\n part: StructuredOutputPart,\n includeSnapshotStructuredOutput: boolean,\n): NonNullable<TanStackMessageMetadata['structuredOutput']> {\n return {\n status: part.status,\n raw: part.raw,\n ...(includeSnapshotStructuredOutput && part.partial !== undefined\n ? { partial: part.partial }\n : {}),\n ...(includeSnapshotStructuredOutput && part.data !== undefined\n ? { data: part.data }\n : {}),\n ...(includeSnapshotStructuredOutput && part.reasoning\n ? { reasoning: part.reasoning }\n : {}),\n ...(part.errorMessage !== undefined && { errorMessage: part.errorMessage }),\n }\n}\n\nfunction collectText(parts: ReadonlyArray<MessagePart>): string {\n // The streamed JSON of a completed structured-output part is the source of\n // truth for multi-turn coherence — emitting it back as assistant content\n // lets the LLM see its own prior structured response. Streaming/errored\n // parts are skipped: they'd ship malformed JSON fragments and confuse the\n // model. `completeStructuredOutputPart` tries hard to populate `raw`\n // (caller → existing buffer → `JSON.stringify(data)`), but the stringify\n // fallback can leave it empty when `data` is unserializable (BigInt,\n // circular). The `p.raw !== ''` guard below is what enforces \"no malformed\n // round-trip\" in that case — without it we'd ship `''` and the model would\n // see an empty assistant turn.\n const out: Array<string> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push(p.content)\n } else if (\n p.type === 'structured-output' &&\n p.status === 'complete' &&\n p.raw !== ''\n ) {\n out.push(p.raw)\n }\n }\n return out.join('')\n}\n\n/**\n * A child's messages, tagged with its AG-UI `subagentRunId`. The card data\n * rides in `metadata.tanstack.subagent`, so the other side can rebuild the\n * card and continue a suspended child.\n */\nfunction subagentToWire(\n part: SubagentPart,\n options?: { includeSnapshotStructuredOutput: boolean },\n): Array<WireMessage> {\n const { subagent } = part\n const info: SubagentWireInfo = {\n name: subagent.name,\n status: subagent.status,\n ...(subagent.description !== undefined && {\n description: subagent.description,\n }),\n ...(subagent.error !== undefined && { error: subagent.error }),\n ...(subagent.interruptIds !== undefined && {\n interruptIds: subagent.interruptIds,\n }),\n ...(subagent.parentSubagentRunId !== undefined && {\n parentSubagentRunId: subagent.parentSubagentRunId,\n }),\n ...(subagent.parentToolCallId !== undefined && {\n parentToolCallId: subagent.parentToolCallId,\n }),\n ...(subagent.metadata !== undefined && { metadata: subagent.metadata }),\n }\n const child = uiMessagesToWire(subagent.messages, options)\n const own = child.some((message) => wireSubagentRunId(message) === undefined)\n const messages: Array<WireMessage> = own\n ? child\n : [{ id: `subagent:${subagent.id}`, role: 'assistant' }, ...child]\n return messages.map((message, index) => {\n const nestedId = wireSubagentRunId(message)\n if (nestedId !== undefined) {\n const nested = wireSubagentInfo(message)\n if (!nested || nested.parentSubagentRunId !== undefined) return message\n return withSubagentInfo(message, nestedId, {\n ...nested,\n parentSubagentRunId: subagent.id,\n })\n }\n return withSubagentInfo(\n message,\n subagent.id,\n !own && index === 0 ? { ...info, placeholder: true } : info,\n )\n })\n}\n\nfunction withSubagentInfo(\n message: WireMessage,\n subagentRunId: string,\n info: SubagentWireInfo,\n): WireMessage {\n const metadata = isRecord(message.metadata) ? message.metadata : {}\n const tanstack = isRecord(metadata.tanstack) ? metadata.tanstack : {}\n return {\n ...message,\n subagentRunId,\n metadata: { ...metadata, tanstack: { ...tanstack, subagent: info } },\n }\n}\n\nfunction collectUserContent(\n parts: ReadonlyArray<MessagePart>,\n): string | Array<InputContent> {\n const hasMultimodal = parts.some(\n (p) =>\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document',\n )\n if (!hasMultimodal) {\n return collectText(parts)\n }\n const out: Array<InputContent> = []\n for (const p of parts) {\n if (p.type === 'text') {\n out.push({ type: 'text', text: p.content })\n } else if (\n p.type === 'image' ||\n p.type === 'audio' ||\n p.type === 'video' ||\n p.type === 'document'\n ) {\n out.push(p)\n }\n }\n return out\n}\n\nfunction thoughtSignatureFromMetadata(metadata: unknown): string | undefined {\n if (\n metadata == null ||\n typeof metadata !== 'object' ||\n Array.isArray(metadata)\n ) {\n return undefined\n }\n if (!('thoughtSignature' in metadata)) return undefined\n const value = metadata.thoughtSignature\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction collectToolCalls(\n parts: ReadonlyArray<MessagePart>,\n): Array<ToolCall> | undefined {\n const calls: Array<ToolCall> = []\n for (const p of parts) {\n if (p.type === 'tool-call') {\n const encryptedValue = thoughtSignatureFromMetadata(p.metadata)\n calls.push({\n id: p.id,\n type: 'function',\n function: { name: p.name, arguments: p.arguments },\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n })\n }\n }\n return calls.length > 0 ? calls : undefined\n}\n\nfunction deriveReasoningId(messageId: string, part: MessagePart): string {\n return `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`\n}\n\nfunction deriveToolMessageId(toolCallId: string): string {\n return `tool-${toolCallId}`\n}\n\nfunction uniqueToolWireId(id: string, used: Set<string>): string {\n return uniqueWireId(id, used)\n}\n\nfunction uniqueWireId(id: string, used: Set<string>): string {\n if (!used.has(id)) {\n used.add(id)\n return id\n }\n let suffix = 2\n while (used.has(`${id}-${suffix}`)) suffix++\n const unique = `${id}-${suffix}`\n used.add(unique)\n return unique\n}\n\nfunction toolWireId(\n id: string | undefined,\n toolCallId: string,\n assistantIds: ReadonlySet<string>,\n): string {\n const derived = deriveToolMessageId(toolCallId)\n if (id === undefined || assistantIds.has(id)) return derived\n return id\n}\n\nfunction hashContent(s: string): string {\n // Cheap deterministic id suffix; collisions are tolerable since\n // reasoning ids only matter for AG-UI server consumers, not for our\n // own server's dedup logic (which keys on toolCallId, not reasoning id).\n let h = 0\n for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0\n return Math.abs(h).toString(36)\n}\n"],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { ContentPartFileSource, ContentPartSource } from '../types.js';
2
+ /**
3
+ * Narrow a {@link ContentPartSource} to the provider-file-reference arm.
4
+ *
5
+ * Issuer adapters use this to route a file source to their native wire field;
6
+ * everyone else is protected by the core preflight (see
7
+ * {@link assertMessagesFileSourceSupport}) plus a defensive throw at their own
8
+ * mapping site.
9
+ */
10
+ export declare function isFileSource(source: ContentPartSource): source is ContentPartFileSource;
11
+ /**
12
+ * Resolve the handle `providerName` should send for a file source.
13
+ *
14
+ * A file source carries one opaque handle (`value`) and, optionally, the
15
+ * provider that issued it. An adapter always knows which provider it talks
16
+ * to, so a source that names no provider is taken as-is.
17
+ *
18
+ * @throws when the source names a different issuing provider. A handle only
19
+ * resolves at the provider that minted it.
20
+ */
21
+ export declare function fileReferenceFor(source: ContentPartFileSource, providerName: string): string;
22
+ /**
23
+ * Build the standard error a non-issuer adapter throws when it encounters a
24
+ * `{ type: 'file' }` source it can't consume — either because the provider has
25
+ * no file-reference input surface, or because the endpoint requires raw bytes
26
+ * (image edits, Veo) rather than a reference.
27
+ *
28
+ * @param detail Optional context appended to the message (e.g. a modality or
29
+ * endpoint name, or a pointer to the adapter that does support references).
30
+ * When provided it replaces the generic remediation tail, so a site-specific
31
+ * hint ("pass inline bytes") is never contradicted by generic advice.
32
+ */
33
+ export declare function unsupportedFileSourceError(providerName: string, detail?: string): Error;
34
+ /**
35
+ * The slice of an adapter the file-source preflight reads. Adapters that can
36
+ * consume `{ type: 'file' }` sources declare `supportsFileSources: true`;
37
+ * everything else — including adapters written before this arm existed —
38
+ * fails closed at the activity layer instead of falling through to a
39
+ * URL/data branch and silently mis-mapping the reference.
40
+ */
41
+ export interface FileSourceCapable {
42
+ name: string;
43
+ supportsFileSources?: boolean;
44
+ }
45
+ /**
46
+ * Fail-closed preflight for media prompts and embedding inputs
47
+ * (`generateImage` / `generateVideo` / `embed`): throws when the input
48
+ * carries a `{ type: 'file' }` source and the adapter hasn't declared
49
+ * `supportsFileSources`. Runs in the activity dispatcher — the same layer
50
+ * that validates modality — so an adapter that predates the file arm can
51
+ * never receive one. Walks a single part, an array of parts, and nested
52
+ * arrays (fused embedding items).
53
+ */
54
+ export declare function assertPromptFileSourceSupport(adapter: FileSourceCapable, prompt: unknown): void;
55
+ /**
56
+ * Fail-closed preflight for chat messages: throws when any message content
57
+ * part carries a `{ type: 'file' }` source and the adapter hasn't declared
58
+ * `supportsFileSources`. See {@link assertPromptFileSourceSupport}.
59
+ */
60
+ export declare function assertMessagesFileSourceSupport(adapter: FileSourceCapable, messages: ReadonlyArray<unknown>): void;
@@ -0,0 +1,85 @@
1
+ //#region src/utilities/content-source.ts
2
+ /**
3
+ * Narrow a {@link ContentPartSource} to the provider-file-reference arm.
4
+ *
5
+ * Issuer adapters use this to route a file source to their native wire field;
6
+ * everyone else is protected by the core preflight (see
7
+ * {@link assertMessagesFileSourceSupport}) plus a defensive throw at their own
8
+ * mapping site.
9
+ */
10
+ function isFileSource(source) {
11
+ return source.type === "file";
12
+ }
13
+ /**
14
+ * Resolve the handle `providerName` should send for a file source.
15
+ *
16
+ * A file source carries one opaque handle (`value`) and, optionally, the
17
+ * provider that issued it. An adapter always knows which provider it talks
18
+ * to, so a source that names no provider is taken as-is.
19
+ *
20
+ * @throws when the source names a different issuing provider. A handle only
21
+ * resolves at the provider that minted it.
22
+ */
23
+ function fileReferenceFor(source, providerName) {
24
+ if (source.provider !== void 0 && source.provider !== providerName) throw new Error(`${providerName}: file source was issued by ${source.provider}. A provider file handle only works with the provider that issued it. Upload the file with ${providerName}Files(), or pass a data or url source instead.`);
25
+ return source.value;
26
+ }
27
+ /**
28
+ * Build the standard error a non-issuer adapter throws when it encounters a
29
+ * `{ type: 'file' }` source it can't consume — either because the provider has
30
+ * no file-reference input surface, or because the endpoint requires raw bytes
31
+ * (image edits, Veo) rather than a reference.
32
+ *
33
+ * @param detail Optional context appended to the message (e.g. a modality or
34
+ * endpoint name, or a pointer to the adapter that does support references).
35
+ * When provided it replaces the generic remediation tail, so a site-specific
36
+ * hint ("pass inline bytes") is never contradicted by generic advice.
37
+ */
38
+ function unsupportedFileSourceError(providerName, detail) {
39
+ return /* @__PURE__ */ new Error(`${providerName} does not support provider file-handle sources ({ type: 'file' })` + (detail ? ` ${detail}.` : ". Pass a data or url source, or upload via the provider's files adapter where supported."));
40
+ }
41
+ /** True when a content-part-like value carries a `{ type: 'file' }` source. */
42
+ function partHasFileSource(part) {
43
+ if (typeof part !== "object" || part === null) return false;
44
+ const source = part.source;
45
+ return typeof source === "object" && source !== null && source.type === "file";
46
+ }
47
+ /**
48
+ * True when `value` is a content part with a file source, or an array
49
+ * (possibly nested — fused embedding items) that contains one.
50
+ */
51
+ function inputHasFileSource(value) {
52
+ if (Array.isArray(value)) return value.some(inputHasFileSource);
53
+ return partHasFileSource(value);
54
+ }
55
+ /**
56
+ * Fail-closed preflight for media prompts and embedding inputs
57
+ * (`generateImage` / `generateVideo` / `embed`): throws when the input
58
+ * carries a `{ type: 'file' }` source and the adapter hasn't declared
59
+ * `supportsFileSources`. Runs in the activity dispatcher — the same layer
60
+ * that validates modality — so an adapter that predates the file arm can
61
+ * never receive one. Walks a single part, an array of parts, and nested
62
+ * arrays (fused embedding items).
63
+ */
64
+ function assertPromptFileSourceSupport(adapter, prompt) {
65
+ if (adapter.supportsFileSources === true) return;
66
+ if (inputHasFileSource(prompt)) throw unsupportedFileSourceError(adapter.name);
67
+ }
68
+ /**
69
+ * Fail-closed preflight for chat messages: throws when any message content
70
+ * part carries a `{ type: 'file' }` source and the adapter hasn't declared
71
+ * `supportsFileSources`. See {@link assertPromptFileSourceSupport}.
72
+ */
73
+ function assertMessagesFileSourceSupport(adapter, messages) {
74
+ if (adapter.supportsFileSources === true) return;
75
+ for (const message of messages) {
76
+ if (typeof message !== "object" || message === null) continue;
77
+ const content = message.content;
78
+ if (!Array.isArray(content)) continue;
79
+ for (const part of content) if (partHasFileSource(part)) throw unsupportedFileSourceError(adapter.name);
80
+ }
81
+ }
82
+ //#endregion
83
+ export { assertMessagesFileSourceSupport, assertPromptFileSourceSupport, fileReferenceFor, isFileSource, unsupportedFileSourceError };
84
+
85
+ //# sourceMappingURL=content-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-source.js","names":[],"sources":["../../../src/utilities/content-source.ts"],"sourcesContent":["import type { ContentPartFileSource, ContentPartSource } from '../types'\n\n/**\n * Narrow a {@link ContentPartSource} to the provider-file-reference arm.\n *\n * Issuer adapters use this to route a file source to their native wire field;\n * everyone else is protected by the core preflight (see\n * {@link assertMessagesFileSourceSupport}) plus a defensive throw at their own\n * mapping site.\n */\nexport function isFileSource(\n source: ContentPartSource,\n): source is ContentPartFileSource {\n return source.type === 'file'\n}\n\n/**\n * Resolve the handle `providerName` should send for a file source.\n *\n * A file source carries one opaque handle (`value`) and, optionally, the\n * provider that issued it. An adapter always knows which provider it talks\n * to, so a source that names no provider is taken as-is.\n *\n * @throws when the source names a different issuing provider. A handle only\n * resolves at the provider that minted it.\n */\nexport function fileReferenceFor(\n source: ContentPartFileSource,\n providerName: string,\n): string {\n if (source.provider !== undefined && source.provider !== providerName) {\n throw new Error(\n `${providerName}: file source was issued by ${source.provider}. ` +\n `A provider file handle only works with the provider that issued ` +\n `it. Upload the file with ${providerName}Files(), or pass a data or ` +\n `url source instead.`,\n )\n }\n return source.value\n}\n\n/**\n * Build the standard error a non-issuer adapter throws when it encounters a\n * `{ type: 'file' }` source it can't consume — either because the provider has\n * no file-reference input surface, or because the endpoint requires raw bytes\n * (image edits, Veo) rather than a reference.\n *\n * @param detail Optional context appended to the message (e.g. a modality or\n * endpoint name, or a pointer to the adapter that does support references).\n * When provided it replaces the generic remediation tail, so a site-specific\n * hint (\"pass inline bytes\") is never contradicted by generic advice.\n */\nexport function unsupportedFileSourceError(\n providerName: string,\n detail?: string,\n): Error {\n return new Error(\n `${providerName} does not support provider file-handle sources ` +\n `({ type: 'file' })` +\n (detail\n ? ` ${detail}.`\n : `. Pass a data or url source, or upload via the provider's files ` +\n `adapter where supported.`),\n )\n}\n\n/**\n * The slice of an adapter the file-source preflight reads. Adapters that can\n * consume `{ type: 'file' }` sources declare `supportsFileSources: true`;\n * everything else — including adapters written before this arm existed —\n * fails closed at the activity layer instead of falling through to a\n * URL/data branch and silently mis-mapping the reference.\n */\nexport interface FileSourceCapable {\n name: string\n supportsFileSources?: boolean\n}\n\n/** True when a content-part-like value carries a `{ type: 'file' }` source. */\nfunction partHasFileSource(part: unknown): boolean {\n if (typeof part !== 'object' || part === null) return false\n const source = (part as { source?: unknown }).source\n return (\n typeof source === 'object' &&\n source !== null &&\n (source as { type?: unknown }).type === 'file'\n )\n}\n\n/**\n * True when `value` is a content part with a file source, or an array\n * (possibly nested — fused embedding items) that contains one.\n */\nfunction inputHasFileSource(value: unknown): boolean {\n if (Array.isArray(value)) return value.some(inputHasFileSource)\n return partHasFileSource(value)\n}\n\n/**\n * Fail-closed preflight for media prompts and embedding inputs\n * (`generateImage` / `generateVideo` / `embed`): throws when the input\n * carries a `{ type: 'file' }` source and the adapter hasn't declared\n * `supportsFileSources`. Runs in the activity dispatcher — the same layer\n * that validates modality — so an adapter that predates the file arm can\n * never receive one. Walks a single part, an array of parts, and nested\n * arrays (fused embedding items).\n */\nexport function assertPromptFileSourceSupport(\n adapter: FileSourceCapable,\n prompt: unknown,\n): void {\n if (adapter.supportsFileSources === true) return\n if (inputHasFileSource(prompt)) {\n throw unsupportedFileSourceError(adapter.name)\n }\n}\n\n/**\n * Fail-closed preflight for chat messages: throws when any message content\n * part carries a `{ type: 'file' }` source and the adapter hasn't declared\n * `supportsFileSources`. See {@link assertPromptFileSourceSupport}.\n */\nexport function assertMessagesFileSourceSupport(\n adapter: FileSourceCapable,\n messages: ReadonlyArray<unknown>,\n): void {\n if (adapter.supportsFileSources === true) return\n for (const message of messages) {\n if (typeof message !== 'object' || message === null) continue\n const content = (message as { content?: unknown }).content\n if (!Array.isArray(content)) continue\n for (const part of content) {\n if (partHasFileSource(part)) {\n throw unsupportedFileSourceError(adapter.name)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,aACd,QACiC;CACjC,OAAO,OAAO,SAAS;AACzB;;;;;;;;;;;AAYA,SAAgB,iBACd,QACA,cACQ;CACR,IAAI,OAAO,aAAa,KAAA,KAAa,OAAO,aAAa,cACvD,MAAM,IAAI,MACR,GAAG,aAAa,8BAA8B,OAAO,SAAS,6FAEhC,aAAa,+CAE7C;CAEF,OAAO,OAAO;AAChB;;;;;;;;;;;;AAaA,SAAgB,2BACd,cACA,QACO;CACP,uBAAO,IAAI,MACT,GAAG,aAAa,sEAEb,SACG,IAAI,OAAO,KACX,2FAER;AACF;;AAeA,SAAS,kBAAkB,MAAwB;CACjD,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO;CACtD,MAAM,SAAU,KAA8B;CAC9C,OACE,OAAO,WAAW,YAClB,WAAW,QACV,OAA8B,SAAS;AAE5C;;;;;AAMA,SAAS,mBAAmB,OAAyB;CACnD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,kBAAkB;CAC9D,OAAO,kBAAkB,KAAK;AAChC;;;;;;;;;;AAWA,SAAgB,8BACd,SACA,QACM;CACN,IAAI,QAAQ,wBAAwB,MAAM;CAC1C,IAAI,mBAAmB,MAAM,GAC3B,MAAM,2BAA2B,QAAQ,IAAI;AAEjD;;;;;;AAOA,SAAgB,gCACd,SACA,UACM;CACN,IAAI,QAAQ,wBAAwB,MAAM;CAC1C,KAAK,MAAM,WAAW,UAAU;EAC9B,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;EACrD,MAAM,UAAW,QAAkC;EACnD,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;EAC7B,KAAK,MAAM,QAAQ,SACjB,IAAI,kBAAkB,IAAI,GACxB,MAAM,2BAA2B,QAAQ,IAAI;CAGnD;AACF"}
@@ -7,11 +7,16 @@ import { specKeysFor } from "./spec-event-keys.js";
7
7
  function stringField(value) {
8
8
  return typeof value === "string" && value !== "" ? value : void 0;
9
9
  }
10
+ function chunkFields(chunk) {
11
+ const fields = {};
12
+ for (const key of Object.keys(chunk)) fields[key] = Reflect.get(chunk, key);
13
+ return fields;
14
+ }
10
15
  function encryptedValueExtras(chunk) {
11
16
  const extras = [];
12
17
  const timestamp = "timestamp" in chunk && typeof chunk.timestamp === "number" ? chunk.timestamp : void 0;
13
18
  if (typeof chunk.signature === "string" && chunk.signature !== "") {
14
- const source = chunk;
19
+ const source = chunkFields(chunk);
15
20
  const toolCallId = stringField(source.toolCallId);
16
21
  const entityId = stringField(chunk.stepId) ?? stringField(source.stepName) ?? stringField(source.messageId) ?? toolCallId;
17
22
  if (entityId !== void 0) extras.push(reasoningEncryptedValue({
@@ -34,7 +39,7 @@ function encryptedValueExtras(chunk) {
34
39
  }
35
40
  function normalizeStreamChunk(chunk) {
36
41
  const specKeys = specKeysFor(chunk.type);
37
- const source = chunk;
42
+ const source = chunkFields(chunk);
38
43
  const specChunk = {};
39
44
  for (const key of Object.keys(chunk)) if (specKeys.has(key)) specChunk[key] = source[key];
40
45
  if (chunk.type === EventType.TOOL_CALL_START) {
@@ -1 +1 @@
1
- {"version":3,"file":"normalize-stream-chunk.js","names":[],"sources":["../../../src/utilities/normalize-stream-chunk.ts"],"sourcesContent":["import { EventType } from '../types'\nimport type { StreamChunk, ToolCallResultEvent } from '../types'\nimport type { AdapterYieldChunk } from './adapter-yield-chunk'\nimport { isTanstackUsage, toSpecTokenUsage } from './ag-ui-usage'\nimport type { MetadataRecord } from './merge-metadata'\nimport { withTanstackMetadata } from './merge-metadata'\nimport { reasoningEncryptedValue } from './reasoning-encrypted-value'\nimport { specKeysFor } from './spec-event-keys'\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction encryptedValueExtras(chunk: AdapterYieldChunk): Array<StreamChunk> {\n const extras: Array<StreamChunk> = []\n const timestamp =\n 'timestamp' in chunk && typeof chunk.timestamp === 'number'\n ? chunk.timestamp\n : undefined\n\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n const source = chunk as Record<string, unknown>\n const toolCallId = stringField(source.toolCallId)\n const entityId =\n stringField(chunk.stepId) ??\n stringField(source.stepName) ??\n stringField(source.messageId) ??\n toolCallId\n if (entityId !== undefined) {\n extras.push(\n reasoningEncryptedValue({\n subtype: toolCallId && !chunk.stepId ? 'tool-call' : 'message',\n entityId,\n encryptedValue: chunk.signature,\n timestamp,\n }),\n )\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n const thoughtSignature = stringField(\n (chunk.metadata as { thoughtSignature?: unknown } | undefined)\n ?.thoughtSignature,\n )\n if (thoughtSignature !== undefined && chunk.toolCallId) {\n extras.push(\n reasoningEncryptedValue({\n subtype: 'tool-call',\n entityId: chunk.toolCallId,\n encryptedValue: thoughtSignature,\n timestamp,\n }),\n )\n }\n }\n\n return extras\n}\n\nexport function normalizeStreamChunk(\n chunk: AdapterYieldChunk,\n): Array<StreamChunk> {\n const specKeys = specKeysFor(chunk.type)\n const source = chunk as Record<string, unknown>\n const specChunk: Record<string, unknown> & {\n metadata?: MetadataRecord | null\n } = {}\n\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key)) {\n specChunk[key] = source[key]\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n if (specChunk.toolCallName === undefined && chunk.toolName) {\n specChunk.toolCallName = chunk.toolName\n }\n }\n\n if (chunk.type === EventType.RUN_ERROR && chunk.error != null) {\n if (specChunk.message === undefined && chunk.error.message) {\n specChunk.message = chunk.error.message\n }\n if (specChunk.code === undefined && chunk.error.code !== undefined) {\n specChunk.code = chunk.error.code\n }\n }\n\n const tanstack: MetadataRecord = {}\n\n if (\n chunk.model !== undefined &&\n chunk.type !== EventType.TEXT_MESSAGE_CONTENT &&\n chunk.type !== EventType.TOOL_CALL_ARGS\n ) {\n tanstack.model = chunk.model\n }\n\n if (chunk.finishReason !== undefined) {\n tanstack.finishReason = chunk.finishReason\n }\n\n const interruptErrors = chunk['tanstack:interruptErrors']\n if (interruptErrors !== undefined) {\n tanstack.interruptErrors = interruptErrors\n }\n\n if (chunk.type === EventType.CUSTOM || chunk.type === EventType.RUN_ERROR) {\n if (chunk.threadId !== undefined) {\n tanstack.threadId = chunk.threadId\n }\n if (chunk.runId !== undefined) {\n tanstack.runId = chunk.runId\n }\n }\n\n const skipLeftover = new Set(['result', 'error', 'tanstack:interruptErrors'])\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TOOL_CALL_ARGS\n ) {\n skipLeftover.add('model')\n skipLeftover.add('content')\n skipLeftover.add('args')\n }\n if (chunk.type === EventType.TOOL_CALL_START) {\n skipLeftover.add('toolName')\n }\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key) || skipLeftover.has(key)) continue\n if (tanstack[key] !== undefined) continue\n const value = source[key]\n if (value !== undefined) {\n tanstack[key] = value\n }\n }\n\n if (\n (chunk.type === EventType.RUN_FINISHED ||\n chunk.type === EventType.RUN_ERROR) &&\n isTanstackUsage(specChunk.usage)\n ) {\n const { usage, leftover } = toSpecTokenUsage(specChunk.usage, {\n model: typeof chunk.model === 'string' ? chunk.model : undefined,\n })\n specChunk.usage = usage\n if (leftover !== undefined) {\n tanstack.usage = leftover\n }\n }\n\n const normalized =\n Object.keys(tanstack).length === 0\n ? specChunk\n : withTanstackMetadata(specChunk, tanstack)\n\n const extras = encryptedValueExtras(chunk)\n const main: Array<StreamChunk> = [normalized as StreamChunk]\n\n if (chunk.type === EventType.TOOL_CALL_END && chunk.result !== undefined) {\n const parentMessageId = source.parentMessageId\n const resultChunk: ToolCallResultEvent = {\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(chunk.result)\n ? JSON.stringify(chunk.result)\n : chunk.result,\n messageId:\n typeof parentMessageId === 'string' && parentMessageId !== ''\n ? parentMessageId\n : chunk.toolCallId,\n }\n if (chunk.state === 'output-error') {\n main.push({\n ...resultChunk,\n metadata: { tanstack: { state: chunk.state } },\n })\n } else {\n main.push(resultChunk)\n }\n }\n\n return [...main, ...extras]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"normalize-stream-chunk.js","names":[],"sources":["../../../src/utilities/normalize-stream-chunk.ts"],"sourcesContent":["import { EventType } from '../types'\nimport type { StreamChunk, ToolCallResultEvent } from '../types'\nimport type { AdapterYieldChunk } from './adapter-yield-chunk'\nimport { isTanstackUsage, toSpecTokenUsage } from './ag-ui-usage'\nimport type { MetadataRecord } from './merge-metadata'\nimport { withTanstackMetadata } from './merge-metadata'\nimport { reasoningEncryptedValue } from './reasoning-encrypted-value'\nimport { specKeysFor } from './spec-event-keys'\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value !== '' ? value : undefined\n}\n\nfunction chunkFields(chunk: object) {\n const fields: Record<string, unknown> = {}\n for (const key of Object.keys(chunk)) {\n fields[key] = Reflect.get(chunk, key)\n }\n return fields\n}\n\nfunction encryptedValueExtras(chunk: AdapterYieldChunk): Array<StreamChunk> {\n const extras: Array<StreamChunk> = []\n const timestamp =\n 'timestamp' in chunk && typeof chunk.timestamp === 'number'\n ? chunk.timestamp\n : undefined\n\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n const source = chunkFields(chunk)\n const toolCallId = stringField(source.toolCallId)\n const entityId =\n stringField(chunk.stepId) ??\n stringField(source.stepName) ??\n stringField(source.messageId) ??\n toolCallId\n if (entityId !== undefined) {\n extras.push(\n reasoningEncryptedValue({\n subtype: toolCallId && !chunk.stepId ? 'tool-call' : 'message',\n entityId,\n encryptedValue: chunk.signature,\n timestamp,\n }),\n )\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n const thoughtSignature = stringField(\n (chunk.metadata as { thoughtSignature?: unknown } | undefined)\n ?.thoughtSignature,\n )\n if (thoughtSignature !== undefined && chunk.toolCallId) {\n extras.push(\n reasoningEncryptedValue({\n subtype: 'tool-call',\n entityId: chunk.toolCallId,\n encryptedValue: thoughtSignature,\n timestamp,\n }),\n )\n }\n }\n\n return extras\n}\n\nexport function normalizeStreamChunk(\n chunk: AdapterYieldChunk,\n): Array<StreamChunk> {\n const specKeys = specKeysFor(chunk.type)\n const source = chunkFields(chunk)\n const specChunk: Record<string, unknown> & {\n metadata?: MetadataRecord | null\n } = {}\n\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key)) {\n specChunk[key] = source[key]\n }\n }\n\n if (chunk.type === EventType.TOOL_CALL_START) {\n if (specChunk.toolCallName === undefined && chunk.toolName) {\n specChunk.toolCallName = chunk.toolName\n }\n }\n\n if (chunk.type === EventType.RUN_ERROR && chunk.error != null) {\n if (specChunk.message === undefined && chunk.error.message) {\n specChunk.message = chunk.error.message\n }\n if (specChunk.code === undefined && chunk.error.code !== undefined) {\n specChunk.code = chunk.error.code\n }\n }\n\n const tanstack: MetadataRecord = {}\n\n if (\n chunk.model !== undefined &&\n chunk.type !== EventType.TEXT_MESSAGE_CONTENT &&\n chunk.type !== EventType.TOOL_CALL_ARGS\n ) {\n tanstack.model = chunk.model\n }\n\n if (chunk.finishReason !== undefined) {\n tanstack.finishReason = chunk.finishReason\n }\n\n const interruptErrors = chunk['tanstack:interruptErrors']\n if (interruptErrors !== undefined) {\n tanstack.interruptErrors = interruptErrors\n }\n\n if (chunk.type === EventType.CUSTOM || chunk.type === EventType.RUN_ERROR) {\n if (chunk.threadId !== undefined) {\n tanstack.threadId = chunk.threadId\n }\n if (chunk.runId !== undefined) {\n tanstack.runId = chunk.runId\n }\n }\n\n const skipLeftover = new Set(['result', 'error', 'tanstack:interruptErrors'])\n if (\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TOOL_CALL_ARGS\n ) {\n skipLeftover.add('model')\n skipLeftover.add('content')\n skipLeftover.add('args')\n }\n if (chunk.type === EventType.TOOL_CALL_START) {\n skipLeftover.add('toolName')\n }\n for (const key of Object.keys(chunk)) {\n if (specKeys.has(key) || skipLeftover.has(key)) continue\n if (tanstack[key] !== undefined) continue\n const value = source[key]\n if (value !== undefined) {\n tanstack[key] = value\n }\n }\n\n if (\n (chunk.type === EventType.RUN_FINISHED ||\n chunk.type === EventType.RUN_ERROR) &&\n isTanstackUsage(specChunk.usage)\n ) {\n const { usage, leftover } = toSpecTokenUsage(specChunk.usage, {\n model: typeof chunk.model === 'string' ? chunk.model : undefined,\n })\n specChunk.usage = usage\n if (leftover !== undefined) {\n tanstack.usage = leftover\n }\n }\n\n const normalized =\n Object.keys(tanstack).length === 0\n ? specChunk\n : withTanstackMetadata(specChunk, tanstack)\n\n const extras = encryptedValueExtras(chunk)\n const main: Array<StreamChunk> = [normalized as StreamChunk]\n\n if (chunk.type === EventType.TOOL_CALL_END && chunk.result !== undefined) {\n const parentMessageId = source.parentMessageId\n const resultChunk: ToolCallResultEvent = {\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(chunk.result)\n ? JSON.stringify(chunk.result)\n : chunk.result,\n messageId:\n typeof parentMessageId === 'string' && parentMessageId !== ''\n ? parentMessageId\n : chunk.toolCallId,\n }\n if (chunk.state === 'output-error') {\n main.push({\n ...resultChunk,\n metadata: { tanstack: { state: chunk.state } },\n })\n } else {\n main.push(resultChunk)\n }\n }\n\n return [...main, ...extras]\n}\n"],"mappings":"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"}
@@ -16,3 +16,10 @@ export declare function getProviderExecutedMetadata(toolCall: {
16
16
  export declare function isProviderExecutedToolCall(toolCall: {
17
17
  metadata?: unknown;
18
18
  } | null | undefined): boolean;
19
+ /**
20
+ * True when `id` is a `${parentId}-segment-${n}` message. The wire and the
21
+ * run loop split one provider turn into segments at thinking that follows a
22
+ * provider-executed tool call, to keep signed thinking order. Readers fold a
23
+ * segment back into its parent so the UI still shows one message.
24
+ */
25
+ export declare function isAssistantSegmentOf(id: string | undefined, parentId: string): boolean;
@@ -18,7 +18,16 @@ function getProviderExecutedMetadata(toolCall) {
18
18
  function isProviderExecutedToolCall(toolCall) {
19
19
  return getProviderExecutedMetadata(toolCall) !== null;
20
20
  }
21
+ /**
22
+ * True when `id` is a `${parentId}-segment-${n}` message. The wire and the
23
+ * run loop split one provider turn into segments at thinking that follows a
24
+ * provider-executed tool call, to keep signed thinking order. Readers fold a
25
+ * segment back into its parent so the UI still shows one message.
26
+ */
27
+ function isAssistantSegmentOf(id, parentId) {
28
+ return id?.startsWith(`${parentId}-segment-`) === true;
29
+ }
21
30
  //#endregion
22
- export { getProviderExecutedMetadata, isProviderExecutedToolCall };
31
+ export { getProviderExecutedMetadata, isAssistantSegmentOf, isProviderExecutedToolCall };
23
32
 
24
33
  //# sourceMappingURL=provider-executed.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-executed.js","names":[],"sources":["../../../src/utilities/provider-executed.ts"],"sourcesContent":["import type { ProviderExecutedToolMetadata } from '../types'\n\n/**\n * Narrow a tool call's opaque `metadata` to the provider-executed convention.\n * Returns the typed metadata when the call is provider-executed, else `null`.\n *\n * @see ProviderExecutedToolMetadata\n */\nexport function getProviderExecutedMetadata(\n toolCall: { metadata?: unknown } | null | undefined,\n): ProviderExecutedToolMetadata | null {\n const metadata = toolCall?.metadata\n if (\n typeof metadata === 'object' &&\n metadata !== null &&\n (metadata as ProviderExecutedToolMetadata).providerExecuted === true\n ) {\n return metadata as ProviderExecutedToolMetadata\n }\n return null\n}\n\n/**\n * True when a tool call was executed by the provider (e.g. Anthropic\n * `web_search` / `web_fetch` server tools) rather than the agent loop. Such\n * calls must not be routed to client-side execution and are already \"complete\".\n */\nexport function isProviderExecutedToolCall(\n toolCall: { metadata?: unknown } | null | undefined,\n): boolean {\n return getProviderExecutedMetadata(toolCall) !== null\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,4BACd,UACqC;CACrC,MAAM,WAAW,UAAU;CAC3B,IACE,OAAO,aAAa,YACpB,aAAa,QACZ,SAA0C,qBAAqB,MAEhE,OAAO;CAET,OAAO;AACT;;;;;;AAOA,SAAgB,2BACd,UACS;CACT,OAAO,4BAA4B,QAAQ,MAAM;AACnD"}
1
+ {"version":3,"file":"provider-executed.js","names":[],"sources":["../../../src/utilities/provider-executed.ts"],"sourcesContent":["import type { ProviderExecutedToolMetadata } from '../types'\n\n/**\n * Narrow a tool call's opaque `metadata` to the provider-executed convention.\n * Returns the typed metadata when the call is provider-executed, else `null`.\n *\n * @see ProviderExecutedToolMetadata\n */\nexport function getProviderExecutedMetadata(\n toolCall: { metadata?: unknown } | null | undefined,\n): ProviderExecutedToolMetadata | null {\n const metadata = toolCall?.metadata\n if (\n typeof metadata === 'object' &&\n metadata !== null &&\n (metadata as ProviderExecutedToolMetadata).providerExecuted === true\n ) {\n return metadata as ProviderExecutedToolMetadata\n }\n return null\n}\n\n/**\n * True when a tool call was executed by the provider (e.g. Anthropic\n * `web_search` / `web_fetch` server tools) rather than the agent loop. Such\n * calls must not be routed to client-side execution and are already \"complete\".\n */\nexport function isProviderExecutedToolCall(\n toolCall: { metadata?: unknown } | null | undefined,\n): boolean {\n return getProviderExecutedMetadata(toolCall) !== null\n}\n\n/**\n * True when `id` is a `${parentId}-segment-${n}` message. The wire and the\n * run loop split one provider turn into segments at thinking that follows a\n * provider-executed tool call, to keep signed thinking order. Readers fold a\n * segment back into its parent so the UI still shows one message.\n */\nexport function isAssistantSegmentOf(\n id: string | undefined,\n parentId: string,\n): boolean {\n return id?.startsWith(`${parentId}-segment-`) === true\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,4BACd,UACqC;CACrC,MAAM,WAAW,UAAU;CAC3B,IACE,OAAO,aAAa,YACpB,aAAa,QACZ,SAA0C,qBAAqB,MAEhE,OAAO;CAET,OAAO;AACT;;;;;;AAOA,SAAgB,2BACd,UACS;CACT,OAAO,4BAA4B,QAAQ,MAAM;AACnD;;;;;;;AAQA,SAAgB,qBACd,IACA,UACS;CACT,OAAO,IAAI,WAAW,GAAG,SAAS,UAAU,MAAM;AACpD"}
@@ -19,11 +19,6 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
19
19
  [EventType.TOOL_CALL_END, keys("toolCallId")],
20
20
  [EventType.TOOL_CALL_CHUNK, keys("toolCallId", "toolCallName", "parentMessageId", "delta")],
21
21
  [EventType.TOOL_CALL_RESULT, keys("messageId", "toolCallId", "content", "role")],
22
- [EventType.THINKING_START, keys("title")],
23
- [EventType.THINKING_END, SHARED],
24
- [EventType.THINKING_TEXT_MESSAGE_START, SHARED],
25
- [EventType.THINKING_TEXT_MESSAGE_CONTENT, keys("delta")],
26
- [EventType.THINKING_TEXT_MESSAGE_END, SHARED],
27
22
  [EventType.STATE_SNAPSHOT, keys("snapshot")],
28
23
  [EventType.STATE_DELTA, keys("delta")],
29
24
  [EventType.MESSAGES_SNAPSHOT, keys("messages")],
@@ -31,7 +26,7 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
31
26
  [EventType.ACTIVITY_DELTA, keys("messageId", "activityType", "patch")],
32
27
  [EventType.RAW, keys("event", "source")],
33
28
  [EventType.CUSTOM, keys("name", "value")],
34
- [EventType.RUN_STARTED, keys("threadId", "runId", "parentRunId", "input")],
29
+ [EventType.RUN_STARTED, keys("threadId", "runId", "protocolVersion", "parentRunId", "input")],
35
30
  [EventType.RUN_FINISHED, keys("threadId", "runId", "result", "outcome", "usage")],
36
31
  [EventType.RUN_ERROR, keys("message", "code", "usage")],
37
32
  [EventType.STEP_STARTED, keys("stepName")],
@@ -42,10 +37,20 @@ var SPEC_KEYS = /* @__PURE__ */ new Map([
42
37
  [EventType.REASONING_MESSAGE_END, keys("messageId")],
43
38
  [EventType.REASONING_MESSAGE_CHUNK, keys("messageId", "delta")],
44
39
  [EventType.REASONING_END, keys("messageId")],
45
- [EventType.REASONING_ENCRYPTED_VALUE, keys("subtype", "entityId", "encryptedValue")]
40
+ [EventType.REASONING_ENCRYPTED_VALUE, keys("subtype", "entityId", "encryptedValue")],
41
+ [EventType.SUBAGENT_STARTED, keys("subagentRunId", "name", "description", "parentSubagentRunId", "parentToolCallId", "parentMessageId")],
42
+ [EventType.SUBAGENT_FINISHED, keys("subagentRunId", "result", "outcome")],
43
+ [EventType.SUBAGENT_ERROR, keys("subagentRunId", "message", "code")]
46
44
  ]);
45
+ var RUN_SCOPED = /* @__PURE__ */ new Set([
46
+ EventType.RUN_STARTED,
47
+ EventType.RUN_FINISHED,
48
+ EventType.RUN_ERROR,
49
+ EventType.MESSAGES_SNAPSHOT
50
+ ]);
51
+ var ATTRIBUTABLE_KEYS = new Map([...SPEC_KEYS].filter(([type]) => !RUN_SCOPED.has(type)).map(([type, fields]) => [type, /* @__PURE__ */ new Set([...fields, "subagentRunId"])]));
47
52
  function specKeysFor(type) {
48
- return SPEC_KEYS.get(type) ?? SHARED;
53
+ return ATTRIBUTABLE_KEYS.get(type) ?? SPEC_KEYS.get(type) ?? SHARED;
49
54
  }
50
55
  function isSpecTopLevelKey(type, key) {
51
56
  return specKeysFor(type).has(key);
@@ -1 +1 @@
1
- {"version":3,"file":"spec-event-keys.js","names":[],"sources":["../../../src/utilities/spec-event-keys.ts"],"sourcesContent":["import { EventType } from '../types'\n\nconst SHARED: ReadonlySet<string> = new Set([\n 'type',\n 'timestamp',\n 'rawEvent',\n 'metadata',\n])\n\nfunction keys(...fields: Array<string>): ReadonlySet<string> {\n return new Set([...SHARED, ...fields])\n}\n\nconst SPEC_KEYS: ReadonlyMap<string, ReadonlySet<string>> = new Map([\n [EventType.TEXT_MESSAGE_START, keys('messageId', 'role', 'name')],\n [EventType.TEXT_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.TEXT_MESSAGE_END, keys('messageId')],\n [EventType.TEXT_MESSAGE_CHUNK, keys('messageId', 'role', 'delta', 'name')],\n [\n EventType.TOOL_CALL_START,\n keys('toolCallId', 'toolCallName', 'parentMessageId'),\n ],\n [EventType.TOOL_CALL_ARGS, keys('toolCallId', 'delta')],\n [EventType.TOOL_CALL_END, keys('toolCallId')],\n [\n EventType.TOOL_CALL_CHUNK,\n keys('toolCallId', 'toolCallName', 'parentMessageId', 'delta'),\n ],\n [\n EventType.TOOL_CALL_RESULT,\n keys('messageId', 'toolCallId', 'content', 'role'),\n ],\n [EventType.THINKING_START, keys('title')],\n [EventType.THINKING_END, SHARED],\n [EventType.THINKING_TEXT_MESSAGE_START, SHARED],\n [EventType.THINKING_TEXT_MESSAGE_CONTENT, keys('delta')],\n [EventType.THINKING_TEXT_MESSAGE_END, SHARED],\n [EventType.STATE_SNAPSHOT, keys('snapshot')],\n [EventType.STATE_DELTA, keys('delta')],\n [EventType.MESSAGES_SNAPSHOT, keys('messages')],\n [\n EventType.ACTIVITY_SNAPSHOT,\n keys('messageId', 'activityType', 'content', 'replace'),\n ],\n [EventType.ACTIVITY_DELTA, keys('messageId', 'activityType', 'patch')],\n [EventType.RAW, keys('event', 'source')],\n [EventType.CUSTOM, keys('name', 'value')],\n [EventType.RUN_STARTED, keys('threadId', 'runId', 'parentRunId', 'input')],\n [\n EventType.RUN_FINISHED,\n keys('threadId', 'runId', 'result', 'outcome', 'usage'),\n ],\n [EventType.RUN_ERROR, keys('message', 'code', 'usage')],\n [EventType.STEP_STARTED, keys('stepName')],\n [EventType.STEP_FINISHED, keys('stepName')],\n [EventType.REASONING_START, keys('messageId')],\n [EventType.REASONING_MESSAGE_START, keys('messageId', 'role')],\n [EventType.REASONING_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.REASONING_MESSAGE_END, keys('messageId')],\n [EventType.REASONING_MESSAGE_CHUNK, keys('messageId', 'delta')],\n [EventType.REASONING_END, keys('messageId')],\n [\n EventType.REASONING_ENCRYPTED_VALUE,\n keys('subtype', 'entityId', 'encryptedValue'),\n ],\n])\n\nexport function specKeysFor(type: string): ReadonlySet<string> {\n return SPEC_KEYS.get(type) ?? SHARED\n}\n\nexport function isSpecTopLevelKey(type: string, key: string): boolean {\n return specKeysFor(type).has(key)\n}\n"],"mappings":";;AAEA,IAAM,yBAA8B,IAAI,IAAI;CAC1C;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,KAAK,GAAG,QAA4C;CAC3D,uBAAO,IAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,MAAM,CAAC;AACvC;AAEA,IAAM,4BAAsD,IAAI,IAAI;CAClE,CAAC,UAAU,oBAAoB,KAAK,aAAa,QAAQ,MAAM,CAAC;CAChE,CAAC,UAAU,sBAAsB,KAAK,aAAa,OAAO,CAAC;CAC3D,CAAC,UAAU,kBAAkB,KAAK,WAAW,CAAC;CAC9C,CAAC,UAAU,oBAAoB,KAAK,aAAa,QAAQ,SAAS,MAAM,CAAC;CACzE,CACE,UAAU,iBACV,KAAK,cAAc,gBAAgB,iBAAiB,CACtD;CACA,CAAC,UAAU,gBAAgB,KAAK,cAAc,OAAO,CAAC;CACtD,CAAC,UAAU,eAAe,KAAK,YAAY,CAAC;CAC5C,CACE,UAAU,iBACV,KAAK,cAAc,gBAAgB,mBAAmB,OAAO,CAC/D;CACA,CACE,UAAU,kBACV,KAAK,aAAa,cAAc,WAAW,MAAM,CACnD;CACA,CAAC,UAAU,gBAAgB,KAAK,OAAO,CAAC;CACxC,CAAC,UAAU,cAAc,MAAM;CAC/B,CAAC,UAAU,6BAA6B,MAAM;CAC9C,CAAC,UAAU,+BAA+B,KAAK,OAAO,CAAC;CACvD,CAAC,UAAU,2BAA2B,MAAM;CAC5C,CAAC,UAAU,gBAAgB,KAAK,UAAU,CAAC;CAC3C,CAAC,UAAU,aAAa,KAAK,OAAO,CAAC;CACrC,CAAC,UAAU,mBAAmB,KAAK,UAAU,CAAC;CAC9C,CACE,UAAU,mBACV,KAAK,aAAa,gBAAgB,WAAW,SAAS,CACxD;CACA,CAAC,UAAU,gBAAgB,KAAK,aAAa,gBAAgB,OAAO,CAAC;CACrE,CAAC,UAAU,KAAK,KAAK,SAAS,QAAQ,CAAC;CACvC,CAAC,UAAU,QAAQ,KAAK,QAAQ,OAAO,CAAC;CACxC,CAAC,UAAU,aAAa,KAAK,YAAY,SAAS,eAAe,OAAO,CAAC;CACzE,CACE,UAAU,cACV,KAAK,YAAY,SAAS,UAAU,WAAW,OAAO,CACxD;CACA,CAAC,UAAU,WAAW,KAAK,WAAW,QAAQ,OAAO,CAAC;CACtD,CAAC,UAAU,cAAc,KAAK,UAAU,CAAC;CACzC,CAAC,UAAU,eAAe,KAAK,UAAU,CAAC;CAC1C,CAAC,UAAU,iBAAiB,KAAK,WAAW,CAAC;CAC7C,CAAC,UAAU,yBAAyB,KAAK,aAAa,MAAM,CAAC;CAC7D,CAAC,UAAU,2BAA2B,KAAK,aAAa,OAAO,CAAC;CAChE,CAAC,UAAU,uBAAuB,KAAK,WAAW,CAAC;CACnD,CAAC,UAAU,yBAAyB,KAAK,aAAa,OAAO,CAAC;CAC9D,CAAC,UAAU,eAAe,KAAK,WAAW,CAAC;CAC3C,CACE,UAAU,2BACV,KAAK,WAAW,YAAY,gBAAgB,CAC9C;AACF,CAAC;AAED,SAAgB,YAAY,MAAmC;CAC7D,OAAO,UAAU,IAAI,IAAI,KAAK;AAChC;AAEA,SAAgB,kBAAkB,MAAc,KAAsB;CACpE,OAAO,YAAY,IAAI,CAAC,CAAC,IAAI,GAAG;AAClC"}
1
+ {"version":3,"file":"spec-event-keys.js","names":[],"sources":["../../../src/utilities/spec-event-keys.ts"],"sourcesContent":["import { EventType } from '../types'\n\nconst SHARED: ReadonlySet<string> = new Set([\n 'type',\n 'timestamp',\n 'rawEvent',\n 'metadata',\n])\n\nfunction keys(...fields: Array<string>): ReadonlySet<string> {\n return new Set([...SHARED, ...fields])\n}\n\nconst SPEC_KEYS: ReadonlyMap<string, ReadonlySet<string>> = new Map([\n [EventType.TEXT_MESSAGE_START, keys('messageId', 'role', 'name')],\n [EventType.TEXT_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.TEXT_MESSAGE_END, keys('messageId')],\n [EventType.TEXT_MESSAGE_CHUNK, keys('messageId', 'role', 'delta', 'name')],\n [\n EventType.TOOL_CALL_START,\n keys('toolCallId', 'toolCallName', 'parentMessageId'),\n ],\n [EventType.TOOL_CALL_ARGS, keys('toolCallId', 'delta')],\n [EventType.TOOL_CALL_END, keys('toolCallId')],\n [\n EventType.TOOL_CALL_CHUNK,\n keys('toolCallId', 'toolCallName', 'parentMessageId', 'delta'),\n ],\n [\n EventType.TOOL_CALL_RESULT,\n keys('messageId', 'toolCallId', 'content', 'role'),\n ],\n [EventType.STATE_SNAPSHOT, keys('snapshot')],\n [EventType.STATE_DELTA, keys('delta')],\n [EventType.MESSAGES_SNAPSHOT, keys('messages')],\n [\n EventType.ACTIVITY_SNAPSHOT,\n keys('messageId', 'activityType', 'content', 'replace'),\n ],\n [EventType.ACTIVITY_DELTA, keys('messageId', 'activityType', 'patch')],\n [EventType.RAW, keys('event', 'source')],\n [EventType.CUSTOM, keys('name', 'value')],\n [\n EventType.RUN_STARTED,\n keys('threadId', 'runId', 'protocolVersion', 'parentRunId', 'input'),\n ],\n [\n EventType.RUN_FINISHED,\n keys('threadId', 'runId', 'result', 'outcome', 'usage'),\n ],\n [EventType.RUN_ERROR, keys('message', 'code', 'usage')],\n [EventType.STEP_STARTED, keys('stepName')],\n [EventType.STEP_FINISHED, keys('stepName')],\n [EventType.REASONING_START, keys('messageId')],\n [EventType.REASONING_MESSAGE_START, keys('messageId', 'role')],\n [EventType.REASONING_MESSAGE_CONTENT, keys('messageId', 'delta')],\n [EventType.REASONING_MESSAGE_END, keys('messageId')],\n [EventType.REASONING_MESSAGE_CHUNK, keys('messageId', 'delta')],\n [EventType.REASONING_END, keys('messageId')],\n [\n EventType.REASONING_ENCRYPTED_VALUE,\n keys('subtype', 'entityId', 'encryptedValue'),\n ],\n [\n EventType.SUBAGENT_STARTED,\n keys(\n 'subagentRunId',\n 'name',\n 'description',\n 'parentSubagentRunId',\n 'parentToolCallId',\n 'parentMessageId',\n ),\n ],\n [EventType.SUBAGENT_FINISHED, keys('subagentRunId', 'result', 'outcome')],\n [EventType.SUBAGENT_ERROR, keys('subagentRunId', 'message', 'code')],\n])\n\nconst RUN_SCOPED = new Set<string>([\n EventType.RUN_STARTED,\n EventType.RUN_FINISHED,\n EventType.RUN_ERROR,\n EventType.MESSAGES_SNAPSHOT,\n])\n\nconst ATTRIBUTABLE_KEYS = new Map(\n [...SPEC_KEYS]\n .filter(([type]) => !RUN_SCOPED.has(type))\n .map(\n ([type, fields]) =>\n [type, new Set([...fields, 'subagentRunId'])] as const,\n ),\n)\n\nexport function specKeysFor(type: string): ReadonlySet<string> {\n return ATTRIBUTABLE_KEYS.get(type) ?? SPEC_KEYS.get(type) ?? SHARED\n}\n\nexport function isSpecTopLevelKey(type: string, key: string): boolean {\n return specKeysFor(type).has(key)\n}\n"],"mappings":"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"}