@assistant-ui/react-ag-ui 0.0.52 → 0.0.54

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 (31) hide show
  1. package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
  2. package/dist/runtime/AgUiThreadRuntimeCore.js +14 -4
  3. package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
  4. package/dist/runtime/adapter/conversions.d.ts +6 -0
  5. package/dist/runtime/adapter/conversions.d.ts.map +1 -1
  6. package/dist/runtime/adapter/conversions.js +139 -10
  7. package/dist/runtime/adapter/conversions.js.map +1 -1
  8. package/dist/runtime/adapter/run-aggregator.d.ts +10 -1
  9. package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
  10. package/dist/runtime/adapter/run-aggregator.js +36 -9
  11. package/dist/runtime/adapter/run-aggregator.js.map +1 -1
  12. package/dist/runtime/adapter/subscriber.d.ts +3 -0
  13. package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
  14. package/dist/runtime/adapter/subscriber.js +1 -0
  15. package/dist/runtime/adapter/subscriber.js.map +1 -1
  16. package/dist/runtime/event-parser.js +13 -0
  17. package/dist/runtime/event-parser.js.map +1 -1
  18. package/dist/runtime/types.d.ts +5 -0
  19. package/dist/runtime/types.d.ts.map +1 -1
  20. package/dist/useAgUiRuntime.js +4 -3
  21. package/dist/useAgUiRuntime.js.map +1 -1
  22. package/package.json +8 -8
  23. package/src/runtime/AgUiThreadRuntimeCore.ts +21 -1
  24. package/src/runtime/adapter/conversions.content.test.ts +220 -0
  25. package/src/runtime/adapter/conversions.ts +215 -11
  26. package/src/runtime/adapter/run-aggregator.ts +59 -4
  27. package/src/runtime/adapter/subscriber.ts +3 -0
  28. package/src/runtime/event-parser.ts +13 -0
  29. package/src/runtime/types.ts +6 -0
  30. package/src/useAgUiRuntime.queue.test.tsx +68 -1
  31. package/src/useAgUiRuntime.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"run-aggregator.js","names":[],"sources":["../../../src/runtime/adapter/run-aggregator.ts"],"sourcesContent":["\"use client\";\n\nimport {\n isMcpAppUri,\n type ChatModelRunResult,\n type MessageTiming,\n type ThreadAssistantMessagePart,\n type ToolCallMessagePart,\n type ToolModelContentPart,\n} from \"@assistant-ui/core\";\nimport {\n applyA2uiOperations,\n convertSurfaceToUISpec,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/react-generative-ui/a2ui\";\nimport { readMcpAppResourceUri } from \"../mcp-tool-result\";\nimport type { AgUiEvent, AgUiInterrupt } from \"../types\";\nimport type { Logger } from \"../logger\";\n\nexport const AG_UI_METADATA_NAMESPACE = \"agui\";\n\nexport type AgUiCustomMetadata = {\n interrupts?: AgUiInterrupt[];\n};\n\ntype Emit = (update: ChatModelRunResult) => void;\n\ntype ToolCallState = {\n toolCallId: string;\n toolCallName: string;\n argsText: string;\n parsedArgs: Record<string, unknown> | undefined;\n result: unknown;\n isError: boolean | undefined;\n parentMessageId?: string;\n toolMessageId?: string;\n mcpAppResourceUri?: string;\n mcpAppServerId?: string;\n modelContent?: ToolModelContentPart[];\n snapshotResultApplied: boolean;\n};\n\nexport const MCP_APPS_ACTIVITY_TYPE = \"mcp-apps\";\n\nexport const A2UI_SURFACE_ACTIVITY_TYPE = \"a2ui-surface\";\n\nexport const isPlainObject = (\n value: unknown,\n): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\nexport type RunAggregatorOptions = {\n showThinking: boolean;\n logger: Logger;\n emit: Emit;\n onServerMessageId?: (messageId: string) => void;\n};\n\n/**\n * Collects AG-UI events into assistant-ui run snapshots that can be yielded from a ChatModelAdapter.\n *\n * The aggregator keeps a single assistant message worth of parts. Each incoming event updates the parts and\n * emits a fresh snapshot through the provided `emit` callback.\n */\nexport class RunAggregator {\n private readonly emitUpdate: Emit;\n private readonly showThinking: boolean;\n private readonly logger: Logger;\n private readonly onServerMessageId: ((messageId: string) => void) | undefined;\n\n private status: ChatModelRunResult[\"status\"] | undefined;\n private interrupts: AgUiInterrupt[] | undefined;\n private readonly textParts = new Map<\n string,\n { buffer: string; touched: boolean }\n >();\n private activeTextMessageId: string | undefined;\n private readonly reasoningParts = new Map<string, string>(); // key → buffer\n private activeReasoningKey: string | undefined;\n private reasoningPartCounter = 0;\n private readonly toolCalls = new Map<string, ToolCallState>();\n private readonly a2uiBuckets = new Map<string, A2uiState>();\n private readonly a2uiToolCallIds = new Set<string>();\n private lastResolvedToolCallId: string | undefined;\n private readonly partOrder: (\n | { kind: \"text\"; key: string }\n | { kind: \"reasoning\"; key: string }\n | { kind: \"tool-call\"; toolCallId: string }\n )[] = [];\n private textPartCounter = 0;\n private serverMessageIdReported = false;\n\n private streamStartTime: number | undefined;\n private firstTokenTime: number | undefined;\n private totalChunks = 0;\n\n constructor(options: RunAggregatorOptions) {\n this.emitUpdate = options.emit;\n this.showThinking = options.showThinking;\n this.logger = options.logger;\n this.onServerMessageId = options.onServerMessageId;\n }\n\n hasToolCall(toolCallId: string): boolean {\n return this.toolCalls.has(toolCallId);\n }\n\n handle(event: AgUiEvent): void {\n switch (event.type) {\n case \"RUN_STARTED\": {\n this.clearTextParts();\n this.reasoningParts.clear();\n this.activeReasoningKey = undefined;\n this.reasoningPartCounter = 0;\n this.toolCalls.clear();\n this.a2uiBuckets.clear();\n this.a2uiToolCallIds.clear();\n this.lastResolvedToolCallId = undefined;\n this.partOrder.length = 0;\n this.textPartCounter = 0;\n this.activeTextMessageId = undefined;\n this.interrupts = undefined;\n this.serverMessageIdReported = false;\n this.streamStartTime = Date.now();\n this.firstTokenTime = undefined;\n this.totalChunks = 0;\n this.status = { type: \"running\" };\n this.emit();\n break;\n }\n case \"RUN_FINISHED\": {\n if (event.outcome?.type === \"interrupt\") {\n this.interrupts = event.outcome.interrupts;\n this.status = { type: \"requires-action\", reason: \"interrupt\" };\n this.emit();\n break;\n }\n\n this.interrupts = undefined;\n const hasUnresolvedToolCalls = Array.from(this.toolCalls.values()).some(\n (tc) => tc.result === undefined,\n );\n\n this.status =\n event.outcome?.type === \"success\" || !hasUnresolvedToolCalls\n ? { type: \"complete\", reason: \"unknown\" }\n : { type: \"requires-action\", reason: \"tool-calls\" };\n this.emit();\n break;\n }\n case \"RUN_ERROR\": {\n this.status = {\n type: \"incomplete\",\n reason: \"error\",\n ...(event.message !== undefined ? { error: event.message } : {}),\n };\n this.emit();\n break;\n }\n case \"RUN_CANCELLED\": {\n this.status = { type: \"incomplete\", reason: \"cancelled\" };\n this.emit();\n break;\n }\n\n case \"TEXT_MESSAGE_START\": {\n this.reportServerMessageId(event.messageId);\n const id = this.startTextMessage(event.messageId);\n if (id) {\n this.markTextPartTouched(id);\n }\n this.emit();\n break;\n }\n case \"TEXT_MESSAGE_CONTENT\":\n case \"TEXT_MESSAGE_CHUNK\": {\n const incomingId = \"messageId\" in event ? event.messageId : undefined;\n this.reportServerMessageId(incomingId);\n if (!event.delta) break;\n this.recordFirstToken();\n const id = this.resolveTextMessageId(incomingId);\n this.appendText(id, event.delta);\n this.totalChunks++;\n this.emit();\n break;\n }\n case \"TEXT_MESSAGE_END\": {\n this.reportServerMessageId(event.messageId);\n if (event.messageId && this.activeTextMessageId === event.messageId) {\n this.activeTextMessageId = undefined;\n }\n this.emit();\n break;\n }\n\n case \"THINKING_START\":\n case \"THINKING_TEXT_MESSAGE_START\":\n case \"REASONING_START\":\n case \"REASONING_MESSAGE_START\":\n this.handleReasoningStart(\n \"messageId\" in event ? event.messageId : undefined,\n );\n break;\n case \"THINKING_TEXT_MESSAGE_CONTENT\":\n this.handleReasoningContent(event.delta);\n this.totalChunks++;\n this.recordFirstToken();\n break;\n case \"REASONING_MESSAGE_CONTENT\":\n this.handleReasoningContent(\n event.delta,\n \"messageId\" in event ? event.messageId : undefined,\n );\n this.totalChunks++;\n this.recordFirstToken();\n break;\n case \"THINKING_TEXT_MESSAGE_END\":\n case \"THINKING_END\":\n case \"REASONING_MESSAGE_END\":\n case \"REASONING_END\":\n this.handleReasoningEnd();\n break;\n\n case \"TOOL_CALL_START\": {\n this.reportServerMessageId(event.parentMessageId);\n this.startToolCall(\n event.toolCallId,\n event.toolCallName,\n event.parentMessageId,\n );\n this.emit();\n break;\n }\n case \"TOOL_CALL_ARGS\":\n case \"TOOL_CALL_CHUNK\": {\n if (event.type === \"TOOL_CALL_CHUNK\") {\n this.reportServerMessageId(event.parentMessageId);\n }\n if (!event.delta) break;\n this.appendToolArgs(event.toolCallId, event.delta);\n this.emit();\n break;\n }\n case \"TOOL_CALL_END\": {\n this.emit();\n break;\n }\n case \"TOOL_CALL_RESULT\": {\n this.finishToolCall(\n event.toolCallId,\n event.content ?? \"\",\n typeof event.mcpResult?.isError === \"boolean\"\n ? event.mcpResult.isError\n : event.role === \"tool\"\n ? false\n : undefined,\n event.messageId,\n event.mcpResult,\n );\n this.emit();\n break;\n }\n case \"ACTIVITY_SNAPSHOT\": {\n if (event.activityType === A2UI_SURFACE_ACTIVITY_TYPE) {\n this.handleA2uiActivitySnapshot(event);\n break;\n }\n if (event.activityType !== MCP_APPS_ACTIVITY_TYPE) break;\n const toolCallId = event.content.toolCallId;\n const entry =\n typeof toolCallId === \"string\"\n ? this.toolCalls.get(toolCallId)\n : this.lastResolvedToolCallId\n ? this.toolCalls.get(this.lastResolvedToolCallId)\n : undefined;\n const resourceUri = event.content.resourceUri;\n if (\n entry &&\n typeof resourceUri === \"string\" &&\n isMcpAppUri(resourceUri)\n ) {\n entry.mcpAppResourceUri = resourceUri;\n const id = event.content.serverId;\n const hash = event.content.serverHash;\n if (typeof id === \"string\" && id.length > 0) {\n entry.mcpAppServerId = id;\n } else if (typeof hash === \"string\" && hash.length > 0) {\n entry.mcpAppServerId = hash;\n }\n const result = event.content.result;\n if (isPlainObject(result)) {\n if (\n entry.result !== undefined &&\n entry.modelContent === undefined\n ) {\n entry.modelContent = [\n {\n type: \"text\",\n text:\n typeof entry.result === \"string\"\n ? entry.result\n : JSON.stringify(entry.result),\n },\n ];\n }\n entry.result = result;\n entry.snapshotResultApplied = true;\n if (typeof result.isError === \"boolean\") {\n entry.isError = result.isError;\n }\n }\n this.emit();\n }\n break;\n }\n\n default: {\n this.logger.debug?.(\"[agui] aggregator ignored event\", event);\n }\n }\n }\n\n private handleA2uiActivitySnapshot(\n event: Extract<AgUiEvent, { type: \"ACTIVITY_SNAPSHOT\" }>,\n ): void {\n const operations = event.content[\"a2ui_operations\"];\n if (!Array.isArray(operations)) return;\n\n const messageId = event.messageId ?? \"a2ui:anonymous\";\n if (event.replace === false && this.a2uiBuckets.has(messageId)) return;\n\n const { state, warnings } = applyA2uiOperations(new Map(), operations);\n for (const warning of warnings) {\n this.logger.debug(\"[agui] a2ui operation warning\", warning);\n }\n this.a2uiBuckets.delete(messageId);\n this.a2uiBuckets.set(messageId, state);\n this.synthesizeA2uiToolCalls();\n this.emit();\n }\n\n private synthesizeA2uiToolCalls(): void {\n const surfaces = new Map<string, A2uiSurfaceState>();\n\n for (const bucket of this.a2uiBuckets.values()) {\n for (const [surfaceId, surface] of bucket) {\n surfaces.set(surfaceId, surface);\n }\n }\n\n const activeToolCallIds = new Set<string>();\n for (const [surfaceId, surface] of surfaces) {\n const toolCallId = `a2ui:${surfaceId}`;\n const { spec, warnings } = convertSurfaceToUISpec(surface);\n for (const warning of warnings) {\n this.logger.debug(\"[agui] a2ui surface conversion warning\", warning);\n }\n if (!spec) continue;\n\n activeToolCallIds.add(toolCallId);\n\n const entry: ToolCallState = {\n toolCallId,\n toolCallName: \"present\",\n argsText: JSON.stringify(spec),\n parsedArgs: spec,\n result: {},\n isError: undefined,\n snapshotResultApplied: false,\n };\n if (!this.toolCalls.has(toolCallId)) {\n this.partOrder.push({ kind: \"tool-call\", toolCallId });\n }\n this.toolCalls.set(toolCallId, entry);\n this.a2uiToolCallIds.add(toolCallId);\n }\n\n for (const toolCallId of this.a2uiToolCallIds) {\n if (activeToolCallIds.has(toolCallId)) continue;\n this.toolCalls.delete(toolCallId);\n const partIndex = this.partOrder.findIndex(\n (part) => part.kind === \"tool-call\" && part.toolCallId === toolCallId,\n );\n if (partIndex !== -1) this.partOrder.splice(partIndex, 1);\n this.a2uiToolCallIds.delete(toolCallId);\n }\n }\n\n private reportServerMessageId(messageId: string | undefined): void {\n if (this.serverMessageIdReported || !messageId) return;\n this.serverMessageIdReported = true;\n this.onServerMessageId?.(messageId);\n }\n\n private clearTextParts(): void {\n this.textParts.clear();\n }\n\n private generateTextKey(): string {\n this.textPartCounter += 1;\n return `text-${this.textPartCounter}`;\n }\n\n private startTextMessage(messageId?: string): string {\n const id = messageId ?? this.generateTextKey();\n this.ensureTextPart(id);\n this.activeTextMessageId = id;\n return id;\n }\n\n private resolveTextMessageId(messageId?: string): string {\n if (messageId) {\n this.ensureTextPart(messageId);\n this.activeTextMessageId = messageId;\n return messageId;\n }\n\n if (this.activeTextMessageId) {\n return this.activeTextMessageId;\n }\n\n const generated = this.generateTextKey();\n this.ensureTextPart(generated);\n this.activeTextMessageId = generated;\n return generated;\n }\n\n private ensureTextPart(id: string): void {\n if (!this.textParts.has(id)) {\n this.textParts.set(id, { buffer: \"\", touched: false });\n if (\n !this.partOrder.some((part) => part.kind === \"text\" && part.key === id)\n ) {\n this.partOrder.push({ kind: \"text\", key: id });\n }\n }\n }\n\n private markTextPartTouched(id: string): void {\n const entry = this.textParts.get(id);\n if (!entry) return;\n entry.touched = true;\n }\n\n private appendText(id: string, delta: string): void {\n this.ensureTextPart(id);\n const entry = this.textParts.get(id);\n if (!entry) return;\n entry.buffer += delta;\n entry.touched = true;\n }\n\n private startToolCall(\n id: string | undefined,\n name?: string,\n parentMessageId?: string,\n ) {\n if (!id) return;\n // A new tool call acts as a boundary: any anonymous text that arrives\n // after it should be a new part, not appended to the pre-tool text.\n this.activeTextMessageId = undefined;\n if (\n !this.partOrder.some(\n (part) => part.kind === \"tool-call\" && part.toolCallId === id,\n )\n ) {\n this.insertToolPart(id, parentMessageId);\n }\n const state: ToolCallState = {\n toolCallId: id,\n toolCallName: name ?? \"tool\",\n argsText: \"\",\n parsedArgs: undefined,\n result: undefined,\n isError: undefined,\n snapshotResultApplied: false,\n };\n if (parentMessageId) {\n state.parentMessageId = parentMessageId;\n }\n this.toolCalls.set(id, state);\n }\n\n // The message and tool-call channels are unordered on the wire, so anchor a\n // tool call under its parentMessageId text part instead of appending it.\n private insertToolPart(id: string, parentMessageId?: string) {\n const entry = { kind: \"tool-call\", toolCallId: id } as const;\n if (parentMessageId) {\n const parentIndex = this.partOrder.findIndex(\n (part) => part.kind === \"text\" && part.key === parentMessageId,\n );\n if (parentIndex !== -1) {\n let insertAt = parentIndex + 1;\n while (insertAt < this.partOrder.length) {\n const part = this.partOrder[insertAt];\n if (\n part?.kind === \"tool-call\" &&\n this.toolCalls.get(part.toolCallId)?.parentMessageId ===\n parentMessageId\n ) {\n insertAt += 1;\n continue;\n }\n break;\n }\n this.partOrder.splice(insertAt, 0, entry);\n return;\n }\n }\n this.partOrder.push(entry);\n }\n\n private appendToolArgs(id: string | undefined, delta: string) {\n const entry = id ? this.toolCalls.get(id) : undefined;\n if (!entry) return;\n entry.argsText += delta;\n try {\n const parsed = JSON.parse(entry.argsText);\n if (parsed && typeof parsed === \"object\") {\n entry.parsedArgs = parsed as Record<string, unknown>;\n } else {\n entry.parsedArgs = undefined;\n }\n } catch {\n entry.parsedArgs = undefined;\n }\n }\n\n private finishToolCall(\n id: string,\n content: string,\n isError?: boolean,\n toolMessageId?: string,\n mcpResult?: Record<string, unknown>,\n ) {\n if (!id) return;\n let entry = this.toolCalls.get(id);\n if (!entry) {\n entry = {\n toolCallId: id,\n toolCallName: \"tool\",\n argsText: \"\",\n parsedArgs: undefined,\n result: undefined,\n isError: undefined,\n snapshotResultApplied: false,\n };\n this.toolCalls.set(id, entry);\n }\n if (\n !this.partOrder.some(\n (part) => part.kind === \"tool-call\" && part.toolCallId === id,\n )\n ) {\n this.partOrder.push({ kind: \"tool-call\", toolCallId: id });\n }\n if (mcpResult !== undefined && !entry.snapshotResultApplied) {\n entry.result = mcpResult;\n entry.modelContent = [{ type: \"text\", text: content }];\n entry.snapshotResultApplied = true;\n entry.isError = isError;\n if (entry.mcpAppResourceUri === undefined) {\n const uri = readMcpAppResourceUri(mcpResult._meta);\n if (uri !== undefined) entry.mcpAppResourceUri = uri;\n }\n } else if (entry.snapshotResultApplied) {\n if (entry.modelContent === undefined) {\n entry.modelContent = [{ type: \"text\", text: content }];\n }\n if (entry.isError === undefined) {\n entry.isError = isError;\n }\n } else {\n entry.result = tryParseJSON(content);\n entry.isError = isError;\n }\n if (toolMessageId) {\n entry.toolMessageId = toolMessageId;\n }\n this.lastResolvedToolCallId = id;\n }\n\n private emit(): void {\n const snapshot: ThreadAssistantMessagePart[] = [];\n\n for (const part of this.partOrder) {\n if (part.kind === \"reasoning\") {\n if (this.showThinking) {\n const buffer = this.reasoningParts.get(part.key) ?? \"\";\n if (buffer.length > 0 || this.activeReasoningKey === part.key) {\n snapshot.push({ type: \"reasoning\", text: buffer } as const);\n }\n }\n continue;\n }\n\n if (part.kind === \"text\") {\n const entry = this.textParts.get(part.key);\n if (entry?.touched) {\n snapshot.push({ type: \"text\", text: entry.buffer } as const);\n }\n continue;\n }\n\n const entry = this.toolCalls.get(part.toolCallId);\n if (!entry) continue;\n const toolPart: ToolCallMessagePart = {\n type: \"tool-call\",\n toolCallId: entry.toolCallId,\n toolName: entry.toolCallName,\n args: (entry.parsedArgs ?? {}) as any,\n argsText: entry.argsText,\n ...(entry.result !== undefined ? { result: entry.result } : {}),\n ...(entry.modelContent !== undefined\n ? { modelContent: entry.modelContent }\n : {}),\n ...(entry.isError !== undefined ? { isError: entry.isError } : {}),\n ...(entry.mcpAppResourceUri\n ? {\n mcp: {\n app: {\n resourceUri: entry.mcpAppResourceUri,\n ...(entry.mcpAppServerId\n ? { serverId: entry.mcpAppServerId }\n : {}),\n },\n },\n }\n : {}),\n ...(entry.parentMessageId ? { parentId: entry.parentMessageId } : {}),\n ...(entry.toolMessageId\n ? { unstable_toolMessageId: entry.toolMessageId }\n : {}),\n } as ToolCallMessagePart & { unstable_toolMessageId?: string };\n snapshot.push(toolPart);\n }\n\n const timing = this.getTiming();\n const metadata = {\n ...(timing ? { timing } : {}),\n ...(this.interrupts\n ? {\n custom: {\n [AG_UI_METADATA_NAMESPACE]: {\n interrupts: this.interrupts,\n } satisfies AgUiCustomMetadata,\n },\n }\n : {}),\n };\n const result: ChatModelRunResult = {\n content: snapshot,\n ...(this.status ? { status: this.status } : undefined),\n ...(Object.keys(metadata).length > 0 ? { metadata } : undefined),\n };\n this.emitUpdate(result);\n }\n\n private recordFirstToken(): void {\n if (\n this.firstTokenTime === undefined &&\n this.streamStartTime !== undefined\n ) {\n this.firstTokenTime = Date.now() - this.streamStartTime;\n }\n }\n\n private getTiming(): MessageTiming | undefined {\n if (this.streamStartTime === undefined) return undefined;\n\n const now = Date.now();\n const totalStreamTime = now - this.streamStartTime;\n const tokenCount =\n this.totalChunks > 0\n ? Math.ceil(\n Array.from(this.textParts.values()).reduce(\n (sum, p) => sum + p.buffer.length,\n 0,\n ) / 4,\n )\n : undefined;\n const tokensPerSecond =\n tokenCount && totalStreamTime > 0\n ? (tokenCount / totalStreamTime) * 1000\n : undefined;\n\n return {\n streamStartTime: this.streamStartTime,\n ...(this.firstTokenTime !== undefined\n ? { firstTokenTime: this.firstTokenTime }\n : {}),\n totalStreamTime,\n ...(tokenCount !== undefined ? { tokenCount } : {}),\n ...(tokensPerSecond !== undefined ? { tokensPerSecond } : {}),\n totalChunks: this.totalChunks,\n toolCallCount: this.toolCalls.size,\n };\n }\n\n private handleReasoningStart(messageId?: string): void {\n if (!this.showThinking) return;\n // A reasoning block acts as a boundary: anonymous text arriving after it\n // should be a new part, not appended to any pre-reasoning text.\n this.activeTextMessageId = undefined;\n const key = messageId ?? `__auto-reasoning-${++this.reasoningPartCounter}`;\n if (!this.reasoningParts.has(key)) {\n this.reasoningParts.set(key, \"\");\n this.partOrder.push({ kind: \"reasoning\", key });\n }\n this.activeReasoningKey = key;\n this.emit();\n }\n\n private handleReasoningContent(delta: string, messageId?: string): void {\n if (!this.showThinking || !delta) return;\n if (!this.activeReasoningKey) {\n // Content arrived without a preceding START — create the slot lazily.\n this.handleReasoningStart(messageId);\n }\n const key = this.activeReasoningKey;\n if (!key) return;\n this.reasoningParts.set(key, (this.reasoningParts.get(key) ?? \"\") + delta);\n this.emit();\n }\n\n private handleReasoningEnd(): void {\n if (!this.showThinking) return;\n this.activeReasoningKey = undefined;\n this.emit();\n }\n}\n\nexport function tryParseJSON(value: string): unknown {\n if (!value) return value;\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-aggregator.js","names":[],"sources":["../../../src/runtime/adapter/run-aggregator.ts"],"sourcesContent":["\"use client\";\n\nimport {\n isMcpAppUri,\n type ChatModelRunResult,\n type MessageTiming,\n type ThreadAssistantMessagePart,\n type ToolCallMessagePart,\n type ToolModelContentPart,\n} from \"@assistant-ui/core\";\nimport {\n applyA2uiOperations,\n convertSurfaceToUISpec,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/react-generative-ui/a2ui\";\nimport { readMcpAppResourceUri } from \"../mcp-tool-result\";\nimport type { AgUiEvent, AgUiInterrupt } from \"../types\";\nimport type { Logger } from \"../logger\";\n\nexport const AG_UI_METADATA_NAMESPACE = \"agui\";\n\nexport type AgUiOpaqueReasoning = {\n id: string;\n encryptedValue: string;\n after?: boolean;\n};\n\nexport type AgUiCustomMetadata = {\n interrupts?: AgUiInterrupt[];\n opaqueReasoning?: AgUiOpaqueReasoning[];\n};\n\ntype Emit = (update: ChatModelRunResult) => void;\n\ntype ToolCallState = {\n toolCallId: string;\n toolCallName: string;\n argsText: string;\n parsedArgs: Record<string, unknown> | undefined;\n result: unknown;\n isError: boolean | undefined;\n parentMessageId?: string;\n toolMessageId?: string;\n mcpAppResourceUri?: string;\n mcpAppServerId?: string;\n modelContent?: ToolModelContentPart[];\n snapshotResultApplied: boolean;\n};\n\nexport const MCP_APPS_ACTIVITY_TYPE = \"mcp-apps\";\n\nexport const A2UI_SURFACE_ACTIVITY_TYPE = \"a2ui-surface\";\n\nexport const isPlainObject = (\n value: unknown,\n): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\nexport type RunAggregatorOptions = {\n showThinking: boolean;\n logger: Logger;\n emit: Emit;\n onServerMessageId?: (messageId: string) => void;\n};\n\n/**\n * Collects AG-UI events into assistant-ui run snapshots that can be yielded from a ChatModelAdapter.\n *\n * The aggregator keeps a single assistant message worth of parts. Each incoming event updates the parts and\n * emits a fresh snapshot through the provided `emit` callback.\n */\nexport class RunAggregator {\n private readonly emitUpdate: Emit;\n private readonly showThinking: boolean;\n private readonly logger: Logger;\n private readonly onServerMessageId: ((messageId: string) => void) | undefined;\n\n private status: ChatModelRunResult[\"status\"] | undefined;\n private interrupts: AgUiInterrupt[] | undefined;\n private readonly textParts = new Map<\n string,\n { buffer: string; touched: boolean }\n >();\n private activeTextMessageId: string | undefined;\n private readonly reasoningParts = new Map<string, string>(); // key → buffer\n private readonly reasoningSignatures = new Map<string, string>();\n private readonly reasoningMessageIds = new Map<string, string>();\n private readonly anonymousReasoningKeys = new Set<string>();\n private activeReasoningKey: string | undefined;\n private reasoningPartCounter = 0;\n private readonly toolCalls = new Map<string, ToolCallState>();\n private readonly a2uiBuckets = new Map<string, A2uiState>();\n private readonly a2uiToolCallIds = new Set<string>();\n private lastResolvedToolCallId: string | undefined;\n private readonly partOrder: (\n | { kind: \"text\"; key: string }\n | { kind: \"reasoning\"; key: string }\n | { kind: \"tool-call\"; toolCallId: string }\n )[] = [];\n private textPartCounter = 0;\n private serverMessageIdReported = false;\n\n private streamStartTime: number | undefined;\n private firstTokenTime: number | undefined;\n private totalChunks = 0;\n\n constructor(options: RunAggregatorOptions) {\n this.emitUpdate = options.emit;\n this.showThinking = options.showThinking;\n this.logger = options.logger;\n this.onServerMessageId = options.onServerMessageId;\n }\n\n hasToolCall(toolCallId: string): boolean {\n return this.toolCalls.has(toolCallId);\n }\n\n handle(event: AgUiEvent): void {\n switch (event.type) {\n case \"RUN_STARTED\": {\n this.clearTextParts();\n this.reasoningParts.clear();\n this.reasoningSignatures.clear();\n this.reasoningMessageIds.clear();\n this.anonymousReasoningKeys.clear();\n this.activeReasoningKey = undefined;\n this.reasoningPartCounter = 0;\n this.toolCalls.clear();\n this.a2uiBuckets.clear();\n this.a2uiToolCallIds.clear();\n this.lastResolvedToolCallId = undefined;\n this.partOrder.length = 0;\n this.textPartCounter = 0;\n this.activeTextMessageId = undefined;\n this.interrupts = undefined;\n this.serverMessageIdReported = false;\n this.streamStartTime = Date.now();\n this.firstTokenTime = undefined;\n this.totalChunks = 0;\n this.status = { type: \"running\" };\n this.emit();\n break;\n }\n case \"RUN_FINISHED\": {\n if (event.outcome?.type === \"interrupt\") {\n this.interrupts = event.outcome.interrupts;\n this.status = { type: \"requires-action\", reason: \"interrupt\" };\n this.emit();\n break;\n }\n\n this.interrupts = undefined;\n const hasUnresolvedToolCalls = Array.from(this.toolCalls.values()).some(\n (tc) => tc.result === undefined,\n );\n\n this.status =\n event.outcome?.type === \"success\" || !hasUnresolvedToolCalls\n ? { type: \"complete\", reason: \"unknown\" }\n : { type: \"requires-action\", reason: \"tool-calls\" };\n this.emit();\n break;\n }\n case \"RUN_ERROR\": {\n this.status = {\n type: \"incomplete\",\n reason: \"error\",\n ...(event.message !== undefined ? { error: event.message } : {}),\n };\n this.emit();\n break;\n }\n case \"RUN_CANCELLED\": {\n this.status = { type: \"incomplete\", reason: \"cancelled\" };\n this.emit();\n break;\n }\n\n case \"TEXT_MESSAGE_START\": {\n this.reportServerMessageId(event.messageId);\n const id = this.startTextMessage(event.messageId);\n if (id) {\n this.markTextPartTouched(id);\n }\n this.emit();\n break;\n }\n case \"TEXT_MESSAGE_CONTENT\":\n case \"TEXT_MESSAGE_CHUNK\": {\n const incomingId = \"messageId\" in event ? event.messageId : undefined;\n this.reportServerMessageId(incomingId);\n if (!event.delta) break;\n this.recordFirstToken();\n const id = this.resolveTextMessageId(incomingId);\n this.appendText(id, event.delta);\n this.totalChunks++;\n this.emit();\n break;\n }\n case \"TEXT_MESSAGE_END\": {\n this.reportServerMessageId(event.messageId);\n if (event.messageId && this.activeTextMessageId === event.messageId) {\n this.activeTextMessageId = undefined;\n }\n this.emit();\n break;\n }\n\n case \"THINKING_START\":\n case \"THINKING_TEXT_MESSAGE_START\":\n case \"REASONING_START\":\n case \"REASONING_MESSAGE_START\":\n this.handleReasoningStart(\n \"messageId\" in event ? event.messageId : undefined,\n event.type === \"REASONING_MESSAGE_START\",\n );\n break;\n case \"REASONING_ENCRYPTED_VALUE\":\n if (event.subtype === \"message\") {\n // entityId names any message, not necessarily a reasoning one, so an\n // unmatched id may only claim a block that has no id to contradict it.\n const active = this.activeReasoningKey;\n const key = this.reasoningParts.has(event.entityId)\n ? event.entityId\n : active !== undefined && this.anonymousReasoningKeys.has(active)\n ? active\n : undefined;\n if (key !== undefined) {\n this.reasoningSignatures.set(key, event.encryptedValue);\n this.emit();\n }\n }\n break;\n case \"THINKING_TEXT_MESSAGE_CONTENT\":\n this.handleReasoningContent(event.delta);\n this.totalChunks++;\n this.recordFirstToken();\n break;\n case \"REASONING_MESSAGE_CONTENT\":\n this.handleReasoningContent(\n event.delta,\n \"messageId\" in event ? event.messageId : undefined,\n true,\n );\n this.totalChunks++;\n this.recordFirstToken();\n break;\n case \"THINKING_TEXT_MESSAGE_END\":\n case \"THINKING_END\":\n case \"REASONING_MESSAGE_END\":\n case \"REASONING_END\":\n this.handleReasoningEnd();\n break;\n\n case \"TOOL_CALL_START\": {\n this.reportServerMessageId(event.parentMessageId);\n this.startToolCall(\n event.toolCallId,\n event.toolCallName,\n event.parentMessageId,\n );\n this.emit();\n break;\n }\n case \"TOOL_CALL_ARGS\":\n case \"TOOL_CALL_CHUNK\": {\n if (event.type === \"TOOL_CALL_CHUNK\") {\n this.reportServerMessageId(event.parentMessageId);\n }\n if (!event.delta) break;\n this.appendToolArgs(event.toolCallId, event.delta);\n this.emit();\n break;\n }\n case \"TOOL_CALL_END\": {\n this.emit();\n break;\n }\n case \"TOOL_CALL_RESULT\": {\n this.finishToolCall(\n event.toolCallId,\n event.content ?? \"\",\n typeof event.mcpResult?.isError === \"boolean\"\n ? event.mcpResult.isError\n : event.role === \"tool\"\n ? false\n : undefined,\n event.messageId,\n event.mcpResult,\n );\n this.emit();\n break;\n }\n case \"ACTIVITY_SNAPSHOT\": {\n if (event.activityType === A2UI_SURFACE_ACTIVITY_TYPE) {\n this.handleA2uiActivitySnapshot(event);\n break;\n }\n if (event.activityType !== MCP_APPS_ACTIVITY_TYPE) break;\n const toolCallId = event.content.toolCallId;\n const entry =\n typeof toolCallId === \"string\"\n ? this.toolCalls.get(toolCallId)\n : this.lastResolvedToolCallId\n ? this.toolCalls.get(this.lastResolvedToolCallId)\n : undefined;\n const resourceUri = event.content.resourceUri;\n if (\n entry &&\n typeof resourceUri === \"string\" &&\n isMcpAppUri(resourceUri)\n ) {\n entry.mcpAppResourceUri = resourceUri;\n const id = event.content.serverId;\n const hash = event.content.serverHash;\n if (typeof id === \"string\" && id.length > 0) {\n entry.mcpAppServerId = id;\n } else if (typeof hash === \"string\" && hash.length > 0) {\n entry.mcpAppServerId = hash;\n }\n const result = event.content.result;\n if (isPlainObject(result)) {\n if (\n entry.result !== undefined &&\n entry.modelContent === undefined\n ) {\n entry.modelContent = [\n {\n type: \"text\",\n text:\n typeof entry.result === \"string\"\n ? entry.result\n : JSON.stringify(entry.result),\n },\n ];\n }\n entry.result = result;\n entry.snapshotResultApplied = true;\n if (typeof result.isError === \"boolean\") {\n entry.isError = result.isError;\n }\n }\n this.emit();\n }\n break;\n }\n\n default: {\n this.logger.debug?.(\"[agui] aggregator ignored event\", event);\n }\n }\n }\n\n private handleA2uiActivitySnapshot(\n event: Extract<AgUiEvent, { type: \"ACTIVITY_SNAPSHOT\" }>,\n ): void {\n const operations = event.content[\"a2ui_operations\"];\n if (!Array.isArray(operations)) return;\n\n const messageId = event.messageId ?? \"a2ui:anonymous\";\n if (event.replace === false && this.a2uiBuckets.has(messageId)) return;\n\n const { state, warnings } = applyA2uiOperations(new Map(), operations);\n for (const warning of warnings) {\n this.logger.debug(\"[agui] a2ui operation warning\", warning);\n }\n this.a2uiBuckets.delete(messageId);\n this.a2uiBuckets.set(messageId, state);\n this.synthesizeA2uiToolCalls();\n this.emit();\n }\n\n private synthesizeA2uiToolCalls(): void {\n const surfaces = new Map<string, A2uiSurfaceState>();\n\n for (const bucket of this.a2uiBuckets.values()) {\n for (const [surfaceId, surface] of bucket) {\n surfaces.set(surfaceId, surface);\n }\n }\n\n const activeToolCallIds = new Set<string>();\n for (const [surfaceId, surface] of surfaces) {\n const toolCallId = `a2ui:${surfaceId}`;\n const { spec, warnings } = convertSurfaceToUISpec(surface);\n for (const warning of warnings) {\n this.logger.debug(\"[agui] a2ui surface conversion warning\", warning);\n }\n if (!spec) continue;\n\n activeToolCallIds.add(toolCallId);\n\n const entry: ToolCallState = {\n toolCallId,\n toolCallName: \"present\",\n argsText: JSON.stringify(spec),\n parsedArgs: spec,\n result: {},\n isError: undefined,\n snapshotResultApplied: false,\n };\n if (!this.toolCalls.has(toolCallId)) {\n this.partOrder.push({ kind: \"tool-call\", toolCallId });\n }\n this.toolCalls.set(toolCallId, entry);\n this.a2uiToolCallIds.add(toolCallId);\n }\n\n for (const toolCallId of this.a2uiToolCallIds) {\n if (activeToolCallIds.has(toolCallId)) continue;\n this.toolCalls.delete(toolCallId);\n const partIndex = this.partOrder.findIndex(\n (part) => part.kind === \"tool-call\" && part.toolCallId === toolCallId,\n );\n if (partIndex !== -1) this.partOrder.splice(partIndex, 1);\n this.a2uiToolCallIds.delete(toolCallId);\n }\n }\n\n private reportServerMessageId(messageId: string | undefined): void {\n if (this.serverMessageIdReported || !messageId) return;\n this.serverMessageIdReported = true;\n this.onServerMessageId?.(messageId);\n }\n\n private clearTextParts(): void {\n this.textParts.clear();\n }\n\n private generateTextKey(): string {\n this.textPartCounter += 1;\n return `text-${this.textPartCounter}`;\n }\n\n private startTextMessage(messageId?: string): string {\n const id = messageId ?? this.generateTextKey();\n this.ensureTextPart(id);\n this.activeTextMessageId = id;\n return id;\n }\n\n private resolveTextMessageId(messageId?: string): string {\n if (messageId) {\n this.ensureTextPart(messageId);\n this.activeTextMessageId = messageId;\n return messageId;\n }\n\n if (this.activeTextMessageId) {\n return this.activeTextMessageId;\n }\n\n const generated = this.generateTextKey();\n this.ensureTextPart(generated);\n this.activeTextMessageId = generated;\n return generated;\n }\n\n private ensureTextPart(id: string): void {\n if (!this.textParts.has(id)) {\n this.textParts.set(id, { buffer: \"\", touched: false });\n if (\n !this.partOrder.some((part) => part.kind === \"text\" && part.key === id)\n ) {\n this.partOrder.push({ kind: \"text\", key: id });\n }\n }\n }\n\n private markTextPartTouched(id: string): void {\n const entry = this.textParts.get(id);\n if (!entry) return;\n entry.touched = true;\n }\n\n private appendText(id: string, delta: string): void {\n this.ensureTextPart(id);\n const entry = this.textParts.get(id);\n if (!entry) return;\n entry.buffer += delta;\n entry.touched = true;\n }\n\n private startToolCall(\n id: string | undefined,\n name?: string,\n parentMessageId?: string,\n ) {\n if (!id) return;\n // A new tool call acts as a boundary: any anonymous text that arrives\n // after it should be a new part, not appended to the pre-tool text.\n this.activeTextMessageId = undefined;\n if (\n !this.partOrder.some(\n (part) => part.kind === \"tool-call\" && part.toolCallId === id,\n )\n ) {\n this.insertToolPart(id, parentMessageId);\n }\n const state: ToolCallState = {\n toolCallId: id,\n toolCallName: name ?? \"tool\",\n argsText: \"\",\n parsedArgs: undefined,\n result: undefined,\n isError: undefined,\n snapshotResultApplied: false,\n };\n if (parentMessageId) {\n state.parentMessageId = parentMessageId;\n }\n this.toolCalls.set(id, state);\n }\n\n // The message and tool-call channels are unordered on the wire, so anchor a\n // tool call under its parentMessageId text part instead of appending it.\n private insertToolPart(id: string, parentMessageId?: string) {\n const entry = { kind: \"tool-call\", toolCallId: id } as const;\n if (parentMessageId) {\n const parentIndex = this.partOrder.findIndex(\n (part) => part.kind === \"text\" && part.key === parentMessageId,\n );\n if (parentIndex !== -1) {\n let insertAt = parentIndex + 1;\n while (insertAt < this.partOrder.length) {\n const part = this.partOrder[insertAt];\n if (\n part?.kind === \"tool-call\" &&\n this.toolCalls.get(part.toolCallId)?.parentMessageId ===\n parentMessageId\n ) {\n insertAt += 1;\n continue;\n }\n break;\n }\n this.partOrder.splice(insertAt, 0, entry);\n return;\n }\n }\n this.partOrder.push(entry);\n }\n\n private appendToolArgs(id: string | undefined, delta: string) {\n const entry = id ? this.toolCalls.get(id) : undefined;\n if (!entry) return;\n entry.argsText += delta;\n try {\n const parsed = JSON.parse(entry.argsText);\n if (parsed && typeof parsed === \"object\") {\n entry.parsedArgs = parsed as Record<string, unknown>;\n } else {\n entry.parsedArgs = undefined;\n }\n } catch {\n entry.parsedArgs = undefined;\n }\n }\n\n private finishToolCall(\n id: string,\n content: string,\n isError?: boolean,\n toolMessageId?: string,\n mcpResult?: Record<string, unknown>,\n ) {\n if (!id) return;\n let entry = this.toolCalls.get(id);\n if (!entry) {\n entry = {\n toolCallId: id,\n toolCallName: \"tool\",\n argsText: \"\",\n parsedArgs: undefined,\n result: undefined,\n isError: undefined,\n snapshotResultApplied: false,\n };\n this.toolCalls.set(id, entry);\n }\n if (\n !this.partOrder.some(\n (part) => part.kind === \"tool-call\" && part.toolCallId === id,\n )\n ) {\n this.partOrder.push({ kind: \"tool-call\", toolCallId: id });\n }\n if (mcpResult !== undefined && !entry.snapshotResultApplied) {\n entry.result = mcpResult;\n entry.modelContent = [{ type: \"text\", text: content }];\n entry.snapshotResultApplied = true;\n entry.isError = isError;\n if (entry.mcpAppResourceUri === undefined) {\n const uri = readMcpAppResourceUri(mcpResult._meta);\n if (uri !== undefined) entry.mcpAppResourceUri = uri;\n }\n } else if (entry.snapshotResultApplied) {\n if (entry.modelContent === undefined) {\n entry.modelContent = [{ type: \"text\", text: content }];\n }\n if (entry.isError === undefined) {\n entry.isError = isError;\n }\n } else {\n entry.result = tryParseJSON(content);\n entry.isError = isError;\n }\n if (toolMessageId) {\n entry.toolMessageId = toolMessageId;\n }\n this.lastResolvedToolCallId = id;\n }\n\n private emit(): void {\n const snapshot: ThreadAssistantMessagePart[] = [];\n\n for (const part of this.partOrder) {\n if (part.kind === \"reasoning\") {\n if (this.showThinking) {\n const buffer = this.reasoningParts.get(part.key) ?? \"\";\n if (buffer.length > 0 || this.activeReasoningKey === part.key) {\n const encryptedValue = this.reasoningSignatures.get(part.key);\n const reasoningId = this.reasoningMessageIds.get(part.key);\n const meta = {\n ...(reasoningId !== undefined ? { reasoningId } : {}),\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n };\n snapshot.push({\n type: \"reasoning\",\n text: buffer,\n ...(Object.keys(meta).length > 0\n ? { providerMetadata: { [AG_UI_METADATA_NAMESPACE]: meta } }\n : {}),\n } as const);\n }\n }\n continue;\n }\n\n if (part.kind === \"text\") {\n const entry = this.textParts.get(part.key);\n if (entry?.touched) {\n snapshot.push({ type: \"text\", text: entry.buffer } as const);\n }\n continue;\n }\n\n const entry = this.toolCalls.get(part.toolCallId);\n if (!entry) continue;\n const toolPart: ToolCallMessagePart = {\n type: \"tool-call\",\n toolCallId: entry.toolCallId,\n toolName: entry.toolCallName,\n args: (entry.parsedArgs ?? {}) as any,\n argsText: entry.argsText,\n ...(entry.result !== undefined ? { result: entry.result } : {}),\n ...(entry.modelContent !== undefined\n ? { modelContent: entry.modelContent }\n : {}),\n ...(entry.isError !== undefined ? { isError: entry.isError } : {}),\n ...(entry.mcpAppResourceUri\n ? {\n mcp: {\n app: {\n resourceUri: entry.mcpAppResourceUri,\n ...(entry.mcpAppServerId\n ? { serverId: entry.mcpAppServerId }\n : {}),\n },\n },\n }\n : {}),\n ...(entry.parentMessageId ? { parentId: entry.parentMessageId } : {}),\n ...(entry.toolMessageId\n ? { unstable_toolMessageId: entry.toolMessageId }\n : {}),\n } as ToolCallMessagePart & { unstable_toolMessageId?: string };\n snapshot.push(toolPart);\n }\n\n const timing = this.getTiming();\n const metadata = {\n ...(timing ? { timing } : {}),\n ...(this.interrupts\n ? {\n custom: {\n [AG_UI_METADATA_NAMESPACE]: {\n interrupts: this.interrupts,\n } satisfies AgUiCustomMetadata,\n },\n }\n : {}),\n };\n const result: ChatModelRunResult = {\n content: snapshot,\n ...(this.status ? { status: this.status } : undefined),\n ...(Object.keys(metadata).length > 0 ? { metadata } : undefined),\n };\n this.emitUpdate(result);\n }\n\n private recordFirstToken(): void {\n if (\n this.firstTokenTime === undefined &&\n this.streamStartTime !== undefined\n ) {\n this.firstTokenTime = Date.now() - this.streamStartTime;\n }\n }\n\n private getTiming(): MessageTiming | undefined {\n if (this.streamStartTime === undefined) return undefined;\n\n const now = Date.now();\n const totalStreamTime = now - this.streamStartTime;\n const tokenCount =\n this.totalChunks > 0\n ? Math.ceil(\n Array.from(this.textParts.values()).reduce(\n (sum, p) => sum + p.buffer.length,\n 0,\n ) / 4,\n )\n : undefined;\n const tokensPerSecond =\n tokenCount && totalStreamTime > 0\n ? (tokenCount / totalStreamTime) * 1000\n : undefined;\n\n return {\n streamStartTime: this.streamStartTime,\n ...(this.firstTokenTime !== undefined\n ? { firstTokenTime: this.firstTokenTime }\n : {}),\n totalStreamTime,\n ...(tokenCount !== undefined ? { tokenCount } : {}),\n ...(tokensPerSecond !== undefined ? { tokensPerSecond } : {}),\n totalChunks: this.totalChunks,\n toolCallCount: this.toolCalls.size,\n };\n }\n\n private handleReasoningStart(messageId?: string, isMessageId = false): void {\n if (!this.showThinking) return;\n // A reasoning block acts as a boundary: anonymous text arriving after it\n // should be a new part, not appended to any pre-reasoning text.\n this.activeTextMessageId = undefined;\n const key = messageId ?? `__auto-reasoning-${++this.reasoningPartCounter}`;\n // Two different questions: which id may be replayed as a ReasoningMessage.id\n // (only the message-scoped aliases carry one), and which block an unmatched\n // signature may claim (any block opened without an id at all).\n if (messageId === undefined) {\n this.anonymousReasoningKeys.add(key);\n } else if (isMessageId) {\n this.reasoningMessageIds.set(key, messageId);\n }\n if (!this.reasoningParts.has(key)) {\n this.reasoningParts.set(key, \"\");\n this.partOrder.push({ kind: \"reasoning\", key });\n }\n this.activeReasoningKey = key;\n this.emit();\n }\n\n private handleReasoningContent(\n delta: string,\n messageId?: string,\n isMessageId = false,\n ): void {\n if (!this.showThinking || !delta) return;\n if (!this.activeReasoningKey) {\n // Content arrived without a preceding START — create the slot lazily.\n this.handleReasoningStart(messageId, isMessageId);\n }\n const key = this.activeReasoningKey;\n if (!key) return;\n this.reasoningParts.set(key, (this.reasoningParts.get(key) ?? \"\") + delta);\n this.emit();\n }\n\n private handleReasoningEnd(): void {\n if (!this.showThinking) return;\n this.activeReasoningKey = undefined;\n this.emit();\n }\n}\n\nexport function tryParseJSON(value: string): unknown {\n if (!value) return value;\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n"],"mappings":";;;;;AAoBA,MAAa,2BAA2B;AA8BxC,MAAa,yBAAyB;AAEtC,MAAa,6BAA6B;AAE1C,MAAa,iBACX,UAEA,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;;;;;;;AAe9D,IAAa,gBAAb,MAA2B;CACzB;CACA;CACA;CACA;CAEA;CACA;CACA,4BAA6B,IAAI,IAG/B;CACF;CACA,iCAAkC,IAAI,IAAoB;CAC1D,sCAAuC,IAAI,IAAoB;CAC/D,sCAAuC,IAAI,IAAoB;CAC/D,yCAA0C,IAAI,IAAY;CAC1D;CACA,uBAA+B;CAC/B,4BAA6B,IAAI,IAA2B;CAC5D,8BAA+B,IAAI,IAAuB;CAC1D,kCAAmC,IAAI,IAAY;CACnD;CACA,YAIM,CAAC;CACP,kBAA0B;CAC1B,0BAAkC;CAElC;CACA;CACA,cAAsB;CAEtB,YAAY,SAA+B;EACzC,KAAK,aAAa,QAAQ;EAC1B,KAAK,eAAe,QAAQ;EAC5B,KAAK,SAAS,QAAQ;EACtB,KAAK,oBAAoB,QAAQ;CACnC;CAEA,YAAY,YAA6B;EACvC,OAAO,KAAK,UAAU,IAAI,UAAU;CACtC;CAEA,OAAO,OAAwB;EAC7B,QAAQ,MAAM,MAAd;GACE,KAAK;IACH,KAAK,eAAe;IACpB,KAAK,eAAe,MAAM;IAC1B,KAAK,oBAAoB,MAAM;IAC/B,KAAK,oBAAoB,MAAM;IAC/B,KAAK,uBAAuB,MAAM;IAClC,KAAK,qBAAqB,KAAA;IAC1B,KAAK,uBAAuB;IAC5B,KAAK,UAAU,MAAM;IACrB,KAAK,YAAY,MAAM;IACvB,KAAK,gBAAgB,MAAM;IAC3B,KAAK,yBAAyB,KAAA;IAC9B,KAAK,UAAU,SAAS;IACxB,KAAK,kBAAkB;IACvB,KAAK,sBAAsB,KAAA;IAC3B,KAAK,aAAa,KAAA;IAClB,KAAK,0BAA0B;IAC/B,KAAK,kBAAkB,KAAK,IAAI;IAChC,KAAK,iBAAiB,KAAA;IACtB,KAAK,cAAc;IACnB,KAAK,SAAS,EAAE,MAAM,UAAU;IAChC,KAAK,KAAK;IACV;GAEF,KAAK,gBAAgB;IACnB,IAAI,MAAM,SAAS,SAAS,aAAa;KACvC,KAAK,aAAa,MAAM,QAAQ;KAChC,KAAK,SAAS;MAAE,MAAM;MAAmB,QAAQ;KAAY;KAC7D,KAAK,KAAK;KACV;IACF;IAEA,KAAK,aAAa,KAAA;IAClB,MAAM,yBAAyB,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,MAChE,OAAO,GAAG,WAAW,KAAA,CACxB;IAEA,KAAK,SACH,MAAM,SAAS,SAAS,aAAa,CAAC,yBAClC;KAAE,MAAM;KAAY,QAAQ;IAAU,IACtC;KAAE,MAAM;KAAmB,QAAQ;IAAa;IACtD,KAAK,KAAK;IACV;GACF;GACA,KAAK;IACH,KAAK,SAAS;KACZ,MAAM;KACN,QAAQ;KACR,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,OAAO,MAAM,QAAQ,IAAI,CAAC;IAChE;IACA,KAAK,KAAK;IACV;GAEF,KAAK;IACH,KAAK,SAAS;KAAE,MAAM;KAAc,QAAQ;IAAY;IACxD,KAAK,KAAK;IACV;GAGF,KAAK,sBAAsB;IACzB,KAAK,sBAAsB,MAAM,SAAS;IAC1C,MAAM,KAAK,KAAK,iBAAiB,MAAM,SAAS;IAChD,IAAI,IACF,KAAK,oBAAoB,EAAE;IAE7B,KAAK,KAAK;IACV;GACF;GACA,KAAK;GACL,KAAK,sBAAsB;IACzB,MAAM,aAAa,eAAe,QAAQ,MAAM,YAAY,KAAA;IAC5D,KAAK,sBAAsB,UAAU;IACrC,IAAI,CAAC,MAAM,OAAO;IAClB,KAAK,iBAAiB;IACtB,MAAM,KAAK,KAAK,qBAAqB,UAAU;IAC/C,KAAK,WAAW,IAAI,MAAM,KAAK;IAC/B,KAAK;IACL,KAAK,KAAK;IACV;GACF;GACA,KAAK;IACH,KAAK,sBAAsB,MAAM,SAAS;IAC1C,IAAI,MAAM,aAAa,KAAK,wBAAwB,MAAM,WACxD,KAAK,sBAAsB,KAAA;IAE7B,KAAK,KAAK;IACV;GAGF,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,qBACH,eAAe,QAAQ,MAAM,YAAY,KAAA,GACzC,MAAM,SAAS,yBACjB;IACA;GACF,KAAK;IACH,IAAI,MAAM,YAAY,WAAW;KAG/B,MAAM,SAAS,KAAK;KACpB,MAAM,MAAM,KAAK,eAAe,IAAI,MAAM,QAAQ,IAC9C,MAAM,WACN,WAAW,KAAA,KAAa,KAAK,uBAAuB,IAAI,MAAM,IAC5D,SACA,KAAA;KACN,IAAI,QAAQ,KAAA,GAAW;MACrB,KAAK,oBAAoB,IAAI,KAAK,MAAM,cAAc;MACtD,KAAK,KAAK;KACZ;IACF;IACA;GACF,KAAK;IACH,KAAK,uBAAuB,MAAM,KAAK;IACvC,KAAK;IACL,KAAK,iBAAiB;IACtB;GACF,KAAK;IACH,KAAK,uBACH,MAAM,OACN,eAAe,QAAQ,MAAM,YAAY,KAAA,GACzC,IACF;IACA,KAAK;IACL,KAAK,iBAAiB;IACtB;GACF,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;IACH,KAAK,mBAAmB;IACxB;GAEF,KAAK;IACH,KAAK,sBAAsB,MAAM,eAAe;IAChD,KAAK,cACH,MAAM,YACN,MAAM,cACN,MAAM,eACR;IACA,KAAK,KAAK;IACV;GAEF,KAAK;GACL,KAAK;IACH,IAAI,MAAM,SAAS,mBACjB,KAAK,sBAAsB,MAAM,eAAe;IAElD,IAAI,CAAC,MAAM,OAAO;IAClB,KAAK,eAAe,MAAM,YAAY,MAAM,KAAK;IACjD,KAAK,KAAK;IACV;GAEF,KAAK;IACH,KAAK,KAAK;IACV;GAEF,KAAK;IACH,KAAK,eACH,MAAM,YACN,MAAM,WAAW,IACjB,OAAO,MAAM,WAAW,YAAY,YAChC,MAAM,UAAU,UAChB,MAAM,SAAS,SACb,QACA,KAAA,GACN,MAAM,WACN,MAAM,SACR;IACA,KAAK,KAAK;IACV;GAEF,KAAK,qBAAqB;IACxB,IAAI,MAAM,iBAAA,gBAA6C;KACrD,KAAK,2BAA2B,KAAK;KACrC;IACF;IACA,IAAI,MAAM,iBAAA,YAAyC;IACnD,MAAM,aAAa,MAAM,QAAQ;IACjC,MAAM,QACJ,OAAO,eAAe,WAClB,KAAK,UAAU,IAAI,UAAU,IAC7B,KAAK,yBACH,KAAK,UAAU,IAAI,KAAK,sBAAsB,IAC9C,KAAA;IACR,MAAM,cAAc,MAAM,QAAQ;IAClC,IACE,SACA,OAAO,gBAAgB,YACvB,YAAY,WAAW,GACvB;KACA,MAAM,oBAAoB;KAC1B,MAAM,KAAK,MAAM,QAAQ;KACzB,MAAM,OAAO,MAAM,QAAQ;KAC3B,IAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GACxC,MAAM,iBAAiB;UAClB,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,GACnD,MAAM,iBAAiB;KAEzB,MAAM,SAAS,MAAM,QAAQ;KAC7B,IAAI,cAAc,MAAM,GAAG;MACzB,IACE,MAAM,WAAW,KAAA,KACjB,MAAM,iBAAiB,KAAA,GAEvB,MAAM,eAAe,CACnB;OACE,MAAM;OACN,MACE,OAAO,MAAM,WAAW,WACpB,MAAM,SACN,KAAK,UAAU,MAAM,MAAM;MACnC,CACF;MAEF,MAAM,SAAS;MACf,MAAM,wBAAwB;MAC9B,IAAI,OAAO,OAAO,YAAY,WAC5B,MAAM,UAAU,OAAO;KAE3B;KACA,KAAK,KAAK;IACZ;IACA;GACF;GAEA,SACE,KAAK,OAAO,QAAQ,mCAAmC,KAAK;EAEhE;CACF;CAEA,2BACE,OACM;EACN,MAAM,aAAa,MAAM,QAAQ;EACjC,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;EAEhC,MAAM,YAAY,MAAM,aAAa;EACrC,IAAI,MAAM,YAAY,SAAS,KAAK,YAAY,IAAI,SAAS,GAAG;EAEhE,MAAM,EAAE,OAAO,aAAa,oCAAoB,IAAI,IAAI,GAAG,UAAU;EACrE,KAAK,MAAM,WAAW,UACpB,KAAK,OAAO,MAAM,iCAAiC,OAAO;EAE5D,KAAK,YAAY,OAAO,SAAS;EACjC,KAAK,YAAY,IAAI,WAAW,KAAK;EACrC,KAAK,wBAAwB;EAC7B,KAAK,KAAK;CACZ;CAEA,0BAAwC;EACtC,MAAM,2BAAW,IAAI,IAA8B;EAEnD,KAAK,MAAM,UAAU,KAAK,YAAY,OAAO,GAC3C,KAAK,MAAM,CAAC,WAAW,YAAY,QACjC,SAAS,IAAI,WAAW,OAAO;EAInC,MAAM,oCAAoB,IAAI,IAAY;EAC1C,KAAK,MAAM,CAAC,WAAW,YAAY,UAAU;GAC3C,MAAM,aAAa,QAAQ;GAC3B,MAAM,EAAE,MAAM,aAAa,uBAAuB,OAAO;GACzD,KAAK,MAAM,WAAW,UACpB,KAAK,OAAO,MAAM,0CAA0C,OAAO;GAErE,IAAI,CAAC,MAAM;GAEX,kBAAkB,IAAI,UAAU;GAEhC,MAAM,QAAuB;IAC3B;IACA,cAAc;IACd,UAAU,KAAK,UAAU,IAAI;IAC7B,YAAY;IACZ,QAAQ,CAAC;IACT,SAAS,KAAA;IACT,uBAAuB;GACzB;GACA,IAAI,CAAC,KAAK,UAAU,IAAI,UAAU,GAChC,KAAK,UAAU,KAAK;IAAE,MAAM;IAAa;GAAW,CAAC;GAEvD,KAAK,UAAU,IAAI,YAAY,KAAK;GACpC,KAAK,gBAAgB,IAAI,UAAU;EACrC;EAEA,KAAK,MAAM,cAAc,KAAK,iBAAiB;GAC7C,IAAI,kBAAkB,IAAI,UAAU,GAAG;GACvC,KAAK,UAAU,OAAO,UAAU;GAChC,MAAM,YAAY,KAAK,UAAU,WAC9B,SAAS,KAAK,SAAS,eAAe,KAAK,eAAe,UAC7D;GACA,IAAI,cAAc,IAAI,KAAK,UAAU,OAAO,WAAW,CAAC;GACxD,KAAK,gBAAgB,OAAO,UAAU;EACxC;CACF;CAEA,sBAA8B,WAAqC;EACjE,IAAI,KAAK,2BAA2B,CAAC,WAAW;EAChD,KAAK,0BAA0B;EAC/B,KAAK,oBAAoB,SAAS;CACpC;CAEA,iBAA+B;EAC7B,KAAK,UAAU,MAAM;CACvB;CAEA,kBAAkC;EAChC,KAAK,mBAAmB;EACxB,OAAO,QAAQ,KAAK;CACtB;CAEA,iBAAyB,WAA4B;EACnD,MAAM,KAAK,aAAa,KAAK,gBAAgB;EAC7C,KAAK,eAAe,EAAE;EACtB,KAAK,sBAAsB;EAC3B,OAAO;CACT;CAEA,qBAA6B,WAA4B;EACvD,IAAI,WAAW;GACb,KAAK,eAAe,SAAS;GAC7B,KAAK,sBAAsB;GAC3B,OAAO;EACT;EAEA,IAAI,KAAK,qBACP,OAAO,KAAK;EAGd,MAAM,YAAY,KAAK,gBAAgB;EACvC,KAAK,eAAe,SAAS;EAC7B,KAAK,sBAAsB;EAC3B,OAAO;CACT;CAEA,eAAuB,IAAkB;EACvC,IAAI,CAAC,KAAK,UAAU,IAAI,EAAE,GAAG;GAC3B,KAAK,UAAU,IAAI,IAAI;IAAE,QAAQ;IAAI,SAAS;GAAM,CAAC;GACrD,IACE,CAAC,KAAK,UAAU,MAAM,SAAS,KAAK,SAAS,UAAU,KAAK,QAAQ,EAAE,GAEtE,KAAK,UAAU,KAAK;IAAE,MAAM;IAAQ,KAAK;GAAG,CAAC;EAEjD;CACF;CAEA,oBAA4B,IAAkB;EAC5C,MAAM,QAAQ,KAAK,UAAU,IAAI,EAAE;EACnC,IAAI,CAAC,OAAO;EACZ,MAAM,UAAU;CAClB;CAEA,WAAmB,IAAY,OAAqB;EAClD,KAAK,eAAe,EAAE;EACtB,MAAM,QAAQ,KAAK,UAAU,IAAI,EAAE;EACnC,IAAI,CAAC,OAAO;EACZ,MAAM,UAAU;EAChB,MAAM,UAAU;CAClB;CAEA,cACE,IACA,MACA,iBACA;EACA,IAAI,CAAC,IAAI;EAGT,KAAK,sBAAsB,KAAA;EAC3B,IACE,CAAC,KAAK,UAAU,MACb,SAAS,KAAK,SAAS,eAAe,KAAK,eAAe,EAC7D,GAEA,KAAK,eAAe,IAAI,eAAe;EAEzC,MAAM,QAAuB;GAC3B,YAAY;GACZ,cAAc,QAAQ;GACtB,UAAU;GACV,YAAY,KAAA;GACZ,QAAQ,KAAA;GACR,SAAS,KAAA;GACT,uBAAuB;EACzB;EACA,IAAI,iBACF,MAAM,kBAAkB;EAE1B,KAAK,UAAU,IAAI,IAAI,KAAK;CAC9B;CAIA,eAAuB,IAAY,iBAA0B;EAC3D,MAAM,QAAQ;GAAE,MAAM;GAAa,YAAY;EAAG;EAClD,IAAI,iBAAiB;GACnB,MAAM,cAAc,KAAK,UAAU,WAChC,SAAS,KAAK,SAAS,UAAU,KAAK,QAAQ,eACjD;GACA,IAAI,gBAAgB,IAAI;IACtB,IAAI,WAAW,cAAc;IAC7B,OAAO,WAAW,KAAK,UAAU,QAAQ;KACvC,MAAM,OAAO,KAAK,UAAU;KAC5B,IACE,MAAM,SAAS,eACf,KAAK,UAAU,IAAI,KAAK,UAAU,CAAC,EAAE,oBACnC,iBACF;MACA,YAAY;MACZ;KACF;KACA;IACF;IACA,KAAK,UAAU,OAAO,UAAU,GAAG,KAAK;IACxC;GACF;EACF;EACA,KAAK,UAAU,KAAK,KAAK;CAC3B;CAEA,eAAuB,IAAwB,OAAe;EAC5D,MAAM,QAAQ,KAAK,KAAK,UAAU,IAAI,EAAE,IAAI,KAAA;EAC5C,IAAI,CAAC,OAAO;EACZ,MAAM,YAAY;EAClB,IAAI;GACF,MAAM,SAAS,KAAK,MAAM,MAAM,QAAQ;GACxC,IAAI,UAAU,OAAO,WAAW,UAC9B,MAAM,aAAa;QAEnB,MAAM,aAAa,KAAA;EAEvB,QAAQ;GACN,MAAM,aAAa,KAAA;EACrB;CACF;CAEA,eACE,IACA,SACA,SACA,eACA,WACA;EACA,IAAI,CAAC,IAAI;EACT,IAAI,QAAQ,KAAK,UAAU,IAAI,EAAE;EACjC,IAAI,CAAC,OAAO;GACV,QAAQ;IACN,YAAY;IACZ,cAAc;IACd,UAAU;IACV,YAAY,KAAA;IACZ,QAAQ,KAAA;IACR,SAAS,KAAA;IACT,uBAAuB;GACzB;GACA,KAAK,UAAU,IAAI,IAAI,KAAK;EAC9B;EACA,IACE,CAAC,KAAK,UAAU,MACb,SAAS,KAAK,SAAS,eAAe,KAAK,eAAe,EAC7D,GAEA,KAAK,UAAU,KAAK;GAAE,MAAM;GAAa,YAAY;EAAG,CAAC;EAE3D,IAAI,cAAc,KAAA,KAAa,CAAC,MAAM,uBAAuB;GAC3D,MAAM,SAAS;GACf,MAAM,eAAe,CAAC;IAAE,MAAM;IAAQ,MAAM;GAAQ,CAAC;GACrD,MAAM,wBAAwB;GAC9B,MAAM,UAAU;GAChB,IAAI,MAAM,sBAAsB,KAAA,GAAW;IACzC,MAAM,MAAM,sBAAsB,UAAU,KAAK;IACjD,IAAI,QAAQ,KAAA,GAAW,MAAM,oBAAoB;GACnD;EACF,OAAO,IAAI,MAAM,uBAAuB;GACtC,IAAI,MAAM,iBAAiB,KAAA,GACzB,MAAM,eAAe,CAAC;IAAE,MAAM;IAAQ,MAAM;GAAQ,CAAC;GAEvD,IAAI,MAAM,YAAY,KAAA,GACpB,MAAM,UAAU;EAEpB,OAAO;GACL,MAAM,SAAS,aAAa,OAAO;GACnC,MAAM,UAAU;EAClB;EACA,IAAI,eACF,MAAM,gBAAgB;EAExB,KAAK,yBAAyB;CAChC;CAEA,OAAqB;EACnB,MAAM,WAAyC,CAAC;EAEhD,KAAK,MAAM,QAAQ,KAAK,WAAW;GACjC,IAAI,KAAK,SAAS,aAAa;IAC7B,IAAI,KAAK,cAAc;KACrB,MAAM,SAAS,KAAK,eAAe,IAAI,KAAK,GAAG,KAAK;KACpD,IAAI,OAAO,SAAS,KAAK,KAAK,uBAAuB,KAAK,KAAK;MAC7D,MAAM,iBAAiB,KAAK,oBAAoB,IAAI,KAAK,GAAG;MAC5D,MAAM,cAAc,KAAK,oBAAoB,IAAI,KAAK,GAAG;MACzD,MAAM,OAAO;OACX,GAAI,gBAAgB,KAAA,IAAY,EAAE,YAAY,IAAI,CAAC;OACnD,GAAI,mBAAmB,KAAA,IAAY,EAAE,eAAe,IAAI,CAAC;MAC3D;MACA,SAAS,KAAK;OACZ,MAAM;OACN,MAAM;OACN,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAC3B,EAAE,kBAAkB,GAAG,2BAA2B,KAAK,EAAE,IACzD,CAAC;MACP,CAAU;KACZ;IACF;IACA;GACF;GAEA,IAAI,KAAK,SAAS,QAAQ;IACxB,MAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,GAAG;IACzC,IAAI,OAAO,SACT,SAAS,KAAK;KAAE,MAAM;KAAQ,MAAM,MAAM;IAAO,CAAU;IAE7D;GACF;GAEA,MAAM,QAAQ,KAAK,UAAU,IAAI,KAAK,UAAU;GAChD,IAAI,CAAC,OAAO;GACZ,MAAM,WAAgC;IACpC,MAAM;IACN,YAAY,MAAM;IAClB,UAAU,MAAM;IAChB,MAAO,MAAM,cAAc,CAAC;IAC5B,UAAU,MAAM;IAChB,GAAI,MAAM,WAAW,KAAA,IAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;IAC7D,GAAI,MAAM,iBAAiB,KAAA,IACvB,EAAE,cAAc,MAAM,aAAa,IACnC,CAAC;IACL,GAAI,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;IAChE,GAAI,MAAM,oBACN,EACE,KAAK,EACH,KAAK;KACH,aAAa,MAAM;KACnB,GAAI,MAAM,iBACN,EAAE,UAAU,MAAM,eAAe,IACjC,CAAC;IACP,EACF,EACF,IACA,CAAC;IACL,GAAI,MAAM,kBAAkB,EAAE,UAAU,MAAM,gBAAgB,IAAI,CAAC;IACnE,GAAI,MAAM,gBACN,EAAE,wBAAwB,MAAM,cAAc,IAC9C,CAAC;GACP;GACA,SAAS,KAAK,QAAQ;EACxB;EAEA,MAAM,SAAS,KAAK,UAAU;EAC9B,MAAM,WAAW;GACf,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;GAC3B,GAAI,KAAK,aACL,EACE,QAAQ,GACL,2BAA2B,EAC1B,YAAY,KAAK,WACnB,EACF,EACF,IACA,CAAC;EACP;EACA,MAAM,SAA6B;GACjC,SAAS;GACT,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,KAAA;GAC5C,GAAI,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,IAAI,EAAE,SAAS,IAAI,KAAA;EACxD;EACA,KAAK,WAAW,MAAM;CACxB;CAEA,mBAAiC;EAC/B,IACE,KAAK,mBAAmB,KAAA,KACxB,KAAK,oBAAoB,KAAA,GAEzB,KAAK,iBAAiB,KAAK,IAAI,IAAI,KAAK;CAE5C;CAEA,YAA+C;EAC7C,IAAI,KAAK,oBAAoB,KAAA,GAAW,OAAO,KAAA;EAG/C,MAAM,kBADM,KAAK,IACS,IAAI,KAAK;EACnC,MAAM,aACJ,KAAK,cAAc,IACf,KAAK,KACH,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC,CAAC,CAAC,QACjC,KAAK,MAAM,MAAM,EAAE,OAAO,QAC3B,CACF,IAAI,CACN,IACA,KAAA;EACN,MAAM,kBACJ,cAAc,kBAAkB,IAC3B,aAAa,kBAAmB,MACjC,KAAA;EAEN,OAAO;GACL,iBAAiB,KAAK;GACtB,GAAI,KAAK,mBAAmB,KAAA,IACxB,EAAE,gBAAgB,KAAK,eAAe,IACtC,CAAC;GACL;GACA,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;GACjD,GAAI,oBAAoB,KAAA,IAAY,EAAE,gBAAgB,IAAI,CAAC;GAC3D,aAAa,KAAK;GAClB,eAAe,KAAK,UAAU;EAChC;CACF;CAEA,qBAA6B,WAAoB,cAAc,OAAa;EAC1E,IAAI,CAAC,KAAK,cAAc;EAGxB,KAAK,sBAAsB,KAAA;EAC3B,MAAM,MAAM,aAAa,oBAAoB,EAAE,KAAK;EAIpD,IAAI,cAAc,KAAA,GAChB,KAAK,uBAAuB,IAAI,GAAG;OAC9B,IAAI,aACT,KAAK,oBAAoB,IAAI,KAAK,SAAS;EAE7C,IAAI,CAAC,KAAK,eAAe,IAAI,GAAG,GAAG;GACjC,KAAK,eAAe,IAAI,KAAK,EAAE;GAC/B,KAAK,UAAU,KAAK;IAAE,MAAM;IAAa;GAAI,CAAC;EAChD;EACA,KAAK,qBAAqB;EAC1B,KAAK,KAAK;CACZ;CAEA,uBACE,OACA,WACA,cAAc,OACR;EACN,IAAI,CAAC,KAAK,gBAAgB,CAAC,OAAO;EAClC,IAAI,CAAC,KAAK,oBAER,KAAK,qBAAqB,WAAW,WAAW;EAElD,MAAM,MAAM,KAAK;EACjB,IAAI,CAAC,KAAK;EACV,KAAK,eAAe,IAAI,MAAM,KAAK,eAAe,IAAI,GAAG,KAAK,MAAM,KAAK;EACzE,KAAK,KAAK;CACZ;CAEA,qBAAmC;EACjC,IAAI,CAAC,KAAK,cAAc;EACxB,KAAK,qBAAqB,KAAA;EAC1B,KAAK,KAAK;CACZ;AACF;AAEA,SAAgB,aAAa,OAAwB;CACnD,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -48,6 +48,9 @@ type Subscriber = {
48
48
  onReasoningMessageEndEvent?: (payload: {
49
49
  event: unknown;
50
50
  }) => void;
51
+ onReasoningEncryptedValueEvent?: (payload: {
52
+ event: unknown;
53
+ }) => void;
51
54
  onToolCallStartEvent?: (payload: {
52
55
  event: unknown;
53
56
  }) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"subscriber.d.ts","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"mappings":";;;KAMK,YAAY,OAAO;KAEnB;EACH,WAAW;IAAW;;EACtB,2BAA2B;IAAW;;EACtC,6BAA6B;IAAW;;EACxC,yBAAyB;IAAW;;EACpC,2BAA2B;IAAW;;EACtC,wBAAwB;IAAW;;EACnC,sBAAsB;IAAW;;EACjC,mCAAmC;IAAW;;EAC9C,qCAAqC;IAAW;;EAChD,iCAAiC;IAAW;;EAC5C,yBAAyB;IAAW;;EACpC,uBAAuB;IAAW;;EAClC,gCAAgC;IAAW;;EAC3C,kCAAkC;IAAW;;EAC7C,8BAA8B;IAAW;;EACzC,wBAAwB;IAAW;;EACnC,uBAAuB;IAAW;;EAClC,sBAAsB;IAAW;;EACjC,wBAAwB;IAAW;;EACnC,yBAAyB;IAAW;;EACpC,2BAA2B;IAAW;;EACtC,wBAAwB;IAAW;;EACnC,qBAAqB;IAAW;;EAChC,2BAA2B;IAAW;;EACtC,iBAAiB;IAAW;;EAC5B,cAAc;IAAW;;EACzB,sBAAsB;IAAW;;EACjC;EACA,eAAe;IAAW,OAAO;;;KAiC9B;EACH,UAAU;EACV;EACA,SAAS;EACT,eAAe,OAAO;;cAGX,uBACX,SAAS,sBACR;KAiGS,iBAAiB,kBAAkB"}
1
+ {"version":3,"file":"subscriber.d.ts","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"mappings":";;;KAMK,YAAY,OAAO;KAEnB;EACH,WAAW;IAAW;;EACtB,2BAA2B;IAAW;;EACtC,6BAA6B;IAAW;;EACxC,yBAAyB;IAAW;;EACpC,2BAA2B;IAAW;;EACtC,wBAAwB;IAAW;;EACnC,sBAAsB;IAAW;;EACjC,mCAAmC;IAAW;;EAC9C,qCAAqC;IAAW;;EAChD,iCAAiC;IAAW;;EAC5C,yBAAyB;IAAW;;EACpC,uBAAuB;IAAW;;EAClC,gCAAgC;IAAW;;EAC3C,kCAAkC;IAAW;;EAC7C,8BAA8B;IAAW;;EACzC,kCAAkC;IAAW;;EAC7C,wBAAwB;IAAW;;EACnC,uBAAuB;IAAW;;EAClC,sBAAsB;IAAW;;EACjC,wBAAwB;IAAW;;EACnC,yBAAyB;IAAW;;EACpC,2BAA2B;IAAW;;EACtC,wBAAwB;IAAW;;EACnC,qBAAqB;IAAW;;EAChC,2BAA2B;IAAW;;EACtC,iBAAiB;IAAW;;EAC5B,cAAc;IAAW;;EACzB,sBAAsB;IAAW;;EACjC;EACA,eAAe;IAAW,OAAO;;;KAiC9B;EACH,UAAU;EACV;EACA,SAAS;EACT,eAAe,OAAO;;cAGX,uBACX,SAAS,sBACR;KAmGS,iBAAiB,kBAAkB"}
@@ -47,6 +47,7 @@ const createAgUiSubscriber = (options) => {
47
47
  onReasoningMessageStartEvent: ({ event }) => dispatchIfValid(event, "REASONING_MESSAGE_START"),
48
48
  onReasoningMessageContentEvent: ({ event }) => dispatchIfValid(event, "REASONING_MESSAGE_CONTENT"),
49
49
  onReasoningMessageEndEvent: ({ event }) => dispatchIfValid(event, "REASONING_MESSAGE_END"),
50
+ onReasoningEncryptedValueEvent: ({ event }) => dispatchIfValid(event, "REASONING_ENCRYPTED_VALUE"),
50
51
  onToolCallStartEvent: ({ event }) => dispatchIfValid(event, "TOOL_CALL_START"),
51
52
  onToolCallArgsEvent: ({ event }) => dispatchIfValid(event, "TOOL_CALL_ARGS"),
52
53
  onToolCallEndEvent: ({ event }) => dispatchIfValid(event, "TOOL_CALL_END"),
@@ -1 +1 @@
1
- {"version":3,"file":"subscriber.js","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"sourcesContent":["\"use client\";\n\nimport type { AgUiEvent } from \"../types\";\nimport { parseAgUiEvent } from \"../event-parser\";\nimport type { Logger } from \"../logger\";\n\ntype Dispatch = (event: AgUiEvent) => void;\n\ntype Subscriber = {\n onEvent?: (payload: { event: unknown }) => void;\n onTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onTextMessageChunkEvent?: (payload: { event: unknown }) => void;\n onThinkingStartEvent?: (payload: { event: unknown }) => void;\n onThinkingEndEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningStartEvent?: (payload: { event: unknown }) => void;\n onReasoningEndEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageStartEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageContentEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageEndEvent?: (payload: { event: unknown }) => void;\n onToolCallStartEvent?: (payload: { event: unknown }) => void;\n onToolCallArgsEvent?: (payload: { event: unknown }) => void;\n onToolCallEndEvent?: (payload: { event: unknown }) => void;\n onToolCallChunkEvent?: (payload: { event: unknown }) => void;\n onToolCallResultEvent?: (payload: { event: unknown }) => void;\n onActivitySnapshotEvent?: (payload: { event: unknown }) => void;\n onStateSnapshotEvent?: (payload: { event: unknown }) => void;\n onStateDeltaEvent?: (payload: { event: unknown }) => void;\n onMessagesSnapshotEvent?: (payload: { event: unknown }) => void;\n onCustomEvent?: (payload: { event: unknown }) => void;\n onRawEvent?: (payload: { event: unknown }) => void;\n onRunFinishedEvent?: (payload: { event: unknown }) => void;\n onRunFinalized?: () => void;\n onRunFailed?: (payload: { error: Error }) => void;\n};\n\nconst isAbortError = (error: Error): boolean => {\n if (error.name === \"AbortError\") return true;\n const message = typeof error.message === \"string\" ? error.message : \"\";\n return (\n message === \"Fetch is aborted\" ||\n message === \"signal is aborted without reason\" ||\n message === \"component unmounted\"\n );\n};\n\nconst ensureEvent = (\n raw: unknown,\n type: AgUiEvent[\"type\"],\n logger?: Logger,\n): AgUiEvent | null => {\n const parseOptions = logger ? { logger } : undefined;\n let parsed: AgUiEvent | null;\n if (raw && typeof raw === \"object\") {\n const payload = raw as Record<string, unknown>;\n if (typeof payload.type === \"string\") {\n parsed = parseAgUiEvent(payload, parseOptions);\n } else {\n parsed = parseAgUiEvent({ type, ...payload }, parseOptions);\n }\n } else {\n parsed = parseAgUiEvent({ type }, parseOptions);\n }\n return parsed && parsed.type === type ? parsed : null;\n};\n\ntype SubscriberOptions = {\n dispatch: Dispatch;\n runId: string;\n logger?: Logger;\n onRunFailed?: (error: Error) => void;\n};\n\nexport const createAgUiSubscriber = (\n options: SubscriberOptions,\n): Subscriber => {\n const { dispatch, runId, logger, onRunFailed } = options;\n let runFinishedDispatched = false;\n const dispatchIfValid = (raw: unknown, type: AgUiEvent[\"type\"]) => {\n const event = ensureEvent(raw, type, logger);\n if (!event) return;\n dispatch(event);\n };\n return {\n onEvent: ({ event }) => {\n const typeCandidate =\n event && typeof event === \"object\"\n ? (event as Record<string, unknown>).type\n : undefined;\n if (typeof typeCandidate === \"string\") {\n // Typed handlers will receive this via the discriminated callbacks; avoid duplicates.\n return;\n }\n const parsed = parseAgUiEvent(event);\n if (parsed) dispatch(parsed);\n },\n onTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_START\"),\n onTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CONTENT\"),\n onTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_END\"),\n onTextMessageChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CHUNK\"),\n onThinkingStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_START\"),\n onThinkingEndEvent: ({ event }) => dispatchIfValid(event, \"THINKING_END\"),\n onThinkingTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_START\"),\n onThinkingTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_CONTENT\"),\n onThinkingTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_END\"),\n onReasoningStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_START\"),\n onReasoningEndEvent: ({ event }) => dispatchIfValid(event, \"REASONING_END\"),\n onReasoningMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_START\"),\n onReasoningMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_CONTENT\"),\n onReasoningMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_END\"),\n onToolCallStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_START\"),\n onToolCallArgsEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_ARGS\"),\n onToolCallEndEvent: ({ event }) => dispatchIfValid(event, \"TOOL_CALL_END\"),\n onToolCallChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_CHUNK\"),\n onToolCallResultEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_RESULT\"),\n onActivitySnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_SNAPSHOT\"),\n onStateSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"STATE_SNAPSHOT\"),\n onStateDeltaEvent: ({ event }) => dispatchIfValid(event, \"STATE_DELTA\"),\n onMessagesSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"MESSAGES_SNAPSHOT\"),\n onCustomEvent: ({ event }) => dispatchIfValid(event, \"CUSTOM\"),\n onRawEvent: ({ event }) => dispatchIfValid(event, \"RAW\"),\n onRunFinishedEvent: ({ event }) => {\n const parsed = ensureEvent(event, \"RUN_FINISHED\", logger);\n if (!parsed) return;\n runFinishedDispatched = true;\n dispatch(parsed);\n },\n onRunFinalized: () => {\n if (runFinishedDispatched) return;\n dispatch({ type: \"RUN_FINISHED\", runId });\n },\n onRunFailed: ({ error }) => {\n runFinishedDispatched = true;\n onRunFailed?.(error);\n if (isAbortError(error)) {\n dispatch({ type: \"RUN_CANCELLED\" } satisfies AgUiEvent);\n return;\n }\n const message =\n typeof error.message === \"string\" ? error.message : \"Run failed\";\n const code =\n typeof (error as any)?.code === \"string\"\n ? (error as any).code\n : undefined;\n dispatch({\n type: \"RUN_ERROR\" as const,\n ...(message !== undefined ? { message } : {}),\n ...(code !== undefined ? { code } : {}),\n } satisfies AgUiEvent);\n },\n };\n};\n\nexport type AgUiSubscriber = ReturnType<typeof createAgUiSubscriber>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"subscriber.js","names":[],"sources":["../../../src/runtime/adapter/subscriber.ts"],"sourcesContent":["\"use client\";\n\nimport type { AgUiEvent } from \"../types\";\nimport { parseAgUiEvent } from \"../event-parser\";\nimport type { Logger } from \"../logger\";\n\ntype Dispatch = (event: AgUiEvent) => void;\n\ntype Subscriber = {\n onEvent?: (payload: { event: unknown }) => void;\n onTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onTextMessageChunkEvent?: (payload: { event: unknown }) => void;\n onThinkingStartEvent?: (payload: { event: unknown }) => void;\n onThinkingEndEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageStartEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageContentEvent?: (payload: { event: unknown }) => void;\n onThinkingTextMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningStartEvent?: (payload: { event: unknown }) => void;\n onReasoningEndEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageStartEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageContentEvent?: (payload: { event: unknown }) => void;\n onReasoningMessageEndEvent?: (payload: { event: unknown }) => void;\n onReasoningEncryptedValueEvent?: (payload: { event: unknown }) => void;\n onToolCallStartEvent?: (payload: { event: unknown }) => void;\n onToolCallArgsEvent?: (payload: { event: unknown }) => void;\n onToolCallEndEvent?: (payload: { event: unknown }) => void;\n onToolCallChunkEvent?: (payload: { event: unknown }) => void;\n onToolCallResultEvent?: (payload: { event: unknown }) => void;\n onActivitySnapshotEvent?: (payload: { event: unknown }) => void;\n onStateSnapshotEvent?: (payload: { event: unknown }) => void;\n onStateDeltaEvent?: (payload: { event: unknown }) => void;\n onMessagesSnapshotEvent?: (payload: { event: unknown }) => void;\n onCustomEvent?: (payload: { event: unknown }) => void;\n onRawEvent?: (payload: { event: unknown }) => void;\n onRunFinishedEvent?: (payload: { event: unknown }) => void;\n onRunFinalized?: () => void;\n onRunFailed?: (payload: { error: Error }) => void;\n};\n\nconst isAbortError = (error: Error): boolean => {\n if (error.name === \"AbortError\") return true;\n const message = typeof error.message === \"string\" ? error.message : \"\";\n return (\n message === \"Fetch is aborted\" ||\n message === \"signal is aborted without reason\" ||\n message === \"component unmounted\"\n );\n};\n\nconst ensureEvent = (\n raw: unknown,\n type: AgUiEvent[\"type\"],\n logger?: Logger,\n): AgUiEvent | null => {\n const parseOptions = logger ? { logger } : undefined;\n let parsed: AgUiEvent | null;\n if (raw && typeof raw === \"object\") {\n const payload = raw as Record<string, unknown>;\n if (typeof payload.type === \"string\") {\n parsed = parseAgUiEvent(payload, parseOptions);\n } else {\n parsed = parseAgUiEvent({ type, ...payload }, parseOptions);\n }\n } else {\n parsed = parseAgUiEvent({ type }, parseOptions);\n }\n return parsed && parsed.type === type ? parsed : null;\n};\n\ntype SubscriberOptions = {\n dispatch: Dispatch;\n runId: string;\n logger?: Logger;\n onRunFailed?: (error: Error) => void;\n};\n\nexport const createAgUiSubscriber = (\n options: SubscriberOptions,\n): Subscriber => {\n const { dispatch, runId, logger, onRunFailed } = options;\n let runFinishedDispatched = false;\n const dispatchIfValid = (raw: unknown, type: AgUiEvent[\"type\"]) => {\n const event = ensureEvent(raw, type, logger);\n if (!event) return;\n dispatch(event);\n };\n return {\n onEvent: ({ event }) => {\n const typeCandidate =\n event && typeof event === \"object\"\n ? (event as Record<string, unknown>).type\n : undefined;\n if (typeof typeCandidate === \"string\") {\n // Typed handlers will receive this via the discriminated callbacks; avoid duplicates.\n return;\n }\n const parsed = parseAgUiEvent(event);\n if (parsed) dispatch(parsed);\n },\n onTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_START\"),\n onTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CONTENT\"),\n onTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_END\"),\n onTextMessageChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TEXT_MESSAGE_CHUNK\"),\n onThinkingStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_START\"),\n onThinkingEndEvent: ({ event }) => dispatchIfValid(event, \"THINKING_END\"),\n onThinkingTextMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_START\"),\n onThinkingTextMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_CONTENT\"),\n onThinkingTextMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"THINKING_TEXT_MESSAGE_END\"),\n onReasoningStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_START\"),\n onReasoningEndEvent: ({ event }) => dispatchIfValid(event, \"REASONING_END\"),\n onReasoningMessageStartEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_START\"),\n onReasoningMessageContentEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_CONTENT\"),\n onReasoningMessageEndEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_MESSAGE_END\"),\n onReasoningEncryptedValueEvent: ({ event }) =>\n dispatchIfValid(event, \"REASONING_ENCRYPTED_VALUE\"),\n onToolCallStartEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_START\"),\n onToolCallArgsEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_ARGS\"),\n onToolCallEndEvent: ({ event }) => dispatchIfValid(event, \"TOOL_CALL_END\"),\n onToolCallChunkEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_CHUNK\"),\n onToolCallResultEvent: ({ event }) =>\n dispatchIfValid(event, \"TOOL_CALL_RESULT\"),\n onActivitySnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"ACTIVITY_SNAPSHOT\"),\n onStateSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"STATE_SNAPSHOT\"),\n onStateDeltaEvent: ({ event }) => dispatchIfValid(event, \"STATE_DELTA\"),\n onMessagesSnapshotEvent: ({ event }) =>\n dispatchIfValid(event, \"MESSAGES_SNAPSHOT\"),\n onCustomEvent: ({ event }) => dispatchIfValid(event, \"CUSTOM\"),\n onRawEvent: ({ event }) => dispatchIfValid(event, \"RAW\"),\n onRunFinishedEvent: ({ event }) => {\n const parsed = ensureEvent(event, \"RUN_FINISHED\", logger);\n if (!parsed) return;\n runFinishedDispatched = true;\n dispatch(parsed);\n },\n onRunFinalized: () => {\n if (runFinishedDispatched) return;\n dispatch({ type: \"RUN_FINISHED\", runId });\n },\n onRunFailed: ({ error }) => {\n runFinishedDispatched = true;\n onRunFailed?.(error);\n if (isAbortError(error)) {\n dispatch({ type: \"RUN_CANCELLED\" } satisfies AgUiEvent);\n return;\n }\n const message =\n typeof error.message === \"string\" ? error.message : \"Run failed\";\n const code =\n typeof (error as any)?.code === \"string\"\n ? (error as any).code\n : undefined;\n dispatch({\n type: \"RUN_ERROR\" as const,\n ...(message !== undefined ? { message } : {}),\n ...(code !== undefined ? { code } : {}),\n } satisfies AgUiEvent);\n },\n };\n};\n\nexport type AgUiSubscriber = ReturnType<typeof createAgUiSubscriber>;\n"],"mappings":"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"}
@@ -110,6 +110,19 @@ const parseAgUiEvent = (event, options) => {
110
110
  }, { messageId: getString("messageId") });
111
111
  }
112
112
  case "REASONING_MESSAGE_END": return withOptional({ type: "REASONING_MESSAGE_END" }, { messageId: getString("messageId") });
113
+ case "REASONING_ENCRYPTED_VALUE": {
114
+ const entityId = getString("entityId");
115
+ const encryptedValue = getString("encryptedValue");
116
+ const subtype = getString("subtype");
117
+ if (!entityId || !encryptedValue) return null;
118
+ if (subtype !== "message" && subtype !== "tool-call") return null;
119
+ return {
120
+ type: "REASONING_ENCRYPTED_VALUE",
121
+ subtype,
122
+ entityId,
123
+ encryptedValue
124
+ };
125
+ }
113
126
  case "REASONING_END": return withOptional({ type: "REASONING_END" }, { messageId: getString("messageId") });
114
127
  case "TOOL_CALL_START": {
115
128
  const toolCallId = getString("toolCallId");
@@ -1 +1 @@
1
- {"version":3,"file":"event-parser.js","names":[],"sources":["../../src/runtime/event-parser.ts"],"sourcesContent":["import type { AgUiEvent, AgUiInterrupt, AgUiRunFinishedOutcome } from \"./types\";\nimport type { Logger } from \"./logger\";\nimport { parseMcpToolCallResult } from \"./mcp-tool-result\";\n\nexport type ParseAgUiEventOptions = {\n logger?: Logger;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNonEmptyString = (value: unknown): value is string =>\n isString(value) && value.length > 0;\n\nconst withOptional = <T extends object>(\n base: T,\n optionals: Record<string, unknown>,\n) => {\n const definedEntries = Object.entries(optionals).filter(\n ([, value]) => value !== undefined,\n );\n return definedEntries.length === 0\n ? base\n : ({ ...base, ...Object.fromEntries(definedEntries) } as T);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\nconst parseInterrupt = (raw: unknown): AgUiInterrupt | null => {\n if (!isPlainObject(raw)) return null;\n const id = raw.id;\n const reason = raw.reason;\n if (typeof id !== \"string\" || typeof reason !== \"string\") return null;\n const interrupt: AgUiInterrupt = { id, reason };\n if (typeof raw.message === \"string\") interrupt.message = raw.message;\n if (typeof raw.toolCallId === \"string\") interrupt.toolCallId = raw.toolCallId;\n if (typeof raw.expiresAt === \"string\") interrupt.expiresAt = raw.expiresAt;\n if (isPlainObject(raw.responseSchema))\n interrupt.responseSchema = raw.responseSchema;\n if (isPlainObject(raw.metadata)) interrupt.metadata = raw.metadata;\n return interrupt;\n};\n\nconst parseRunFinishedOutcome = (\n raw: unknown,\n logger: Logger | undefined,\n): AgUiRunFinishedOutcome | undefined => {\n if (!isPlainObject(raw)) return undefined;\n if (raw.type === \"success\") return { type: \"success\" };\n if (raw.type === \"interrupt\") {\n if (!Array.isArray(raw.interrupts)) {\n logger?.debug?.(\n \"[agui] RUN_FINISHED interrupt outcome missing interrupts array\",\n raw,\n );\n return undefined;\n }\n const parsed = raw.interrupts\n .map((entry) => parseInterrupt(entry))\n .filter((entry): entry is AgUiInterrupt => entry !== null);\n if (parsed.length === 0) {\n logger?.debug?.(\n \"[agui] RUN_FINISHED interrupt outcome has no valid interrupts\",\n raw.interrupts,\n );\n return undefined;\n }\n return { type: \"interrupt\", interrupts: parsed };\n }\n return undefined;\n};\n\nexport const parseAgUiEvent = (\n event: unknown,\n options?: ParseAgUiEventOptions,\n): AgUiEvent | null => {\n if (!event || typeof event !== \"object\") return null;\n const payload = event as Record<string, unknown>;\n const typeValue = payload.type;\n if (!isString(typeValue)) return null;\n\n const getString = (key: string) =>\n isString(payload[key]) ? (payload[key] as string) : undefined;\n\n switch (typeValue) {\n case \"RUN_STARTED\": {\n const runId = getString(\"runId\");\n return runId ? { type: \"RUN_STARTED\", runId } : null;\n }\n case \"RUN_FINISHED\": {\n const runId = getString(\"runId\");\n if (!runId) return null;\n return withOptional(\n { type: \"RUN_FINISHED\" as const, runId },\n {\n outcome: parseRunFinishedOutcome(payload.outcome, options?.logger),\n },\n );\n }\n case \"RUN_CANCELLED\": {\n const runId = getString(\"runId\");\n return withOptional({ type: \"RUN_CANCELLED\" as const }, { runId });\n }\n case \"RUN_ERROR\": {\n return withOptional(\n { type: \"RUN_ERROR\" as const },\n {\n message: getString(\"message\"),\n code: getString(\"code\"),\n },\n );\n }\n case \"TEXT_MESSAGE_START\":\n return withOptional(\n { type: \"TEXT_MESSAGE_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TEXT_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\");\n if (!isNonEmptyString(delta)) return null;\n return withOptional(\n { type: \"TEXT_MESSAGE_CONTENT\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"TEXT_MESSAGE_END\":\n return withOptional(\n { type: \"TEXT_MESSAGE_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TEXT_MESSAGE_CHUNK\": {\n const delta = getString(\"delta\") ?? \"\";\n return withOptional(\n { type: \"TEXT_MESSAGE_CHUNK\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"THINKING_START\":\n return withOptional(\n { type: \"THINKING_START\" as const },\n { title: getString(\"title\") },\n );\n case \"THINKING_TEXT_MESSAGE_START\":\n return { type: \"THINKING_TEXT_MESSAGE_START\" };\n case \"THINKING_TEXT_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\") ?? \"\";\n return { type: \"THINKING_TEXT_MESSAGE_CONTENT\", delta };\n }\n case \"THINKING_TEXT_MESSAGE_END\":\n return { type: \"THINKING_TEXT_MESSAGE_END\" };\n case \"THINKING_END\":\n return { type: \"THINKING_END\" };\n case \"REASONING_START\":\n return withOptional(\n { type: \"REASONING_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_MESSAGE_START\":\n return withOptional(\n { type: \"REASONING_MESSAGE_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\") ?? \"\";\n return withOptional(\n { type: \"REASONING_MESSAGE_CONTENT\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"REASONING_MESSAGE_END\":\n return withOptional(\n { type: \"REASONING_MESSAGE_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_END\":\n return withOptional(\n { type: \"REASONING_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TOOL_CALL_START\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n return withOptional(\n { type: \"TOOL_CALL_START\" as const, toolCallId },\n {\n toolCallName: getString(\"toolCallName\"),\n parentMessageId: getString(\"parentMessageId\"),\n },\n );\n }\n case \"TOOL_CALL_ARGS\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n const delta = getString(\"delta\") ?? \"\";\n return { type: \"TOOL_CALL_ARGS\", toolCallId, delta };\n }\n case \"TOOL_CALL_END\": {\n const toolCallId = getString(\"toolCallId\");\n return toolCallId ? { type: \"TOOL_CALL_END\", toolCallId } : null;\n }\n case \"TOOL_CALL_CHUNK\":\n return withOptional(\n { type: \"TOOL_CALL_CHUNK\" as const },\n {\n toolCallId: getString(\"toolCallId\"),\n toolCallName: getString(\"toolCallName\"),\n parentMessageId: getString(\"parentMessageId\"),\n delta: getString(\"delta\"),\n },\n );\n case \"TOOL_CALL_RESULT\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n const content = getString(\"content\") ?? \"\";\n return withOptional(\n {\n type: \"TOOL_CALL_RESULT\" as const,\n toolCallId,\n content,\n },\n {\n messageId: getString(\"messageId\"),\n role: payload.role === \"tool\" ? \"tool\" : undefined,\n mcpResult: parseMcpToolCallResult(payload, content),\n },\n );\n }\n case \"STATE_SNAPSHOT\":\n return { type: \"STATE_SNAPSHOT\", snapshot: payload.snapshot };\n case \"STATE_DELTA\":\n return {\n type: \"STATE_DELTA\",\n delta: Array.isArray(payload.delta) ? (payload.delta as any[]) : [],\n };\n case \"MESSAGES_SNAPSHOT\":\n return {\n type: \"MESSAGES_SNAPSHOT\",\n messages: Array.isArray(payload.messages)\n ? (payload.messages as any[])\n : [],\n };\n case \"ACTIVITY_SNAPSHOT\": {\n const activityType = getString(\"activityType\");\n if (!activityType || !isPlainObject(payload.content)) return null;\n return withOptional(\n {\n type: \"ACTIVITY_SNAPSHOT\" as const,\n activityType,\n content: payload.content,\n },\n {\n messageId: getString(\"messageId\"),\n replace:\n typeof payload.replace === \"boolean\" ? payload.replace : undefined,\n },\n );\n }\n case \"RAW\":\n return withOptional(\n { type: \"RAW\" as const, event: payload.event },\n { source: getString(\"source\") },\n );\n case \"CUSTOM\": {\n const name = getString(\"name\");\n if (!name) return null;\n return { type: \"CUSTOM\", name, value: payload.value };\n }\n default:\n return withOptional(\n { type: \"RAW\" as const, event: payload },\n {\n source: isString(payload.type) ? (payload.type as string) : undefined,\n },\n );\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"event-parser.js","names":[],"sources":["../../src/runtime/event-parser.ts"],"sourcesContent":["import type { AgUiEvent, AgUiInterrupt, AgUiRunFinishedOutcome } from \"./types\";\nimport type { Logger } from \"./logger\";\nimport { parseMcpToolCallResult } from \"./mcp-tool-result\";\n\nexport type ParseAgUiEventOptions = {\n logger?: Logger;\n};\n\nconst isString = (value: unknown): value is string => typeof value === \"string\";\nconst isNonEmptyString = (value: unknown): value is string =>\n isString(value) && value.length > 0;\n\nconst withOptional = <T extends object>(\n base: T,\n optionals: Record<string, unknown>,\n) => {\n const definedEntries = Object.entries(optionals).filter(\n ([, value]) => value !== undefined,\n );\n return definedEntries.length === 0\n ? base\n : ({ ...base, ...Object.fromEntries(definedEntries) } as T);\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\nconst parseInterrupt = (raw: unknown): AgUiInterrupt | null => {\n if (!isPlainObject(raw)) return null;\n const id = raw.id;\n const reason = raw.reason;\n if (typeof id !== \"string\" || typeof reason !== \"string\") return null;\n const interrupt: AgUiInterrupt = { id, reason };\n if (typeof raw.message === \"string\") interrupt.message = raw.message;\n if (typeof raw.toolCallId === \"string\") interrupt.toolCallId = raw.toolCallId;\n if (typeof raw.expiresAt === \"string\") interrupt.expiresAt = raw.expiresAt;\n if (isPlainObject(raw.responseSchema))\n interrupt.responseSchema = raw.responseSchema;\n if (isPlainObject(raw.metadata)) interrupt.metadata = raw.metadata;\n return interrupt;\n};\n\nconst parseRunFinishedOutcome = (\n raw: unknown,\n logger: Logger | undefined,\n): AgUiRunFinishedOutcome | undefined => {\n if (!isPlainObject(raw)) return undefined;\n if (raw.type === \"success\") return { type: \"success\" };\n if (raw.type === \"interrupt\") {\n if (!Array.isArray(raw.interrupts)) {\n logger?.debug?.(\n \"[agui] RUN_FINISHED interrupt outcome missing interrupts array\",\n raw,\n );\n return undefined;\n }\n const parsed = raw.interrupts\n .map((entry) => parseInterrupt(entry))\n .filter((entry): entry is AgUiInterrupt => entry !== null);\n if (parsed.length === 0) {\n logger?.debug?.(\n \"[agui] RUN_FINISHED interrupt outcome has no valid interrupts\",\n raw.interrupts,\n );\n return undefined;\n }\n return { type: \"interrupt\", interrupts: parsed };\n }\n return undefined;\n};\n\nexport const parseAgUiEvent = (\n event: unknown,\n options?: ParseAgUiEventOptions,\n): AgUiEvent | null => {\n if (!event || typeof event !== \"object\") return null;\n const payload = event as Record<string, unknown>;\n const typeValue = payload.type;\n if (!isString(typeValue)) return null;\n\n const getString = (key: string) =>\n isString(payload[key]) ? (payload[key] as string) : undefined;\n\n switch (typeValue) {\n case \"RUN_STARTED\": {\n const runId = getString(\"runId\");\n return runId ? { type: \"RUN_STARTED\", runId } : null;\n }\n case \"RUN_FINISHED\": {\n const runId = getString(\"runId\");\n if (!runId) return null;\n return withOptional(\n { type: \"RUN_FINISHED\" as const, runId },\n {\n outcome: parseRunFinishedOutcome(payload.outcome, options?.logger),\n },\n );\n }\n case \"RUN_CANCELLED\": {\n const runId = getString(\"runId\");\n return withOptional({ type: \"RUN_CANCELLED\" as const }, { runId });\n }\n case \"RUN_ERROR\": {\n return withOptional(\n { type: \"RUN_ERROR\" as const },\n {\n message: getString(\"message\"),\n code: getString(\"code\"),\n },\n );\n }\n case \"TEXT_MESSAGE_START\":\n return withOptional(\n { type: \"TEXT_MESSAGE_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TEXT_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\");\n if (!isNonEmptyString(delta)) return null;\n return withOptional(\n { type: \"TEXT_MESSAGE_CONTENT\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"TEXT_MESSAGE_END\":\n return withOptional(\n { type: \"TEXT_MESSAGE_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TEXT_MESSAGE_CHUNK\": {\n const delta = getString(\"delta\") ?? \"\";\n return withOptional(\n { type: \"TEXT_MESSAGE_CHUNK\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"THINKING_START\":\n return withOptional(\n { type: \"THINKING_START\" as const },\n { title: getString(\"title\") },\n );\n case \"THINKING_TEXT_MESSAGE_START\":\n return { type: \"THINKING_TEXT_MESSAGE_START\" };\n case \"THINKING_TEXT_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\") ?? \"\";\n return { type: \"THINKING_TEXT_MESSAGE_CONTENT\", delta };\n }\n case \"THINKING_TEXT_MESSAGE_END\":\n return { type: \"THINKING_TEXT_MESSAGE_END\" };\n case \"THINKING_END\":\n return { type: \"THINKING_END\" };\n case \"REASONING_START\":\n return withOptional(\n { type: \"REASONING_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_MESSAGE_START\":\n return withOptional(\n { type: \"REASONING_MESSAGE_START\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_MESSAGE_CONTENT\": {\n const delta = getString(\"delta\") ?? \"\";\n return withOptional(\n { type: \"REASONING_MESSAGE_CONTENT\" as const, delta },\n { messageId: getString(\"messageId\") },\n );\n }\n case \"REASONING_MESSAGE_END\":\n return withOptional(\n { type: \"REASONING_MESSAGE_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"REASONING_ENCRYPTED_VALUE\": {\n const entityId = getString(\"entityId\");\n const encryptedValue = getString(\"encryptedValue\");\n const subtype = getString(\"subtype\");\n if (!entityId || !encryptedValue) return null;\n if (subtype !== \"message\" && subtype !== \"tool-call\") return null;\n return {\n type: \"REASONING_ENCRYPTED_VALUE\" as const,\n subtype,\n entityId,\n encryptedValue,\n };\n }\n case \"REASONING_END\":\n return withOptional(\n { type: \"REASONING_END\" as const },\n { messageId: getString(\"messageId\") },\n );\n case \"TOOL_CALL_START\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n return withOptional(\n { type: \"TOOL_CALL_START\" as const, toolCallId },\n {\n toolCallName: getString(\"toolCallName\"),\n parentMessageId: getString(\"parentMessageId\"),\n },\n );\n }\n case \"TOOL_CALL_ARGS\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n const delta = getString(\"delta\") ?? \"\";\n return { type: \"TOOL_CALL_ARGS\", toolCallId, delta };\n }\n case \"TOOL_CALL_END\": {\n const toolCallId = getString(\"toolCallId\");\n return toolCallId ? { type: \"TOOL_CALL_END\", toolCallId } : null;\n }\n case \"TOOL_CALL_CHUNK\":\n return withOptional(\n { type: \"TOOL_CALL_CHUNK\" as const },\n {\n toolCallId: getString(\"toolCallId\"),\n toolCallName: getString(\"toolCallName\"),\n parentMessageId: getString(\"parentMessageId\"),\n delta: getString(\"delta\"),\n },\n );\n case \"TOOL_CALL_RESULT\": {\n const toolCallId = getString(\"toolCallId\");\n if (!toolCallId) return null;\n const content = getString(\"content\") ?? \"\";\n return withOptional(\n {\n type: \"TOOL_CALL_RESULT\" as const,\n toolCallId,\n content,\n },\n {\n messageId: getString(\"messageId\"),\n role: payload.role === \"tool\" ? \"tool\" : undefined,\n mcpResult: parseMcpToolCallResult(payload, content),\n },\n );\n }\n case \"STATE_SNAPSHOT\":\n return { type: \"STATE_SNAPSHOT\", snapshot: payload.snapshot };\n case \"STATE_DELTA\":\n return {\n type: \"STATE_DELTA\",\n delta: Array.isArray(payload.delta) ? (payload.delta as any[]) : [],\n };\n case \"MESSAGES_SNAPSHOT\":\n return {\n type: \"MESSAGES_SNAPSHOT\",\n messages: Array.isArray(payload.messages)\n ? (payload.messages as any[])\n : [],\n };\n case \"ACTIVITY_SNAPSHOT\": {\n const activityType = getString(\"activityType\");\n if (!activityType || !isPlainObject(payload.content)) return null;\n return withOptional(\n {\n type: \"ACTIVITY_SNAPSHOT\" as const,\n activityType,\n content: payload.content,\n },\n {\n messageId: getString(\"messageId\"),\n replace:\n typeof payload.replace === \"boolean\" ? payload.replace : undefined,\n },\n );\n }\n case \"RAW\":\n return withOptional(\n { type: \"RAW\" as const, event: payload.event },\n { source: getString(\"source\") },\n );\n case \"CUSTOM\": {\n const name = getString(\"name\");\n if (!name) return null;\n return { type: \"CUSTOM\", name, value: payload.value };\n }\n default:\n return withOptional(\n { type: \"RAW\" as const, event: payload },\n {\n source: isString(payload.type) ? (payload.type as string) : undefined,\n },\n );\n }\n};\n"],"mappings":"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"}
@@ -142,6 +142,11 @@ type AgUiEvent = {
142
142
  } | {
143
143
  type: "REASONING_MESSAGE_END";
144
144
  messageId?: string;
145
+ } | {
146
+ type: "REASONING_ENCRYPTED_VALUE";
147
+ subtype: "message" | "tool-call";
148
+ entityId: string;
149
+ encryptedValue: string;
145
150
  } | {
146
151
  type: "REASONING_END";
147
152
  messageId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/runtime/types.ts"],"mappings":";;;;;;;;;;;;KAuBK;EACH,mBAAmB;EACnB,QAAQ;;;;;;EAMR;;KAGU,2BAA2B,KACrC;EAGA,qBAEM,qBACG,QAAQ,wBAAwB;;KAI/B;EACV,cAAc;EACd,SAAS;EACT,YAAY;EACZ,QAAQ;EACR,WAAW;EACX,UAAU;;;;EAIV,aAAa;;KAGH,wBAAwB;EAClC,OAAO;EACP,SAAS,QAAQ;EACjB;;;;;;;;;;;EAWA;;;;;;;EAOA;EACA,WAAW,GAAG;EACd;EACA,WAAW;;KAGD;KAMA;EACV;EACA,QAAQ;EACR;EACA;EACA,iBAAiB;EACjB;EACA,WAAW;;KAGD;EACV;EACA;EACA;;KAGU;EACV,qBAAqB;EACrB,iBAAiB,QAAQ;EACzB,2BACE,oBAAoB,sBACjB;EACL,YACE,SAAS,qBACT,qBAAqB,sBAClB;EACL,OAAO;EACP,WACE,MACI,sBACE,MAAM,kCAAkC;;KAItC;EACN;;EACA;EAAmB,YAAY;;KAEzB;EACN;EAAqB;;EAErB;EACA;EACA,UAAU;;EAEV;EAAuB;;EACvB;EAAmB;EAAkB;;EACrC;EAA4B;;EAC5B;EAA8B;EAAoB;;EAClD;EAA0B;;EAC1B;EAA4B;;EAC5B;EAAwB;;EACxB;;EACA;EAAuC;;EACvC;;EACA;;EACA;EAAyB;;EACzB;EAAiC;;EACjC;EAAmC;EAAoB;;EACvD;EAA+B;;EAC/B;EAAuB;;EAEvB;EACA;EACA;EACA;;EAEA;EAAwB;EAAoB;;EAC5C;EAAuB;;EAEvB;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA,YAAY;;EAGZ;EACA;EACA,SAAS;EACT;EACA;;EAEA;EAAa;EAAY;;EACzB;EAAgB;EAAc;;EAC9B;EAAwB;;EACxB;EAAqB;;EACrB;EAA2B"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/runtime/types.ts"],"mappings":";;;;;;;;;;;;KAuBK;EACH,mBAAmB;EACnB,QAAQ;;;;;;EAMR;;KAGU,2BAA2B,KACrC;EAGA,qBAEM,qBACG,QAAQ,wBAAwB;;KAI/B;EACV,cAAc;EACd,SAAS;EACT,YAAY;EACZ,QAAQ;EACR,WAAW;EACX,UAAU;;;;EAIV,aAAa;;KAGH,wBAAwB;EAClC,OAAO;EACP,SAAS,QAAQ;EACjB;;;;;;;;;;;EAWA;;;;;;;EAOA;EACA,WAAW,GAAG;EACd;EACA,WAAW;;KAGD;KAMA;EACV;EACA,QAAQ;EACR;EACA;EACA,iBAAiB;EACjB;EACA,WAAW;;KAGD;EACV;EACA;EACA;;KAGU;EACV,qBAAqB;EACrB,iBAAiB,QAAQ;EACzB,2BACE,oBAAoB,sBACjB;EACL,YACE,SAAS,qBACT,qBAAqB,sBAClB;EACL,OAAO;EACP,WACE,MACI,sBACE,MAAM,kCAAkC;;KAItC;EACN;;EACA;EAAmB,YAAY;;KAEzB;EACN;EAAqB;;EAErB;EACA;EACA,UAAU;;EAEV;EAAuB;;EACvB;EAAmB;EAAkB;;EACrC;EAA4B;;EAC5B;EAA8B;EAAoB;;EAClD;EAA0B;;EAC1B;EAA4B;;EAC5B;EAAwB;;EACxB;;EACA;EAAuC;;EACvC;;EACA;;EACA;EAAyB;;EACzB;EAAiC;;EACjC;EAAmC;EAAoB;;EACvD;EAA+B;;EAE/B;EACA;EACA;EACA;;EAEA;EAAuB;;EAEvB;EACA;EACA;EACA;;EAEA;EAAwB;EAAoB;;EAC5C;EAAuB;;EAEvB;EACA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA,YAAY;;EAGZ;EACA;EACA,SAAS;EACT;EACA;;EAEA;EAAa;EAAY;;EACzB;EAAgB;EAAc;;EAC9B;EAAwB;;EACxB;EAAqB;;EACrB;EAA2B"}
@@ -102,7 +102,7 @@ function useAgUiRuntime(options) {
102
102
  threadList
103
103
  ]);
104
104
  const shared = useExternalStoreSharedOptions(options);
105
- const baseRuntime = useExternalStoreRuntime(useMemo(() => {
105
+ const store = useMemo(() => {
106
106
  return {
107
107
  ...shared,
108
108
  isLoading: core.isLoading,
@@ -129,7 +129,7 @@ function useAgUiRuntime(options) {
129
129
  return core.reload(parentId, config);
130
130
  },
131
131
  onCancel: async () => {
132
- queueController?.clear();
132
+ queueController?.notifyCancelled();
133
133
  core.cancel();
134
134
  },
135
135
  onAddToolResult: (options) => core.addToolResult(options),
@@ -149,7 +149,8 @@ function useAgUiRuntime(options) {
149
149
  queueItems,
150
150
  steerQueueItems,
151
151
  shared
152
- ]));
152
+ ]);
153
+ const baseRuntime = useExternalStoreRuntime(store);
153
154
  const runtime = useMemo(() => {
154
155
  const wrapper = Object.create(baseRuntime);
155
156
  wrapper.unstable_getPendingInterrupts = () => core.getPendingInterrupts()?.interrupts ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { createMessageQueue } from \"@assistant-ui/core\";\nimport type {\n MessageQueueController,\n ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);\nconst subscribeNoop = () => () => {};\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n /**\n * @deprecated Use the `useAgUiInterrupts()` hook instead. This method is kept\n * for backward compatibility and will be removed in a future major release.\n */\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n /**\n * @deprecated Use the `useAgUiSubmitInterruptResponses()` hook instead. This\n * method is kept for backward compatibility and will be removed in a future\n * major release.\n */\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning = core.isRunning() || hasExecutingTools;\n\n // The driver sends through the agent core rather than the runtime, because\n // the runtime's append routes every tail append back into this queue.\n const queueRef = useRef<MessageQueueController | null>(null);\n // Counts rendered busy edges, whether a run start or an interrupt arriving.\n // A dispatch whose count never moves was never observed as busy, so no\n // falling edge is coming to release the queue.\n const busyEdgesRef = useRef(0);\n if (options.unstable_enableMessageQueue && !queueRef.current) {\n queueRef.current = createMessageQueue({\n run: (message) => {\n const controller = queueRef.current;\n const edgesAtDispatch = busyEdgesRef.current;\n // The queue drops the item before dispatching and stays busy until an\n // idle edge. An append observed as busy is released by that falling\n // edge, and releasing again here would advance the queue twice; one\n // that never runs (a pre-run rejection, or startRun false) has to be\n // released here or every later send buffers forever. An interrupt is\n // rechecked because a run that resolves without yielding to React\n // reaches here before the effect below has seen either edge.\n const releaseIfNoRun = () => {\n if (\n queueRef.current !== controller ||\n busyEdgesRef.current !== edgesAtDispatch ||\n core.getPendingInterrupts() !== null\n )\n return;\n controller?.notifyIdle();\n };\n void core.append(message).then(releaseIfNoRun, (e: unknown) => {\n releaseIfNoRun();\n logger.error?.(\"[agui] queued message failed to send\", e);\n });\n },\n });\n } else if (!options.unstable_enableMessageQueue && queueRef.current) {\n queueRef.current.clear();\n queueRef.current = null;\n }\n const queueController = options.unstable_enableMessageQueue\n ? queueRef.current\n : null;\n\n // Feeds the store memo below: the runtime core skips an adapter whose\n // identity is unchanged, so queue items have to move the store reference or\n // subscribers never see composer.queue change.\n const queueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.items ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n const steerQueueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n\n // Holds the queue while client-side tools are still executing, and while an\n // interrupt is unanswered: `append` refuses a new run until it is resolved,\n // and the queue drops an item before dispatching it, so draining into that\n // refusal would lose the message instead of keeping it visible.\n const queueBusy = isRunning || core.getPendingInterrupts() !== null;\n useEffect(() => {\n if (queueBusy) {\n busyEdgesRef.current++;\n queueController?.notifyBusy();\n } else {\n queueController?.notifyIdle();\n }\n }, [queueBusy, queueController]);\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread, ...rest } =\n threadListAdapter;\n\n return {\n ...rest,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n core.resetState();\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n if (result.state !== undefined) {\n core.loadExternalState(result.state);\n } else {\n core.resetState();\n }\n if (result.unstable_resume) {\n void core.resumeInFlightRun(result.messages);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(\n () => {\n void _version; // rerender on version change\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messageRepository: core.getMessageRepository(),\n state: core.getState(),\n isRunning,\n extras: agUiExtras.provide({\n interrupts:\n core.getPendingInterrupts()?.interrupts ?? EMPTY_INTERRUPTS,\n sendA2uiAction: (action) => core.sendA2uiAction(action),\n submitInterruptResponses: (responses) =>\n core.submitInterruptResponses(responses),\n steerAway: (message, responses) => core.steerAway(message, responses),\n state: core.getState(),\n setState: (next) => core.setState(next),\n }),\n unstable_enableToolInvocations: true,\n setToolStatuses,\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => {\n queueController?.clear();\n return core.edit(message);\n },\n onReload: (parentId: string | null, config: { runConfig?: any }) => {\n queueController?.clear();\n return core.reload(parentId, config);\n },\n onCancel: async () => {\n queueController?.clear();\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n ...(queueController && { queue: queueController.adapter }),\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [\n adapterAdapters,\n core,\n _version,\n isRunning,\n queueController,\n queueItems,\n steerQueueItems,\n shared,\n ],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const runtime = useMemo<AgUiAssistantRuntime>(() => {\n const wrapper = Object.create(baseRuntime) as AgUiAssistantRuntime;\n wrapper.unstable_getPendingInterrupts = () =>\n core.getPendingInterrupts()?.interrupts ?? [];\n wrapper.unstable_submitInterruptResponses = (responses) =>\n core.submitInterruptResponses(responses);\n return wrapper;\n }, [baseRuntime, core]);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAgUiRuntime.js","names":[],"sources":["../src/useAgUiRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n useExternalStoreRuntime,\n useExternalStoreSharedOptions,\n useRuntimeAdapters,\n} from \"@assistant-ui/core/react\";\nimport { createMessageQueue } from \"@assistant-ui/core\";\nimport type {\n MessageQueueController,\n ToolExecutionStatus,\n} from \"@assistant-ui/core\";\nimport type {\n AssistantRuntime,\n AppendMessage,\n ExternalStoreAdapter,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { makeLogger } from \"./runtime/logger\";\nimport type {\n AgUiInterrupt,\n AgUiResumeEntry,\n UseAgUiRuntimeOptions,\n} from \"./runtime/types\";\nimport { AgUiThreadRuntimeCore } from \"./runtime/AgUiThreadRuntimeCore\";\nimport { agUiExtras } from \"./agUiExtras\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\n\nconst EMPTY_INTERRUPTS: readonly AgUiInterrupt[] = [];\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);\nconst subscribeNoop = () => () => {};\n\nexport type AgUiAssistantRuntime = AssistantRuntime & {\n /**\n * @deprecated Use the `useAgUiInterrupts()` hook instead. This method is kept\n * for backward compatibility and will be removed in a future major release.\n */\n unstable_getPendingInterrupts: () => readonly AgUiInterrupt[];\n /**\n * @deprecated Use the `useAgUiSubmitInterruptResponses()` hook instead. This\n * method is kept for backward compatibility and will be removed in a future\n * major release.\n */\n unstable_submitInterruptResponses: (\n responses: readonly AgUiResumeEntry[],\n ) => Promise<void>;\n};\n\nexport function useAgUiRuntime(\n options: UseAgUiRuntimeOptions,\n): AgUiAssistantRuntime {\n const logger = useMemo(() => makeLogger(options.logger), [options.logger]);\n const [_version, setVersion] = useState(0);\n const notifyUpdate = useCallback(() => setVersion((v) => v + 1), []);\n const coreRef = useRef<AgUiThreadRuntimeCore | null>(null);\n const runtimeAdapters = useRuntimeAdapters();\n\n const historyAdapter = options.adapters?.history ?? runtimeAdapters?.history;\n const threadListAdapter = options.adapters?.threadList;\n\n if (!coreRef.current) {\n coreRef.current = new AgUiThreadRuntimeCore({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n notifyUpdate,\n });\n }\n\n const core = coreRef.current;\n core.updateOptions({\n agent: options.agent,\n logger,\n showThinking: options.showThinking ?? true,\n autoCancelPendingToolCalls: options.autoCancelPendingToolCalls,\n ...(options.onError && { onError: options.onError }),\n ...(options.onCancel && { onCancel: options.onCancel }),\n ...(historyAdapter && { history: historyAdapter }),\n });\n\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n const hasExecutingTools = Object.values(toolStatuses).some(\n (s) => s?.type === \"executing\",\n );\n const isRunning = core.isRunning() || hasExecutingTools;\n\n // The driver sends through the agent core rather than the runtime, because\n // the runtime's append routes every tail append back into this queue.\n const queueRef = useRef<MessageQueueController | null>(null);\n // Counts rendered busy edges, whether a run start or an interrupt arriving.\n // A dispatch whose count never moves was never observed as busy, so no\n // falling edge is coming to release the queue.\n const busyEdgesRef = useRef(0);\n if (options.unstable_enableMessageQueue && !queueRef.current) {\n queueRef.current = createMessageQueue({\n run: (message) => {\n const controller = queueRef.current;\n const edgesAtDispatch = busyEdgesRef.current;\n // The queue drops the item before dispatching and stays busy until an\n // idle edge. An append observed as busy is released by that falling\n // edge, and releasing again here would advance the queue twice; one\n // that never runs (a pre-run rejection, or startRun false) has to be\n // released here or every later send buffers forever. An interrupt is\n // rechecked because a run that resolves without yielding to React\n // reaches here before the effect below has seen either edge.\n const releaseIfNoRun = () => {\n if (\n queueRef.current !== controller ||\n busyEdgesRef.current !== edgesAtDispatch ||\n core.getPendingInterrupts() !== null\n )\n return;\n controller?.notifyIdle();\n };\n void core.append(message).then(releaseIfNoRun, (e: unknown) => {\n releaseIfNoRun();\n logger.error?.(\"[agui] queued message failed to send\", e);\n });\n },\n });\n } else if (!options.unstable_enableMessageQueue && queueRef.current) {\n queueRef.current.clear();\n queueRef.current = null;\n }\n const queueController = options.unstable_enableMessageQueue\n ? queueRef.current\n : null;\n\n // Feeds the store memo below: the runtime core skips an adapter whose\n // identity is unchanged, so queue items have to move the store reference or\n // subscribers never see composer.queue change.\n const queueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.items ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n const steerQueueItems = useSyncExternalStore(\n queueController?.subscribe ?? subscribeNoop,\n () => queueController?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS,\n () => EMPTY_QUEUE_ITEMS,\n );\n\n // Holds the queue while client-side tools are still executing, and while an\n // interrupt is unanswered: `append` refuses a new run until it is resolved,\n // and the queue drops an item before dispatching it, so draining into that\n // refusal would lose the message instead of keeping it visible.\n const queueBusy = isRunning || core.getPendingInterrupts() !== null;\n useEffect(() => {\n if (queueBusy) {\n busyEdgesRef.current++;\n queueController?.notifyBusy();\n } else {\n queueController?.notifyIdle();\n }\n }, [queueBusy, queueController]);\n\n const threadList = useMemo(() => {\n if (!threadListAdapter) return undefined;\n\n const { onSwitchToNewThread, onSwitchToThread, ...rest } =\n threadListAdapter;\n\n return {\n ...rest,\n onSwitchToNewThread: onSwitchToNewThread\n ? async () => {\n await onSwitchToNewThread();\n core.applyExternalMessages([]);\n core.resetState();\n }\n : undefined,\n onSwitchToThread: onSwitchToThread\n ? async (threadId: string) => {\n // Clear before the thread id flips, or the old messages leak\n // into the new thread as a sibling branch.\n core.applyExternalMessages([]);\n const result = await onSwitchToThread(threadId);\n core.applyExternalMessages(result.messages);\n if (result.state !== undefined) {\n core.loadExternalState(result.state);\n } else {\n core.resetState();\n }\n if (result.unstable_resume) {\n void core.resumeInFlightRun(result.messages);\n }\n }\n : undefined,\n };\n }, [threadListAdapter, core]);\n\n const adapters = options.adapters;\n const adapterAdapters = useMemo(\n () => ({\n attachments: adapters?.attachments ?? runtimeAdapters?.attachments,\n speech: adapters?.speech,\n dictation: adapters?.dictation,\n voice: adapters?.voice,\n feedback: adapters?.feedback,\n threadList,\n }),\n [adapters, runtimeAdapters, threadList],\n );\n\n const shared = useExternalStoreSharedOptions(options);\n const store = useMemo(\n () => {\n void _version; // rerender on version change\n\n return {\n ...shared,\n isLoading: core.isLoading,\n messageRepository: core.getMessageRepository(),\n state: core.getState(),\n isRunning,\n extras: agUiExtras.provide({\n interrupts:\n core.getPendingInterrupts()?.interrupts ?? EMPTY_INTERRUPTS,\n sendA2uiAction: (action) => core.sendA2uiAction(action),\n submitInterruptResponses: (responses) =>\n core.submitInterruptResponses(responses),\n steerAway: (message, responses) => core.steerAway(message, responses),\n state: core.getState(),\n setState: (next) => core.setState(next),\n }),\n unstable_enableToolInvocations: true,\n setToolStatuses,\n onNew: (message: AppendMessage) => core.append(message),\n onEdit: (message: AppendMessage) => {\n queueController?.clear();\n return core.edit(message);\n },\n onReload: (parentId: string | null, config: { runConfig?: any }) => {\n queueController?.clear();\n return core.reload(parentId, config);\n },\n onCancel: async () => {\n queueController?.notifyCancelled();\n core.cancel();\n },\n onAddToolResult: (options) => core.addToolResult(options),\n onResume: (config) => core.resume(config),\n setMessages: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onImport: (messages: readonly ThreadMessage[]) =>\n core.applyExternalMessages(messages),\n onLoadExternalState: (state: ReadonlyJSONValue) =>\n core.loadExternalState(state),\n adapters: adapterAdapters,\n ...(queueController && { queue: queueController.adapter }),\n } satisfies ExternalStoreAdapter<ThreadMessage>;\n },\n // _version is intentionally included to trigger re-computation when core state changes via notifyUpdate\n // toolInvocations intentionally excluded: abort/resume use refs internally and work with stale captures\n [\n adapterAdapters,\n core,\n _version,\n isRunning,\n queueController,\n queueItems,\n steerQueueItems,\n shared,\n ],\n );\n\n const baseRuntime = useExternalStoreRuntime(store);\n\n const runtime = useMemo<AgUiAssistantRuntime>(() => {\n const wrapper = Object.create(baseRuntime) as AgUiAssistantRuntime;\n wrapper.unstable_getPendingInterrupts = () =>\n core.getPendingInterrupts()?.interrupts ?? [];\n wrapper.unstable_submitInterruptResponses = (responses) =>\n core.submitInterruptResponses(responses);\n return wrapper;\n }, [baseRuntime, core]);\n\n useEffect(() => {\n core.attachRuntime(runtime);\n return () => {\n core.detachRuntime();\n };\n }, [core, runtime]);\n\n useEffect(() => {\n core.__internal_load();\n }, [core]);\n\n return runtime;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-ag-ui",
3
- "version": "0.0.52",
3
+ "version": "0.0.54",
4
4
  "description": "AG-UI protocol adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "ag-ui",
@@ -30,10 +30,10 @@
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
32
  "@ag-ui/client": "^0.0.57",
33
- "@assistant-ui/core": "^0.3.8",
34
- "@assistant-ui/react-generative-ui": "^0.0.12",
35
- "@assistant-ui/store": "^0.3.7",
36
- "assistant-stream": "^0.3.35",
33
+ "@assistant-ui/core": "^0.3.13",
34
+ "@assistant-ui/react-generative-ui": "^0.0.14",
35
+ "@assistant-ui/store": "^0.3.9",
36
+ "assistant-stream": "^0.3.36",
37
37
  "fast-json-patch": "^3.1.1"
38
38
  },
39
39
  "peerDependencies": {
@@ -48,12 +48,12 @@
48
48
  "devDependencies": {
49
49
  "@testing-library/dom": "^10.4.1",
50
50
  "@testing-library/react": "^16.3.2",
51
- "@types/react": "^19.2.17",
52
- "jsdom": "^29.1.1",
51
+ "@types/react": "^19.2.18",
52
+ "jsdom": "^30.0.1",
53
53
  "react": "^19.2.8",
54
54
  "vitest": "^4.1.10",
55
55
  "zod": "^4.4.3",
56
- "@assistant-ui/x-buildutils": "0.0.21"
56
+ "@assistant-ui/x-buildutils": "0.0.22"
57
57
  },
58
58
  "publishConfig": {
59
59
  "access": "public",
@@ -120,6 +120,26 @@ const invokeRuntimeCallback = <TArgs extends unknown[]>(
120
120
  }
121
121
  };
122
122
 
123
+ // The aggregator only ever sends the interrupts it owns, so a shallow spread at
124
+ // the custom level would drop sibling agui state such as opaqueReasoning.
125
+ const mergeAgUiNamespace = (
126
+ current: Record<string, unknown> | undefined,
127
+ incoming: Record<string, unknown>,
128
+ ) => {
129
+ const merged = { ...current, ...incoming };
130
+ const currentNs = current?.[AG_UI_METADATA_NAMESPACE];
131
+ const incomingNs = incoming[AG_UI_METADATA_NAMESPACE];
132
+ if (
133
+ typeof currentNs === "object" &&
134
+ currentNs !== null &&
135
+ typeof incomingNs === "object" &&
136
+ incomingNs !== null
137
+ ) {
138
+ merged[AG_UI_METADATA_NAMESPACE] = { ...currentNs, ...incomingNs };
139
+ }
140
+ return merged;
141
+ };
142
+
123
143
  export class AgUiThreadRuntimeCore {
124
144
  private agent: AbstractAgent;
125
145
  private logger: Logger;
@@ -1456,7 +1476,7 @@ export class AgUiThreadRuntimeCore {
1456
1476
  ...(current.isOptimistic ? { isOptimistic: true } : {}),
1457
1477
  ...(incoming.timing ? { timing: incoming.timing } : {}),
1458
1478
  custom: incoming.custom
1459
- ? { ...current.custom, ...incoming.custom }
1479
+ ? mergeAgUiNamespace(current.custom, incoming.custom)
1460
1480
  : current.custom,
1461
1481
  };
1462
1482
  }