@assistant-ui/react-ag-ui 0.0.71 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agUiExtras.js +1 -2
- package/dist/hooks.js +1 -2
- package/dist/runtime/{AgUiThreadRuntimeCore.d.ts → AgUiThreadController.d.ts} +6 -12
- package/dist/runtime/AgUiThreadController.d.ts.map +1 -0
- package/dist/runtime/{AgUiThreadRuntimeCore.js → AgUiThreadController.js} +567 -194
- package/dist/runtime/AgUiThreadController.js.map +1 -0
- package/dist/runtime/adapter/conversions.d.ts +4 -4
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +120 -35
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/replay-content.d.ts +9 -0
- package/dist/runtime/adapter/replay-content.d.ts.map +1 -0
- package/dist/runtime/adapter/replay-content.js +185 -0
- package/dist/runtime/adapter/replay-content.js.map +1 -0
- package/dist/runtime/adapter/run-aggregator.d.ts +3 -5
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +48 -63
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts +0 -24
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/subscriber.js +2 -24
- package/dist/runtime/adapter/subscriber.js.map +1 -1
- package/dist/runtime/adapter/tool-approval.d.ts +2 -0
- package/dist/runtime/adapter/tool-approval.d.ts.map +1 -1
- package/dist/runtime/adapter/tool-approval.js +23 -6
- package/dist/runtime/adapter/tool-approval.js.map +1 -1
- package/dist/runtime/agUiThreadState.d.ts +60 -0
- package/dist/runtime/agUiThreadState.d.ts.map +1 -0
- package/dist/runtime/agUiThreadState.js +94 -0
- package/dist/runtime/agUiThreadState.js.map +1 -0
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/event-parser.js +46 -50
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/interrupt-internals.js +1 -2
- package/dist/runtime/logger.js +1 -2
- package/dist/runtime/mcp-tool-result.d.ts +3 -1
- package/dist/runtime/mcp-tool-result.d.ts.map +1 -1
- package/dist/runtime/mcp-tool-result.js +7 -5
- package/dist/runtime/mcp-tool-result.js.map +1 -1
- package/dist/runtime/types.d.ts +11 -35
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js +1 -2
- package/dist/runtime/types.js.map +1 -1
- package/dist/useAgUiRuntime.js +3 -4
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +12 -11
- package/src/runtime/AgUiThreadController.deferred-results.test.ts +548 -0
- package/src/runtime/{AgUiThreadRuntimeCore.interrupt-cancel.test.ts → AgUiThreadController.interrupt-cancel.test.ts} +4 -4
- package/src/runtime/AgUiThreadController.replay.test.ts +3932 -0
- package/src/runtime/{AgUiThreadRuntimeCore.test.ts → AgUiThreadController.test.ts} +114 -6
- package/src/runtime/{AgUiThreadRuntimeCore.ts → AgUiThreadController.ts} +1037 -236
- package/src/runtime/adapter/conversions.content.test.ts +149 -5
- package/src/runtime/adapter/conversions.tools.test.ts +2 -1
- package/src/runtime/adapter/conversions.ts +249 -62
- package/src/runtime/adapter/replay-content.test.ts +235 -0
- package/src/runtime/adapter/replay-content.ts +306 -0
- package/src/runtime/adapter/run-aggregator.ts +79 -114
- package/src/runtime/adapter/subscriber.ts +1 -44
- package/src/runtime/adapter/tool-approval.ts +41 -3
- package/src/runtime/agUiThreadState.test.ts +224 -0
- package/src/runtime/agUiThreadState.ts +139 -0
- package/src/runtime/event-parser.ts +40 -58
- package/src/runtime/mcp-tool-result.ts +16 -2
- package/src/runtime/types.ts +16 -28
- package/src/useAgUiRuntime.fast-refresh.test.tsx +3 -3
- package/src/useAgUiRuntime.thread-switch.test.tsx +4 -4
- package/src/useAgUiRuntime.ts +3 -3
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +0 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversions.js","names":[],"sources":["../../../src/runtime/adapter/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type { InputContent, RunAgentParameters } from \"@ag-ui/client\";\nimport { generateId } from \"@assistant-ui/core\";\nimport type {\n ThreadMessageLike as CoreThreadMessageLike,\n PartProviderMetadata,\n ReasoningMessagePart,\n} from \"@assistant-ui/core\";\nimport {\n getAutoStatus,\n parseDataUrl,\n resolveFilePartSource,\n resolveImageMediaType,\n walkToolCallTree,\n} from \"@assistant-ui/core/internal\";\nimport { type Tool, toToolsJSONSchema } from \"assistant-stream\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n A2UI_SURFACE_ACTIVITY_TYPE,\n MCP_APPS_ACTIVITY_TYPE,\n type AgUiCustomMetadata,\n type AgUiOpaqueReasoning,\n} from \"../types\";\nimport {\n applyA2uiOperations,\n surfaceToPresentToolCall,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/generative-ui/a2ui\";\nimport type { AgUiInterrupt } from \"../types\";\nimport { projectAgUiToolApprovals } from \"./tool-approval\";\nimport {\n parseMcpToolCallResult,\n readMcpAppResourceUri,\n} from \"../mcp-tool-result\";\n\nexport type { InputContent };\n\ntype AttachmentLike = {\n name?: string | undefined;\n contentType?: string | undefined;\n content?: readonly unknown[] | undefined;\n};\n\ntype ThreadMessageLike = {\n id?: string | undefined;\n role: string;\n content: unknown;\n metadata?: unknown;\n name?: string | undefined;\n toolCallId?: string | undefined;\n error?: string | undefined;\n attachments?: readonly AttachmentLike[] | undefined;\n};\n\ntype NormalizedThreadMessageLike = ThreadMessageLike & { id: string };\n\ntype AgUiToolCall = {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n};\n\nexport type AgUiMessage =\n | {\n id: string;\n role: \"user\";\n content: string | InputContent[];\n name?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"assistant\";\n content: string;\n name?: string;\n toolCalls?: AgUiToolCall[];\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"system\" | \"developer\";\n content: string;\n name?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"reasoning\";\n content: string;\n encryptedValue?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"tool\";\n content: string;\n toolCallId: string;\n error?: string;\n metadata?: Record<string, unknown>;\n };\n\ntype CoreToolCallPart = Extract<\n Exclude<CoreThreadMessageLike[\"content\"], string>[number],\n { type: \"tool-call\" }\n>;\n\ntype ToolCallPart = Omit<CoreToolCallPart, \"result\" | \"isError\"> & {\n result?: unknown;\n isError?: boolean | undefined;\n /** @deprecated Experimental since 2026-03-08. Not scheduled for removal; the API may change in any release. */\n unstable_toolMessageId?: string;\n};\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst getString = (record: Record<string, unknown>, key: string) => {\n const value = record[key];\n return typeof value === \"string\" ? value : undefined;\n};\n\nfunction toAgUiWireMetadata(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n return isObject(metadata) ? { ...metadata } : undefined;\n}\n\nfunction readLegacyAgUiNamespace(metadata: unknown): Record<string, unknown> {\n if (!isObject(metadata) || !isObject(metadata.custom)) return {};\n const namespaced = metadata.custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return {};\n return \"interrupts\" in namespaced\n ? { interrupts: namespaced.interrupts }\n : {};\n}\n\nfunction withoutPersistedInterrupts(\n wire: Record<string, unknown>,\n): Record<string, unknown> {\n if (!isObject(wire.custom)) return wire;\n const namespaced = wire.custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced) || !(\"interrupts\" in namespaced)) return wire;\n\n const { interrupts: _interrupts, ...remainingNamespace } = namespaced;\n const { [AG_UI_METADATA_NAMESPACE]: _namespace, ...remainingCustom } =\n wire.custom;\n if (Object.keys(remainingNamespace).length > 0) {\n remainingCustom[AG_UI_METADATA_NAMESPACE] = remainingNamespace;\n }\n const { custom: _custom, ...remainingWire } = wire;\n return Object.keys(remainingCustom).length > 0\n ? { ...remainingWire, custom: remainingCustom }\n : remainingWire;\n}\n\nfunction toSnapshotCustom(\n metadata: unknown,\n state: Record<string, unknown> = {},\n): Record<string, unknown> {\n const wire = withoutPersistedInterrupts(toAgUiWireMetadata(metadata) ?? {});\n const needsWireSlot =\n isObject(metadata) &&\n (Object.keys(metadata).length === 0 || AG_UI_METADATA_NAMESPACE in wire);\n const namespaced = {\n ...readLegacyAgUiNamespace(metadata),\n ...state,\n ...(needsWireSlot ? { messageMetadata: wire } : {}),\n };\n return {\n ...wire,\n ...(Object.keys(namespaced).length > 0\n ? { [AG_UI_METADATA_NAMESPACE]: namespaced }\n : {}),\n };\n}\n\nfunction toAgUiMessageMetadata(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n const custom = readCustomMetadata(metadata);\n const namespaced = readNamespacedMetadata(metadata);\n if (isObject(namespaced.messageMetadata)) {\n return { ...namespaced.messageMetadata };\n }\n const { [AG_UI_METADATA_NAMESPACE]: _state, ...wire } = custom;\n return Object.keys(wire).length > 0 ? wire : undefined;\n}\n\nfunction withAgUiMessageMetadata(metadata: unknown): {\n metadata?: Record<string, unknown>;\n} {\n const messageMetadata = toAgUiMessageMetadata(metadata);\n return messageMetadata !== undefined ? { metadata: messageMetadata } : {};\n}\n\nfunction withAgUiPartMessageMetadata(\n providerMetadata: PartProviderMetadata | undefined,\n messageMetadata: Record<string, unknown> | undefined,\n): PartProviderMetadata {\n if (!messageMetadata) return providerMetadata ?? {};\n\n const existing = providerMetadata ?? {};\n const namespaced = isObject(existing[AG_UI_METADATA_NAMESPACE])\n ? existing[AG_UI_METADATA_NAMESPACE]\n : {};\n return {\n ...existing,\n [AG_UI_METADATA_NAMESPACE]: {\n ...namespaced,\n messageMetadata: messageMetadata as ReadonlyJSONObject,\n },\n };\n}\n\nfunction readAgUiPartMessageMetadata(\n providerMetadata: unknown,\n): Record<string, unknown> | undefined {\n const namespaced = readAgUiNamespace(providerMetadata);\n return namespaced && isObject(namespaced.messageMetadata)\n ? toAgUiWireMetadata(namespaced.messageMetadata)\n : undefined;\n}\n\nconst getToolCallId = (record: Record<string, unknown>) =>\n getString(record, \"toolCallId\") ?? getString(record, \"tool_call_id\");\n\nconst readAgUiNamespace = (providerMetadata: unknown) => {\n if (!isObject(providerMetadata)) return undefined;\n const namespaced = providerMetadata[AG_UI_METADATA_NAMESPACE];\n return isObject(namespaced) ? namespaced : undefined;\n};\n\nconst readAgUiReasoningMeta = (providerMetadata: unknown) => {\n const namespaced = readAgUiNamespace(providerMetadata);\n if (!namespaced) return {};\n return {\n encryptedValue: getString(namespaced, \"encryptedValue\"),\n reasoningId: getString(namespaced, \"reasoningId\"),\n messageMetadata: toAgUiWireMetadata(namespaced.messageMetadata),\n };\n};\n\n// AG-UI carries per-item extras in `metadata`; anything else on the item is\n// stripped by its schema. The part's own `filename` wins over a key of the\n// same name in the bag.\nconst buildInputMetadata = (\n part: Record<string, unknown>,\n filename?: string | undefined,\n) => {\n const metadata = {\n ...readAgUiNamespace(part.providerMetadata),\n ...(filename !== undefined && { filename }),\n };\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n};\n\n// The inverse: `filename` lands on the part's own field, everything else the\n// item carried goes back into the namespace it came from, so a snapshot echo\n// resends what the host attached.\nconst readInputMetadata = (\n metadata: unknown,\n): {\n filename?: string | undefined;\n providerMetadata?: PartProviderMetadata | undefined;\n} => {\n if (!isObject(metadata)) return {};\n const { filename: _filename, ...rest } = metadata;\n return {\n filename: getString(metadata, \"filename\"),\n ...(Object.keys(rest).length > 0 && {\n providerMetadata: {\n [AG_UI_METADATA_NAMESPACE]: rest as PartProviderMetadata[string],\n },\n }),\n };\n};\n\nfunction parseJSONText(value: string): unknown {\n if (!value) return value;\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction normalizeToolCall(part: ToolCallPart): {\n id: string;\n call: AgUiToolCall;\n} {\n const id = part.toolCallId ?? generateId();\n const argsText =\n typeof part.argsText === \"string\"\n ? part.argsText\n : JSON.stringify(part.args ?? {});\n\n return {\n id,\n call: {\n id,\n type: \"function\",\n function: {\n name: part.toolName ?? \"tool\",\n arguments: argsText,\n },\n },\n };\n}\n\nconst isExportableNestedToolCall = (part: { readonly toolCallId?: unknown }) =>\n typeof part.toolCallId === \"string\" && !part.toolCallId.startsWith(\"a2ui:\");\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n\n return content\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n part?.type === \"text\" && typeof part?.text === \"string\",\n )\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\ntype InputContentSource =\n | { type: \"data\"; value: string; mimeType: string }\n | { type: \"url\"; value: string; mimeType?: string };\n\ntype MediaInputType = \"image\" | \"audio\" | \"video\" | \"document\";\n\nfunction mediaTypeForMime(mimeType: string | undefined): MediaInputType {\n if (mimeType?.startsWith(\"image/\")) return \"image\";\n if (mimeType?.startsWith(\"audio/\")) return \"audio\";\n if (mimeType?.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\n// Build an AG-UI multimodal source from a data URL, raw base64 payload, or an\n// http(s) URL. A `url` source may omit the mime type; a `data` source always\n// resolves one (falling back to application/octet-stream). An explicit\n// `sourceType: \"url\"` on the part forces the url leg for non-http references,\n// and a data URL that is not base64 takes it too, since a `data` source\n// carries base64 bytes.\nfunction buildInputSource(\n value: string,\n declaredMimeType: string | undefined,\n sourceType?: string,\n): InputContentSource {\n const source = resolveFilePartSource({\n data: value,\n mimeType: declaredMimeType ?? \"application/octet-stream\",\n sourceType:\n /^data:/i.test(value) && !parseDataUrl(value) ? \"url\" : sourceType,\n });\n if (source.kind === \"url\") {\n return declaredMimeType !== undefined\n ? { type: \"url\", value: source.url, mimeType: declaredMimeType }\n : { type: \"url\", value: source.url };\n }\n return {\n type: \"data\",\n value: source.data,\n mimeType: source.mimeType,\n };\n}\n\nfunction toInputContent(\n part: unknown,\n fallbackMimeType: string | undefined,\n): InputContent | null {\n if (!isObject(part)) return null;\n const type = getString(part, \"type\");\n\n if (type === \"text\") {\n const text = getString(part, \"text\");\n if (text === undefined) return null;\n return { type: \"text\", text };\n }\n\n if (type === \"image\") {\n const image = getString(part, \"image\");\n if (image === undefined) return null;\n const metadata = buildInputMetadata(part, getString(part, \"filename\"));\n const source = buildInputSource(image, fallbackMimeType);\n return {\n type: \"image\",\n source:\n source.type === \"data\"\n ? {\n ...source,\n mimeType: resolveImageMediaType(image, fallbackMimeType),\n }\n : source,\n ...(metadata && { metadata }),\n };\n }\n\n if (type === \"file\") {\n const data = getString(part, \"data\");\n if (data === undefined) return null;\n const declaredMimeType = getString(part, \"mimeType\") || fallbackMimeType;\n const filename = getString(part, \"filename\");\n const source = buildInputSource(\n data,\n declaredMimeType,\n getString(part, \"sourceType\"),\n );\n const metadata = buildInputMetadata(part, filename);\n switch (mediaTypeForMime(source.mimeType)) {\n case \"image\":\n return { type: \"image\", source, ...(metadata && { metadata }) };\n case \"audio\":\n return { type: \"audio\", source, ...(metadata && { metadata }) };\n case \"video\":\n return { type: \"video\", source, ...(metadata && { metadata }) };\n default:\n return { type: \"document\", source, ...(metadata && { metadata }) };\n }\n }\n\n if (type === \"audio\") {\n const audio = part.audio;\n if (!isObject(audio)) return null;\n const data = getString(audio, \"data\");\n const format = getString(audio, \"format\");\n if (data === undefined || format === undefined) return null;\n return {\n type: \"audio\",\n source: buildInputSource(\n parseDataUrl(data)?.data ?? data,\n `audio/${format}`,\n ),\n };\n }\n\n return null;\n}\n\ntype SnapshotAttachment = NonNullable<\n CoreThreadMessageLike[\"attachments\"]\n>[number];\n\nconst mediaInputTypes = new Set([\"image\", \"audio\", \"video\", \"document\"]);\n\n// Inverse of buildInputSource.\nfunction inputSourceToString(\n value: unknown,\n): { value: string; mimeType?: string; isUrl?: boolean } | null {\n if (!isObject(value)) return null;\n const sourceValue = getString(value, \"value\");\n if (sourceValue === undefined) return null;\n const mimeType = getString(value, \"mimeType\");\n const type = getString(value, \"type\");\n if (type === \"url\") {\n return {\n value: sourceValue,\n isUrl: true,\n ...(mimeType !== undefined && { mimeType }),\n };\n }\n if (type === \"data\") {\n const resolvedMimeType = mimeType ?? \"application/octet-stream\";\n return {\n value: `data:${resolvedMimeType};base64,${sourceValue}`,\n mimeType: resolvedMimeType,\n };\n }\n return null;\n}\n\n// Mirrors @ag-ui/client's BackwardCompatibility_0_0_47 middleware.\nfunction upgradeBinaryInputPart(\n part: Record<string, unknown>,\n): Record<string, unknown> | null {\n const mimeType = getString(part, \"mimeType\");\n if (mimeType === undefined) return null;\n const data = getString(part, \"data\");\n const url = getString(part, \"url\");\n const source = data\n ? { type: \"data\", value: data, mimeType }\n : url\n ? { type: \"url\", value: url, mimeType }\n : null;\n if (!source) return null;\n const filename = getString(part, \"filename\");\n return {\n type: mediaTypeForMime(mimeType),\n source,\n ...(filename && { metadata: { filename } }),\n };\n}\n\nfunction toSnapshotAttachments(content: unknown): SnapshotAttachment[] {\n if (!Array.isArray(content)) return [];\n\n const attachments: SnapshotAttachment[] = [];\n for (const rawPart of content) {\n if (!isObject(rawPart)) continue;\n const part =\n getString(rawPart, \"type\") === \"binary\"\n ? upgradeBinaryInputPart(rawPart)\n : rawPart;\n if (!part) continue;\n const type = getString(part, \"type\");\n if (type === undefined || !mediaInputTypes.has(type)) continue;\n const source = inputSourceToString(part.source);\n if (!source) continue;\n\n const { filename, providerMetadata } = readInputMetadata(part.metadata);\n const id = attachments.length.toString();\n\n if (type === \"image\") {\n attachments.push({\n id,\n type: \"image\",\n name: filename ?? \"image\",\n ...(source.mimeType !== undefined && { contentType: source.mimeType }),\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: source.value,\n ...(filename !== undefined && { filename }),\n ...(providerMetadata && { providerMetadata }),\n },\n ],\n });\n continue;\n }\n\n const mimeType = source.mimeType ?? \"application/octet-stream\";\n attachments.push({\n id,\n type: type === \"document\" ? \"document\" : \"file\",\n name: filename ?? \"file\",\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n data: source.value,\n mimeType,\n ...(source.isUrl && { sourceType: \"url\" as const }),\n ...(filename !== undefined && { filename }),\n ...(providerMetadata && { providerMetadata }),\n },\n ],\n });\n }\n return attachments;\n}\n\nfunction buildUserContent(message: ThreadMessageLike): string | InputContent[] {\n const contentParts = Array.isArray(message.content) ? message.content : [];\n\n const attachments = message.attachments ?? [];\n\n const converted: InputContent[] = [];\n\n // Promote string-form content to a leading text part so it survives when\n // non-text attachments are present (fromAgUiMessages emits string content).\n if (typeof message.content === \"string\" && message.content.length > 0) {\n converted.push({ type: \"text\", text: message.content });\n }\n\n for (const part of contentParts) {\n const input = toInputContent(part, undefined);\n if (input) converted.push(input);\n }\n for (const attachment of attachments) {\n if (!isObject(attachment)) continue;\n const attachmentContent = attachment.content;\n if (!Array.isArray(attachmentContent)) continue;\n const fallbackMime = getString(attachment, \"contentType\");\n for (const part of attachmentContent) {\n const input = toInputContent(part, fallbackMime);\n if (input) converted.push(input);\n }\n }\n\n const hasNonText = converted.some((part) => part.type !== \"text\");\n if (hasNonText) return converted;\n\n // All-text path: collapse to plain string. Join text parts collected from\n // both content and attachments so attachment-sourced text is not dropped.\n if (converted.length === 0) return extractText(message.content);\n return converted\n .filter(\n (part): part is { type: \"text\"; text: string } => part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\nfunction toToolCallPart(value: unknown): ToolCallPart | null {\n if (!isObject(value)) return null;\n const rawFunction = isObject(value.function) ? value.function : null;\n const toolCallId = getString(value, \"toolCallId\") ?? getString(value, \"id\");\n const toolName =\n getString(value, \"toolName\") ??\n getString(value, \"name\") ??\n (rawFunction ? getString(rawFunction, \"name\") : undefined) ??\n \"tool\";\n const argsText =\n getString(value, \"argsText\") ??\n getString(value, \"arguments\") ??\n (rawFunction ? getString(rawFunction, \"arguments\") : undefined);\n\n const parsedArgs =\n typeof argsText === \"string\" ? parseJSONText(argsText) : undefined;\n const args =\n isObject(parsedArgs) && !Array.isArray(parsedArgs)\n ? (parsedArgs as ReadonlyJSONObject)\n : isObject(value.args) && !Array.isArray(value.args)\n ? (value.args as ReadonlyJSONObject)\n : undefined;\n const part: ToolCallPart = {\n type: \"tool-call\",\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n toolName,\n argsText: argsText ?? JSON.stringify(args ?? {}),\n ...(args !== undefined ? { args } : {}),\n };\n\n if (value.type === \"tool-call\") {\n const result = value.result;\n const isError = value.isError;\n if (result !== undefined) part.result = result;\n if (typeof isError === \"boolean\") part.isError = isError;\n }\n\n return part;\n}\n\nfunction extractAssistantToolCalls(\n message: Record<string, unknown>,\n): ToolCallPart[] {\n const parts: ToolCallPart[] = [];\n const seenToolCallIds = new Set<string>();\n const pushPart = (part: ToolCallPart | null) => {\n if (!part) return;\n const id = part.toolCallId ?? generateId();\n if (seenToolCallIds.has(id)) return;\n seenToolCallIds.add(id);\n parts.push({\n ...part,\n toolCallId: id,\n });\n };\n\n const content = message.content;\n if (Array.isArray(content)) {\n for (const part of content) {\n if (isObject(part) && part.type === \"tool-call\") {\n pushPart(toToolCallPart(part));\n }\n }\n }\n\n const toolCalls = Array.isArray(message.toolCalls)\n ? message.toolCalls\n : Array.isArray(message.tool_calls)\n ? message.tool_calls\n : [];\n for (const call of toolCalls) {\n pushPart(toToolCallPart(call));\n }\n\n return parts;\n}\n\nfunction validateInterrupts(value: unknown): AgUiInterrupt[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const valid = value.filter(\n (entry): entry is AgUiInterrupt =>\n isObject(entry) &&\n typeof entry.id === \"string\" &&\n typeof entry.reason === \"string\",\n );\n return valid.length > 0 ? valid : undefined;\n}\n\nfunction readPersistedInterrupts(\n metadata: unknown,\n): AgUiInterrupt[] | undefined {\n if (!isObject(metadata)) return undefined;\n const custom = metadata.custom;\n if (!isObject(custom)) return undefined;\n const namespaced = custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return undefined;\n return validateInterrupts(namespaced.interrupts);\n}\n\nfunction readOpaqueReasoning(metadata: unknown): AgUiOpaqueReasoning[] {\n if (!isObject(metadata)) return [];\n const custom = metadata.custom;\n if (!isObject(custom)) return [];\n const namespaced = custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return [];\n const entries = namespaced.opaqueReasoning;\n if (!Array.isArray(entries)) return [];\n return entries.flatMap((entry) => {\n if (!isObject(entry)) return [];\n const id = getString(entry, \"id\");\n const encryptedValue = getString(entry, \"encryptedValue\");\n if (!id?.trim() || !encryptedValue?.trim()) return [];\n const metadata = toAgUiWireMetadata(entry.metadata);\n return [\n {\n id,\n encryptedValue,\n ...(metadata ? { metadata } : {}),\n ...(entry.after === true ? { after: true } : {}),\n },\n ];\n });\n}\n\nfunction withOpaqueReasoning(\n message: CoreThreadMessageLike,\n opaqueReasoning: AgUiOpaqueReasoning[],\n): CoreThreadMessageLike {\n const metadata = isObject(message.metadata) ? message.metadata : {};\n const custom = isObject(metadata.custom) ? metadata.custom : {};\n const namespaced = isObject(custom[AG_UI_METADATA_NAMESPACE])\n ? (custom[AG_UI_METADATA_NAMESPACE] as Record<string, unknown>)\n : {};\n return {\n ...message,\n metadata: {\n ...metadata,\n custom: {\n ...custom,\n [AG_UI_METADATA_NAMESPACE]: { ...namespaced, opaqueReasoning },\n },\n },\n } as CoreThreadMessageLike;\n}\n\nfunction toAssistantSnapshotMessage(\n rawMessage: Record<string, unknown>,\n): CoreThreadMessageLike {\n const text = extractText(rawMessage.content);\n const custom = toSnapshotCustom(rawMessage.metadata);\n const interrupts = readPersistedInterrupts({ custom });\n const restoredToolCalls = extractAssistantToolCalls(rawMessage);\n const approvals = projectAgUiToolApprovals(\n interrupts,\n new Set(\n restoredToolCalls\n .map((part) => part.toolCallId)\n .filter((id): id is string => !!id),\n ),\n );\n const toolCallParts = restoredToolCalls.map((part) => {\n const approval = part.toolCallId\n ? approvals.get(part.toolCallId)\n : undefined;\n return approval ? { ...part, approval } : part;\n });\n const assistantContent = [\n ...(text.length > 0 ? [{ type: \"text\" as const, text }] : []),\n ...toolCallParts,\n ];\n const messageName = getString(rawMessage, \"name\");\n const namespaced = isObject(custom[AG_UI_METADATA_NAMESPACE])\n ? { ...custom[AG_UI_METADATA_NAMESPACE] }\n : {};\n if (interrupts) namespaced.interrupts = interrupts;\n else delete namespaced.interrupts;\n const messageCustom = { ...custom };\n if (Object.keys(namespaced).length > 0) {\n messageCustom[AG_UI_METADATA_NAMESPACE] = namespaced;\n } else {\n delete messageCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: assistantContent.length > 0 ? assistantContent : \"\",\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(Object.keys(messageCustom).length > 0\n ? { metadata: { custom: messageCustom } }\n : {}),\n };\n}\n\nfunction toUserOrSystemSnapshotMessage(\n role: \"user\" | \"system\" | \"developer\",\n rawMessage: Record<string, unknown>,\n): CoreThreadMessageLike {\n const messageName = getString(rawMessage, \"name\");\n const custom = toSnapshotCustom(\n rawMessage.metadata,\n role === \"developer\" ? { role: \"developer\" } : {},\n );\n const attachments =\n role === \"user\" ? toSnapshotAttachments(rawMessage.content) : [];\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n // The internal message model has no developer role; it rides as a system\n // message with its wire role kept in metadata so the export restores it.\n role: role === \"developer\" ? \"system\" : role,\n content: extractText(rawMessage.content),\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(attachments.length > 0 ? { attachments } : {}),\n ...(Object.keys(custom).length > 0 ? { metadata: { custom } } : {}),\n };\n}\n\nfunction attachA2uiSurfaces(\n message: CoreThreadMessageLike,\n state: A2uiState,\n): CoreThreadMessageLike {\n const a2uiParts: ToolCallPart[] = [];\n for (const [surfaceId, surface] of state) {\n const { toolCall } = surfaceToPresentToolCall(surfaceId, surface);\n if (!toolCall) continue;\n a2uiParts.push({\n type: \"tool-call\",\n ...toolCall,\n });\n }\n\n const content = Array.isArray(message.content) ? message.content : [];\n const preserved = content.filter(\n (part) =>\n !(\n isObject(part) &&\n part.type === \"tool-call\" &&\n typeof part.toolCallId === \"string\" &&\n part.toolCallId.startsWith(\"a2ui:\")\n ),\n );\n return { ...message, content: [...preserved, ...a2uiParts] };\n}\n\n// A tool call that arrives without a `parentMessageId` has no record to join, so\n// the client opens one keyed by the call id. An assistant record whose own id is\n// a call it carries is that container: an id the client invented for the call\n// rather than a boundary an agent drew. The prose of the turn lands in records\n// of its own on either side of it, and nothing on the wire binds them to the\n// run that produced them.\nfunction isSyntheticToolCallContainer(message: CoreThreadMessageLike): boolean {\n if (message.role !== \"assistant\" || !Array.isArray(message.content))\n return false;\n let carriesOwnId = false;\n for (const part of message.content) {\n if (!isObject(part)) continue;\n // The container is opened empty, so text on the record means an agent\n // addressed it and the id is one it chose.\n if (part.type === \"text\") return false;\n if (\n part.type === \"tool-call\" &&\n getString(part, \"toolCallId\") === message.id\n ) {\n carriesOwnId = true;\n }\n }\n return carriesOwnId;\n}\n\nfunction carriesPart(message: CoreThreadMessageLike, type: string): boolean {\n return (\n Array.isArray(message.content) &&\n message.content.some((part) => isObject(part) && part.type === type)\n );\n}\n\nfunction carriesText(message: CoreThreadMessageLike): boolean {\n return carriesPart(message, \"text\");\n}\n\n// A container joins the assistant record ahead of it when that record holds\n// prose or calls of the turn. A released reasoning record holds neither: its\n// part leaves the export under the record's own id, so a message merged under\n// that id would put two records with one id on the wire.\nfunction opensTurn(message: CoreThreadMessageLike): boolean {\n return (\n message.role === \"assistant\" &&\n (carriesText(message) || carriesPart(message, \"tool-call\"))\n );\n}\n\n// The parts of the answer fold onto the container ahead of them. A record\n// carrying a tool call an agent addressed is a boundary of its own and keeps\n// its message.\nfunction answersToolCallContainer(message: CoreThreadMessageLike): boolean {\n if (message.role !== \"assistant\" || !Array.isArray(message.content))\n return false;\n if (message.content.length === 0) return false;\n return !message.content.some(\n (part) => isObject(part) && part.type === \"tool-call\",\n );\n}\n\nfunction readCustomMetadata(metadata: unknown): Record<string, unknown> {\n if (!isObject(metadata) || !isObject(metadata.custom)) return {};\n return metadata.custom;\n}\n\nfunction readNamespacedMetadata(metadata: unknown): Record<string, unknown> {\n const namespaced = readCustomMetadata(metadata)[AG_UI_METADATA_NAMESPACE];\n return isObject(namespaced) ? namespaced : {};\n}\n\nfunction foldTurnRecords(\n previous: CoreThreadMessageLike,\n message: CoreThreadMessageLike,\n): CoreThreadMessageLike {\n const interrupts = [\n ...(readPersistedInterrupts(previous.metadata) ?? []),\n ...(readPersistedInterrupts(message.metadata) ?? []),\n ];\n // An entry that rode a record behind the turn's calls sat ahead of content\n // that now follows them, so it is replayed after the merged record and its\n // tool results rather than ahead of a message that no longer starts there.\n // One that rode the container opening the turn sat ahead of every call and\n // stays ahead of the record.\n const trailsCalls = carriesPart(previous, \"tool-call\");\n const opaqueReasoning = [\n ...readOpaqueReasoning(previous.metadata),\n ...readOpaqueReasoning(message.metadata).map((entry) =>\n trailsCalls ? { ...entry, after: true } : entry,\n ),\n ];\n const namespaced = {\n ...readNamespacedMetadata(previous.metadata),\n ...readNamespacedMetadata(message.metadata),\n ...(interrupts.length > 0 ? { interrupts } : {}),\n ...(opaqueReasoning.length > 0 ? { opaqueReasoning } : {}),\n } satisfies AgUiCustomMetadata & Record<string, unknown>;\n const custom = {\n ...readCustomMetadata(previous.metadata),\n ...readCustomMetadata(message.metadata),\n ...(Object.keys(namespaced).length > 0\n ? { [AG_UI_METADATA_NAMESPACE]: namespaced }\n : {}),\n };\n const metadata = {\n ...(isObject(previous.metadata) ? previous.metadata : {}),\n ...(isObject(message.metadata) ? message.metadata : {}),\n ...(Object.keys(custom).length > 0 ? { custom } : {}),\n };\n return {\n ...previous,\n ...message,\n // A container's id names a call rather than the turn, so the record the\n // agent addressed its prose to wins: that is the id the next run has to\n // carry for the agent to recognize the message it wrote.\n id: carriesText(message) ? message.id : previous.id,\n content: [\n ...(Array.isArray(previous.content) ? previous.content : []),\n ...(Array.isArray(message.content) ? message.content : []),\n ],\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n } as CoreThreadMessageLike;\n}\n\nexport type FromAgUiMessagesOptions = {\n /**\n * Whether to convert `reasoning` messages into visible reasoning parts.\n * Matches the `showThinking` option of `useAgUiRuntime`. Defaults to `true`.\n */\n showThinking?: boolean;\n};\n\nexport function fromAgUiMessages(\n messages: readonly unknown[],\n options?: FromAgUiMessagesOptions,\n): CoreThreadMessageLike[] {\n const showThinking = options?.showThinking ?? true;\n const converted: CoreThreadMessageLike[] = [];\n const a2uiBuckets = new Map<string, A2uiState>();\n const a2uiBucketOwnerIndices = new Map<string, number>();\n const activityParts = new Map<\n string,\n { ownerIndex: number; part: { type: \"data\"; name: string; data: unknown } }\n >();\n // A zero-data-retention run carries its payload in encryptedValue with no\n // readable content, so the record has no part to become and rides on the\n // neighbouring message instead of being dropped. The anchor is the index the\n // next pushed message will occupy, which is where it sat on the wire.\n const opaqueReasoning: (AgUiOpaqueReasoning & { anchor: number })[] = [];\n // A reasoning record belongs to the assistant record that follows it, which is\n // the binding the export writes and the one the reference integrations read\n // back. Holding it until that assistant arrives rebuilds the pair as the\n // single message the live run produced.\n const pendingReasoning: {\n id: string | undefined;\n part: ReasoningMessagePart;\n }[] = [];\n\n const flushPendingReasoning = () => {\n for (const { id, part } of pendingReasoning) {\n converted.push({\n id: id ?? generateId(),\n role: \"assistant\",\n content: [part],\n });\n }\n pendingReasoning.length = 0;\n };\n\n const withPendingReasoning = (\n message: CoreThreadMessageLike,\n ): CoreThreadMessageLike => {\n if (pendingReasoning.length === 0) return message;\n const parts = pendingReasoning.map(({ part }) => part);\n pendingReasoning.length = 0;\n return {\n ...message,\n content: [\n ...parts,\n ...(Array.isArray(message.content) ? message.content : []),\n ],\n };\n };\n\n for (const rawMessage of messages) {\n if (!isObject(rawMessage)) continue;\n const role = getString(rawMessage, \"role\");\n if (!role) continue;\n\n if (role === \"tool\") {\n flushPendingReasoning();\n const toolCallId = getToolCallId(rawMessage) ?? `tool-${generateId()}`;\n const toolMessageId = getString(rawMessage, \"id\");\n const modelContent = extractText(rawMessage.content);\n const mcpResult = parseMcpToolCallResult(rawMessage, modelContent);\n const mcpModelContent = mcpResult\n ? [{ type: \"text\" as const, text: modelContent }]\n : undefined;\n const result =\n mcpResult ??\n (rawMessage.result !== undefined\n ? rawMessage.result\n : typeof rawMessage.content === \"string\"\n ? parseJSONText(rawMessage.content)\n : rawMessage.content);\n const isError =\n typeof rawMessage.error === \"string\" ||\n rawMessage.isError === true ||\n rawMessage.status === \"error\"\n ? true\n : rawMessage.isError === false\n ? false\n : undefined;\n const mcpAppUri = readMcpAppResourceUri(mcpResult?._meta);\n const mcpApp =\n mcpAppUri !== undefined ? { resourceUri: mcpAppUri } : undefined;\n const messageMetadata = toAgUiWireMetadata(rawMessage.metadata);\n\n let updated = false;\n for (\n let messageIndex = converted.length - 1;\n messageIndex >= 0 && !updated;\n messageIndex--\n ) {\n const message = converted[messageIndex];\n if (\n !message ||\n message.role !== \"assistant\" ||\n !Array.isArray(message.content)\n )\n continue;\n\n for (\n let partIndex = message.content.length - 1;\n partIndex >= 0;\n partIndex--\n ) {\n const part = message.content[partIndex];\n if (!isObject(part) || part.type !== \"tool-call\") continue;\n if (getString(part, \"toolCallId\") !== toolCallId) continue;\n\n const updatedPart: ToolCallPart = {\n ...(part as ToolCallPart),\n result,\n ...(mcpModelContent ? { modelContent: mcpModelContent } : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(toolMessageId !== undefined\n ? { unstable_toolMessageId: toolMessageId }\n : {}),\n ...(mcpApp ? { mcp: { app: mcpApp } } : {}),\n ...(messageMetadata\n ? {\n providerMetadata: withAgUiPartMessageMetadata(\n (part as ToolCallPart).providerMetadata,\n messageMetadata,\n ),\n }\n : {}),\n };\n const updatedContent = message.content.map((contentPart, index) =>\n index === partIndex ? updatedPart : contentPart,\n );\n converted[messageIndex] = { ...message, content: updatedContent };\n updated = true;\n break;\n }\n }\n\n if (updated) {\n continue;\n }\n\n const id = toolMessageId ?? toolCallId;\n const toolName =\n getString(rawMessage, \"name\") ??\n getString(rawMessage, \"toolName\") ??\n \"tool\";\n converted.push({\n id: `${id}:assistant`,\n role: \"assistant\",\n content: [\n {\n type: \"tool-call\",\n toolCallId,\n toolName,\n args: {},\n argsText: \"{}\",\n result,\n ...(mcpModelContent ? { modelContent: mcpModelContent } : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(toolMessageId !== undefined\n ? { unstable_toolMessageId: toolMessageId }\n : {}),\n ...(mcpApp ? { mcp: { app: mcpApp } } : {}),\n ...(messageMetadata\n ? {\n providerMetadata: withAgUiPartMessageMetadata(\n undefined,\n messageMetadata,\n ),\n }\n : {}),\n },\n ],\n });\n continue;\n }\n\n if (role === \"activity\") {\n const activityType = getString(rawMessage, \"activityType\");\n if (activityType === undefined || activityType === MCP_APPS_ACTIVITY_TYPE)\n continue;\n\n // A surface belongs to the turn that painted it, and held reasoning is a\n // nearer antecedent than the previous turn's assistant record, so it is\n // released here rather than folded past this record.\n flushPendingReasoning();\n\n let ownerIndex = -1;\n for (let i = converted.length - 1; i >= 0; i--) {\n const candidate = converted[i];\n if (candidate && candidate.role === \"assistant\") {\n ownerIndex = i;\n break;\n }\n }\n if (ownerIndex === -1) continue;\n\n const owner = converted[ownerIndex]!;\n if (activityType !== A2UI_SURFACE_ACTIVITY_TYPE) {\n const bucketKey =\n getString(rawMessage, \"id\") ?? `agui-activity:${activityType}`;\n const part = {\n type: \"data\" as const,\n name: `agui-activity/${activityType}`,\n data: rawMessage.content,\n };\n const existing = activityParts.get(bucketKey);\n const existingOwner = existing && converted[existing.ownerIndex];\n const existingIndex =\n existingOwner && Array.isArray(existingOwner.content)\n ? existingOwner.content.indexOf(existing.part)\n : -1;\n if (existing && existingOwner && existingIndex !== -1) {\n const content = [...(existingOwner.content as unknown[])];\n content[existingIndex] = part;\n converted[existing.ownerIndex] = {\n ...existingOwner,\n content: content as typeof existingOwner.content,\n };\n activityParts.set(bucketKey, {\n ownerIndex: existing.ownerIndex,\n part,\n });\n continue;\n }\n\n const content = Array.isArray(owner.content) ? owner.content : [];\n activityParts.set(bucketKey, { ownerIndex, part });\n converted[ownerIndex] = {\n ...owner,\n content: [...content, part],\n };\n continue;\n }\n\n const activityContent = isObject(rawMessage.content)\n ? (rawMessage.content as Record<string, unknown>)\n : null;\n const operations = activityContent?.[\"a2ui_operations\"];\n if (!Array.isArray(operations)) continue;\n const bucketKey = getString(rawMessage, \"id\") ?? \"a2ui:anonymous\";\n const { state } = applyA2uiOperations(new Map(), operations);\n a2uiBuckets.delete(bucketKey);\n a2uiBucketOwnerIndices.delete(bucketKey);\n a2uiBuckets.set(bucketKey, state);\n a2uiBucketOwnerIndices.set(bucketKey, ownerIndex);\n\n const ownerState = new Map<string, A2uiSurfaceState>();\n for (const [candidateBucketKey, candidateState] of a2uiBuckets) {\n if (a2uiBucketOwnerIndices.get(candidateBucketKey) !== ownerIndex)\n continue;\n for (const [surfaceId, surface] of candidateState) {\n ownerState.set(surfaceId, surface);\n }\n }\n converted[ownerIndex] = attachA2uiSurfaces(owner, ownerState);\n continue;\n }\n\n if (role === \"assistant\") {\n converted.push(\n withPendingReasoning(toAssistantSnapshotMessage(rawMessage)),\n );\n continue;\n }\n\n if (role === \"reasoning\") {\n const text = extractText(rawMessage.content);\n const encryptedValue = getString(rawMessage, \"encryptedValue\");\n const messageMetadata = toAgUiWireMetadata(rawMessage.metadata);\n if (text.trim().length === 0) {\n // showThinking hides reasoning; this record is never rendered anyway,\n // and dropping it would deny the provider the payload it needs to\n // accept the next run.\n const opaqueId = getString(rawMessage, \"id\");\n if (opaqueId?.trim() && encryptedValue?.trim()) {\n // The anchor counts materialized messages, so anything still held\n // takes its own slot rather than folding past this record.\n flushPendingReasoning();\n opaqueReasoning.push({\n id: opaqueId,\n encryptedValue,\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n anchor: converted.length,\n });\n }\n continue;\n }\n // Gate visible reasoning on showThinking so a cold reload matches the\n // live run: the aggregator never stores reasoning parts when it is off.\n // A signature on a hidden record is still transport state, so it is kept\n // opaque rather than discarded with the text.\n if (!showThinking) {\n const hiddenId = getString(rawMessage, \"id\");\n if (hiddenId?.trim() && encryptedValue?.trim()) {\n opaqueReasoning.push({\n id: hiddenId,\n encryptedValue,\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n anchor: converted.length,\n });\n }\n continue;\n }\n const rawReasoningId = getString(rawMessage, \"id\");\n // A blank id still wins over a synthesized one on export, which would put\n // an unaddressable record on the wire.\n const reasoningId = rawReasoningId?.trim() ? rawReasoningId : undefined;\n // The fold costs the record its own message id, so it rides the part\n // instead: the export re-emits each block under the id it arrived with.\n const meta = {\n ...(reasoningId !== undefined ? { reasoningId } : {}),\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n ...(messageMetadata\n ? { messageMetadata: messageMetadata as ReadonlyJSONObject }\n : {}),\n };\n pendingReasoning.push({\n id: reasoningId,\n part: {\n type: \"reasoning\",\n text,\n ...(Object.keys(meta).length > 0\n ? { providerMetadata: { [AG_UI_METADATA_NAMESPACE]: meta } }\n : {}),\n },\n });\n continue;\n }\n\n if (role === \"user\" || role === \"system\" || role === \"developer\") {\n flushPendingReasoning();\n converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));\n }\n }\n\n flushPendingReasoning();\n\n for (const { anchor, ...entry } of opaqueReasoning) {\n // Nothing followed it on the wire, so it trails the last message instead.\n const trailing = anchor >= converted.length;\n const index = trailing ? converted.length - 1 : anchor;\n const target = converted[index];\n if (!target) continue;\n converted[index] = withOpaqueReasoning(target, [\n ...readOpaqueReasoning(target.metadata),\n ...(trailing ? [{ ...entry, after: true }] : [entry]),\n ]);\n }\n\n // A turn that called a tool without addressing a record sits on the wire as\n // a container beside the records around it, which the live run renders as\n // one message: the container joins the assistant record ahead of it, and\n // what follows a container joins it until the turn carries text, where a\n // further text record opens a message of its own as it does live.\n const folded: CoreThreadMessageLike[] = [];\n for (const message of converted) {\n const previous = folded[folded.length - 1];\n if (\n previous !== undefined &&\n (isSyntheticToolCallContainer(message)\n ? opensTurn(previous)\n : isSyntheticToolCallContainer(previous) &&\n answersToolCallContainer(message))\n ) {\n folded[folded.length - 1] = foldTurnRecords(previous, message);\n continue;\n }\n folded.push(message);\n }\n\n for (let i = 0; i < folded.length; i++) {\n const message = folded[i]!;\n if (message.role !== \"assistant\") continue;\n\n const hasInterrupt =\n readPersistedInterrupts(message.metadata) !== undefined;\n const hasPendingToolCall =\n Array.isArray(message.content) &&\n message.content.some(\n (part) =>\n isObject(part) &&\n part.type === \"tool-call\" &&\n part.result === undefined,\n );\n\n if (hasInterrupt || hasPendingToolCall) {\n folded[i] = {\n ...message,\n status: getAutoStatus(\n false,\n false,\n hasInterrupt,\n hasPendingToolCall,\n undefined,\n ),\n };\n }\n }\n\n return folded;\n}\n\nfunction convertAssistantMessage(\n message: NormalizedThreadMessageLike,\n converted: AgUiMessage[],\n): void {\n const content = extractText(message.content);\n const contentArray = Array.isArray(message.content) ? message.content : [];\n\n const toolCallParts = contentArray.filter(\n (part): part is ToolCallPart =>\n part?.type === \"tool-call\" &&\n !(\n typeof part.toolCallId === \"string\" &&\n part.toolCallId.startsWith(\"a2ui:\")\n ),\n );\n\n const toolCalls = toolCallParts.map((part) => ({\n ...normalizeToolCall(part),\n part,\n }));\n\n // An AG-UI assistant record has no reasoning field, so reasoning leaves as\n // the standalone record it arrived as, ahead of the assistant it belongs to.\n const shellIsDropped = content.length === 0 && toolCalls.length === 0;\n let reasoningIndex = 0;\n for (const part of contentArray) {\n if (!isObject(part) || part.type !== \"reasoning\") continue;\n const text = getString(part, \"text\") ?? \"\";\n if (text.trim().length === 0) continue;\n const { encryptedValue, reasoningId, messageMetadata } =\n readAgUiReasoningMeta(part.providerMetadata);\n converted.push({\n // The wire id is what a signature was issued against, so it wins over a\n // synthesized one whenever the run carried it.\n id: reasoningId?.trim()\n ? reasoningId\n : shellIsDropped && reasoningIndex === 0\n ? message.id\n : `${message.id}:reasoning-${reasoningIndex}`,\n role: \"reasoning\",\n content: text,\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n });\n reasoningIndex++;\n }\n\n // Some providers reject a replayed blank assistant turn, even when it carries metadata.\n if (shellIsDropped) {\n return;\n }\n\n // A subagent's tool calls live on nested assistant messages. Before\n // subagent attribution they flattened to root and went out with this\n // assistant record as their antecedent, so the resume payload restores\n // exactly that shape: the calls join this record's toolCalls and their\n // results follow as tool records — never a tool record without its call.\n // The nested assistant content itself is backend-owned state and is not\n // re-sent.\n const nestedToolCalls: {\n id: string;\n call: AgUiToolCall;\n part: ToolCallPart;\n }[] = [];\n for (const { part } of toolCalls) {\n for (const { part: nestedToolCall } of walkToolCallTree(\n part.messages ?? [],\n { shouldDescend: isExportableNestedToolCall },\n )) {\n if (!isExportableNestedToolCall(nestedToolCall)) continue;\n nestedToolCalls.push({\n ...normalizeToolCall(nestedToolCall),\n part: nestedToolCall,\n });\n }\n }\n\n converted.push({\n id: message.id,\n role: \"assistant\",\n content,\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n ...(toolCalls.length + nestedToolCalls.length > 0\n ? {\n toolCalls: [...toolCalls, ...nestedToolCalls].map(\n (entry) => entry.call,\n ),\n }\n : {}),\n });\n\n for (const { id: toolCallId, part } of toolCalls) {\n emitToolResult(toolCallId, part, converted);\n }\n for (const { id: toolCallId, part } of nestedToolCalls) {\n // A result recorded while the call's approval gate is still open must not\n // reach the backend as if the gate had been decided.\n const gateOpen =\n part.approval != null &&\n part.approval.approved === undefined &&\n part.approval.resolution === undefined;\n if (gateOpen) continue;\n emitToolResult(toolCallId, part, converted);\n }\n}\n\nfunction emitToolResult(\n toolCallId: string,\n part: ToolCallPart,\n converted: AgUiMessage[],\n): void {\n if (part.result === undefined) return;\n\n const resultContent =\n part.modelContent !== undefined\n ? extractText(part.modelContent)\n : typeof part.result === \"string\"\n ? part.result\n : JSON.stringify(part.result);\n const messageMetadata = readAgUiPartMessageMetadata(part.providerMetadata);\n\n converted.push({\n id: part.unstable_toolMessageId ?? `${toolCallId}:tool`,\n role: \"tool\",\n content: resultContent,\n toolCallId,\n ...(part.isError ? { error: resultContent } : {}),\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n });\n}\n\nfunction convertToolMessage(\n message: NormalizedThreadMessageLike,\n converted: AgUiMessage[],\n): void {\n const content = extractText(message.content);\n const toolCallId = message.toolCallId ?? generateId();\n\n converted.push({\n id: message.id,\n role: \"tool\",\n content,\n toolCallId,\n ...(typeof message.error === \"string\" ? { error: message.error } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n}\n\nexport function toAgUiMessages(\n messages: readonly ThreadMessageLike[],\n): AgUiMessage[] {\n const converted: AgUiMessage[] = [];\n\n for (const rawMessage of messages) {\n const message: NormalizedThreadMessageLike = {\n ...rawMessage,\n id: rawMessage.id ?? generateId(),\n };\n const opaqueReasoning = readOpaqueReasoning(message.metadata);\n const toOpaqueRecord = (entry: AgUiOpaqueReasoning): AgUiMessage => ({\n id: entry.id,\n role: \"reasoning\",\n content: \"\",\n encryptedValue: entry.encryptedValue,\n ...(entry.metadata ? { metadata: entry.metadata } : {}),\n });\n for (const entry of opaqueReasoning) {\n if (entry.after !== true) converted.push(toOpaqueRecord(entry));\n }\n const flushTrailingOpaqueReasoning = () => {\n for (const entry of opaqueReasoning) {\n if (entry.after === true) converted.push(toOpaqueRecord(entry));\n }\n };\n\n if (message.role === \"assistant\") {\n convertAssistantMessage(message, converted);\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"tool\") {\n convertToolMessage(message, converted);\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"user\") {\n converted.push({\n id: message.id,\n role: \"user\",\n content: buildUserContent(message),\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"system\" || message.role === \"developer\") {\n const custom = isObject(message.metadata)\n ? message.metadata.custom\n : undefined;\n const namespaced = isObject(custom)\n ? custom[AG_UI_METADATA_NAMESPACE]\n : undefined;\n const wireRole =\n message.role === \"system\" &&\n isObject(namespaced) &&\n namespaced.role === \"developer\"\n ? (\"developer\" as const)\n : message.role;\n converted.push({\n id: message.id,\n role: wireRole,\n content: extractText(message.content),\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"reasoning\") {\n converted.push({\n id: message.id,\n role: \"reasoning\",\n content: extractText(message.content),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n flushTrailingOpaqueReasoning();\n }\n\n return converted;\n}\n\ntype AgUiTool = NonNullable<RunAgentParameters[\"tools\"]>[number];\n\nexport function toAgUiTools(\n tools: Record<string, Tool> | undefined,\n): AgUiTool[] {\n if (!tools) return [];\n\n const toolsSchema = toToolsJSONSchema(tools);\n return Object.entries(toolsSchema).map(([name, tool]) => ({\n name,\n description: tool.description ?? \"\",\n parameters: tool.parameters,\n }));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversions.js","names":[],"sources":["../../../src/runtime/adapter/conversions.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n ContentPart,\n PartSource,\n RunAgentParameters,\n} from \"@ag-ui/client\";\nimport { generateId } from \"@assistant-ui/core\";\nimport type {\n ThreadMessageLike as CoreThreadMessageLike,\n PartProviderMetadata,\n ReasoningMessagePart,\n} from \"@assistant-ui/core\";\nimport {\n getAutoStatus,\n parseDataUrl,\n resolveFilePartSource,\n resolveImageMediaType,\n walkToolCallTree,\n} from \"@assistant-ui/core/internal\";\nimport { type Tool, toToolsJSONSchema } from \"assistant-stream\";\nimport type { ReadonlyJSONObject } from \"assistant-stream/utils\";\nimport {\n AG_UI_METADATA_NAMESPACE,\n A2UI_SURFACE_ACTIVITY_TYPE,\n MCP_APPS_ACTIVITY_TYPE,\n type AgUiCustomMetadata,\n type AgUiOpaqueReasoning,\n} from \"../types\";\nimport {\n applyA2uiOperations,\n surfaceToPresentToolCall,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/generative-ui/a2ui\";\nimport type { AgUiInterrupt } from \"../types\";\nimport { projectAgUiToolApprovals } from \"./tool-approval\";\nimport {\n parseMcpToolCallResult,\n readMcpAppResourceUri,\n toolContentText,\n} from \"../mcp-tool-result\";\n\ntype AttachmentLike = {\n name?: string | undefined;\n contentType?: string | undefined;\n content?: readonly unknown[] | undefined;\n};\n\ntype ThreadMessageLike = {\n id?: string | undefined;\n role: string;\n content: unknown;\n metadata?: unknown;\n name?: string | undefined;\n toolCallId?: string | undefined;\n error?: string | undefined;\n attachments?: readonly AttachmentLike[] | undefined;\n};\n\ntype NormalizedThreadMessageLike = ThreadMessageLike & { id: string };\n\ntype AgUiToolCall = {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n};\n\nexport type AgUiMessage =\n | {\n id: string;\n role: \"user\";\n content: string | ContentPart[];\n name?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"assistant\";\n content: string;\n name?: string;\n toolCalls?: AgUiToolCall[];\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"system\" | \"developer\";\n content: string;\n name?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"reasoning\";\n content: string;\n encryptedValue?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n id: string;\n role: \"tool\";\n content: string | ContentPart[];\n toolCallId: string;\n error?: string;\n metadata?: Record<string, unknown>;\n };\n\ntype CoreToolCallPart = Extract<\n Exclude<CoreThreadMessageLike[\"content\"], string>[number],\n { type: \"tool-call\" }\n>;\n\ntype ToolCallPart = Omit<CoreToolCallPart, \"result\" | \"isError\"> & {\n result?: unknown;\n isError?: boolean | undefined;\n /** @deprecated Experimental since 2026-03-08. Not scheduled for removal; the API may change in any release. */\n unstable_toolMessageId?: string;\n};\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst getString = (record: Record<string, unknown>, key: string) => {\n const value = record[key];\n return typeof value === \"string\" ? value : undefined;\n};\n\nfunction toAgUiWireMetadata(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n return isObject(metadata) ? { ...metadata } : undefined;\n}\n\nfunction readLegacyAgUiNamespace(metadata: unknown): Record<string, unknown> {\n if (!isObject(metadata) || !isObject(metadata.custom)) return {};\n const namespaced = metadata.custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return {};\n return \"interrupts\" in namespaced\n ? { interrupts: namespaced.interrupts }\n : {};\n}\n\nfunction withoutPersistedStatusMetadata(\n wire: Record<string, unknown>,\n): Record<string, unknown> {\n if (!isObject(wire.custom)) return wire;\n const namespaced = wire.custom[AG_UI_METADATA_NAMESPACE];\n if (\n !isObject(namespaced) ||\n (!(\"interrupts\" in namespaced) && !(\"pendingToolCallIds\" in namespaced))\n )\n return wire;\n\n const {\n interrupts: _interrupts,\n pendingToolCallIds: _pendingToolCallIds,\n ...remainingNamespace\n } = namespaced;\n const { [AG_UI_METADATA_NAMESPACE]: _namespace, ...remainingCustom } =\n wire.custom;\n if (Object.keys(remainingNamespace).length > 0) {\n remainingCustom[AG_UI_METADATA_NAMESPACE] = remainingNamespace;\n }\n const { custom: _custom, ...remainingWire } = wire;\n return Object.keys(remainingCustom).length > 0\n ? { ...remainingWire, custom: remainingCustom }\n : remainingWire;\n}\n\nfunction toSnapshotCustom(\n metadata: unknown,\n state: Record<string, unknown> = {},\n): Record<string, unknown> {\n const wire = withoutPersistedStatusMetadata(\n toAgUiWireMetadata(metadata) ?? {},\n );\n const needsWireSlot =\n isObject(metadata) &&\n (Object.keys(metadata).length === 0 || AG_UI_METADATA_NAMESPACE in wire);\n const namespaced = {\n ...readLegacyAgUiNamespace(metadata),\n ...(readPersistedPendingToolCallIds(metadata) !== undefined\n ? { pendingToolCallIds: readPersistedPendingToolCallIds(metadata) }\n : {}),\n ...state,\n ...(needsWireSlot ? { messageMetadata: wire } : {}),\n };\n return {\n ...wire,\n ...(Object.keys(namespaced).length > 0\n ? { [AG_UI_METADATA_NAMESPACE]: namespaced }\n : {}),\n };\n}\n\nfunction toAgUiMessageMetadata(\n metadata: unknown,\n): Record<string, unknown> | undefined {\n const custom = readCustomMetadata(metadata);\n const namespaced = readNamespacedMetadata(metadata);\n if (isObject(namespaced.messageMetadata)) {\n return { ...namespaced.messageMetadata };\n }\n const { [AG_UI_METADATA_NAMESPACE]: _state, ...wire } = custom;\n return Object.keys(wire).length > 0 ? wire : undefined;\n}\n\nfunction withAgUiMessageMetadata(metadata: unknown): {\n metadata?: Record<string, unknown>;\n} {\n const messageMetadata = toAgUiMessageMetadata(metadata);\n return messageMetadata !== undefined ? { metadata: messageMetadata } : {};\n}\n\nfunction withAgUiPartMessageMetadata(\n providerMetadata: PartProviderMetadata | undefined,\n messageMetadata: Record<string, unknown> | undefined,\n): PartProviderMetadata {\n if (!messageMetadata) return providerMetadata ?? {};\n\n const existing = providerMetadata ?? {};\n const namespaced = isObject(existing[AG_UI_METADATA_NAMESPACE])\n ? existing[AG_UI_METADATA_NAMESPACE]\n : {};\n return {\n ...existing,\n [AG_UI_METADATA_NAMESPACE]: {\n ...namespaced,\n messageMetadata: messageMetadata as ReadonlyJSONObject,\n },\n };\n}\n\nfunction readAgUiPartMessageMetadata(\n providerMetadata: unknown,\n): Record<string, unknown> | undefined {\n const namespaced = readAgUiNamespace(providerMetadata);\n return namespaced && isObject(namespaced.messageMetadata)\n ? toAgUiWireMetadata(namespaced.messageMetadata)\n : undefined;\n}\n\nconst getToolCallId = (record: Record<string, unknown>) =>\n getString(record, \"toolCallId\") ?? getString(record, \"tool_call_id\");\n\nconst readAgUiNamespace = (providerMetadata: unknown) => {\n if (!isObject(providerMetadata)) return undefined;\n const namespaced = providerMetadata[AG_UI_METADATA_NAMESPACE];\n return isObject(namespaced) ? namespaced : undefined;\n};\n\nconst readAgUiReasoningMeta = (providerMetadata: unknown) => {\n const namespaced = readAgUiNamespace(providerMetadata);\n if (!namespaced) return {};\n return {\n encryptedValue: getString(namespaced, \"encryptedValue\"),\n reasoningId: getString(namespaced, \"reasoningId\"),\n messageMetadata: toAgUiWireMetadata(namespaced.messageMetadata),\n };\n};\n\n// AG-UI carries per-item extras in `metadata`; anything else on the item is\n// stripped by its schema. The part's own `filename` wins over a key of the\n// same name in the bag.\nconst buildPartMetadata = (\n part: Record<string, unknown>,\n filename?: string | undefined,\n) => {\n const metadata = {\n ...readAgUiNamespace(part.providerMetadata),\n ...(filename !== undefined && { filename }),\n };\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n};\n\n// The inverse: `filename` lands on the part's own field, everything else the\n// item carried goes back into the namespace it came from, so a snapshot echo\n// resends what the host attached.\nconst readPartMetadata = (\n metadata: unknown,\n): {\n filename?: string | undefined;\n providerMetadata?: PartProviderMetadata | undefined;\n} => {\n if (!isObject(metadata)) return {};\n const { filename: _filename, ...rest } = metadata;\n return {\n filename: getString(metadata, \"filename\"),\n ...(Object.keys(rest).length > 0 && {\n providerMetadata: {\n [AG_UI_METADATA_NAMESPACE]: rest as PartProviderMetadata[string],\n },\n }),\n };\n};\n\nfunction parseJSONText(value: string): unknown {\n if (!value) return value;\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction normalizeToolCall(part: ToolCallPart): {\n id: string;\n call: AgUiToolCall;\n} {\n const id = part.toolCallId ?? generateId();\n const argsText =\n typeof part.argsText === \"string\"\n ? part.argsText\n : JSON.stringify(part.args ?? {});\n\n return {\n id,\n call: {\n id,\n type: \"function\",\n function: {\n name: part.toolName ?? \"tool\",\n arguments: argsText,\n },\n },\n };\n}\n\nconst isExportableNestedToolCall = (part: { readonly toolCallId?: unknown }) =>\n typeof part.toolCallId === \"string\" && !part.toolCallId.startsWith(\"a2ui:\");\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n\n return content\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n part?.type === \"text\" && typeof part?.text === \"string\",\n )\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\ntype EncodedPartSource = Extract<PartSource, { type: \"data\" | \"url\" }>;\n\ntype MediaInputType = \"image\" | \"audio\" | \"video\" | \"document\";\n\nfunction mediaTypeForMime(mimeType: string | undefined): MediaInputType {\n if (mimeType?.startsWith(\"image/\")) return \"image\";\n if (mimeType?.startsWith(\"audio/\")) return \"audio\";\n if (mimeType?.startsWith(\"video/\")) return \"video\";\n return \"document\";\n}\n\n// Build an AG-UI multimodal source from a data URL, raw base64 payload, or an\n// http(s) URL. A `url` source may omit the mime type; a `data` source always\n// resolves one (falling back to application/octet-stream). An explicit\n// `sourceType: \"url\"` on the part forces the url leg for non-http references,\n// and a data URL that is not base64 takes it too, since a `data` source\n// carries base64 bytes.\nfunction buildPartSource(\n value: string,\n declaredMimeType: string | undefined,\n sourceType?: string,\n): EncodedPartSource {\n const source = resolveFilePartSource({\n data: value,\n mimeType: declaredMimeType ?? \"application/octet-stream\",\n sourceType:\n /^data:/i.test(value) && !parseDataUrl(value) ? \"url\" : sourceType,\n });\n if (source.kind === \"url\") {\n return declaredMimeType !== undefined\n ? { type: \"url\", value: source.url, mimeType: declaredMimeType }\n : { type: \"url\", value: source.url };\n }\n return {\n type: \"data\",\n value: source.data,\n mimeType: source.mimeType,\n };\n}\n\nfunction toContentPart(\n part: unknown,\n fallbackMimeType: string | undefined,\n): ContentPart | null {\n if (!isObject(part)) return null;\n const type = getString(part, \"type\");\n\n if (type === \"text\") {\n const text = getString(part, \"text\");\n if (text === undefined) return null;\n return { type: \"text\", text };\n }\n\n if (type === \"image\") {\n const image = getString(part, \"image\");\n if (image === undefined) return null;\n const metadata = buildPartMetadata(part, getString(part, \"filename\"));\n const source = buildPartSource(image, fallbackMimeType);\n return {\n type: \"image\",\n source:\n source.type === \"data\"\n ? {\n ...source,\n mimeType: resolveImageMediaType(image, fallbackMimeType),\n }\n : source,\n ...(metadata && { metadata }),\n };\n }\n\n if (type === \"file\") {\n const data = getString(part, \"data\");\n if (data === undefined) return null;\n const declaredMimeType = getString(part, \"mimeType\") || fallbackMimeType;\n const filename = getString(part, \"filename\");\n const source = buildPartSource(\n data,\n declaredMimeType,\n getString(part, \"sourceType\"),\n );\n const metadata = buildPartMetadata(part, filename);\n switch (mediaTypeForMime(source.mimeType)) {\n case \"image\":\n return { type: \"image\", source, ...(metadata && { metadata }) };\n case \"audio\":\n return { type: \"audio\", source, ...(metadata && { metadata }) };\n case \"video\":\n return { type: \"video\", source, ...(metadata && { metadata }) };\n default:\n return { type: \"document\", source, ...(metadata && { metadata }) };\n }\n }\n\n if (type === \"audio\") {\n const audio = part.audio;\n if (!isObject(audio)) return null;\n const data = getString(audio, \"data\");\n const format = getString(audio, \"format\");\n if (data === undefined || format === undefined) return null;\n return {\n type: \"audio\",\n source: buildPartSource(\n parseDataUrl(data)?.data ?? data,\n `audio/${format}`,\n ),\n };\n }\n\n return null;\n}\n\ntype SnapshotAttachment = NonNullable<\n CoreThreadMessageLike[\"attachments\"]\n>[number];\n\nconst mediaInputTypes = new Set([\"image\", \"audio\", \"video\", \"document\"]);\n\nfunction partSourceToString(\n value: unknown,\n): { value: string; mimeType?: string; isUrl?: boolean } | null {\n if (!isObject(value)) return null;\n const sourceValue = getString(value, \"value\");\n if (sourceValue === undefined) return null;\n const mimeType = getString(value, \"mimeType\");\n const type = getString(value, \"type\");\n if (type === \"url\") {\n return {\n value: sourceValue,\n isUrl: true,\n ...(mimeType !== undefined && { mimeType }),\n };\n }\n if (type === \"data\") {\n const resolvedMimeType = mimeType ?? \"application/octet-stream\";\n return {\n value: `data:${resolvedMimeType};base64,${sourceValue}`,\n mimeType: resolvedMimeType,\n };\n }\n return null;\n}\n\n// Mirrors @ag-ui/client's BackwardCompatibility_0_0_47 middleware.\nfunction upgradeBinaryInputPart(\n part: Record<string, unknown>,\n): Record<string, unknown> | null {\n const mimeType = getString(part, \"mimeType\");\n if (mimeType === undefined) return null;\n const data = getString(part, \"data\");\n const url = getString(part, \"url\");\n const source = data\n ? { type: \"data\", value: data, mimeType }\n : url\n ? { type: \"url\", value: url, mimeType }\n : null;\n if (!source) return null;\n const filename = getString(part, \"filename\");\n return {\n type: mediaTypeForMime(mimeType),\n source,\n ...(filename && { metadata: { filename } }),\n };\n}\n\nfunction normalizeInputPart(\n rawPart: Record<string, unknown>,\n): Record<string, unknown> | null {\n return getString(rawPart, \"type\") === \"binary\"\n ? upgradeBinaryInputPart(rawPart)\n : rawPart;\n}\n\ntype ContentSlot<T> = { index: number } & T;\n\n// Text imports as one string and encoded media as attachments, so export\n// needs the wire layout to restore the original order: each file source part\n// keeps its rank among media, and each text part its position among all kept\n// parts unless the text is one non-empty leading part.\nfunction toUserContentLayout(content: unknown): {\n fileSourceParts: ContentSlot<{ part: Record<string, unknown> }>[];\n textParts: ContentSlot<{ text: string }>[];\n} {\n const fileSourceParts: ContentSlot<{ part: Record<string, unknown> }>[] = [];\n const textParts: ContentSlot<{ text: string }>[] = [];\n if (!Array.isArray(content)) return { fileSourceParts, textParts };\n\n let mediaIndex = 0;\n for (const rawPart of content) {\n if (!isObject(rawPart)) continue;\n if (rawPart.type === \"text\" && typeof rawPart.text === \"string\") {\n textParts.push({\n index: textParts.length + mediaIndex,\n text: rawPart.text,\n });\n continue;\n }\n const part = normalizeInputPart(rawPart);\n if (!part || !mediaInputTypes.has(getString(part, \"type\") ?? \"\")) continue;\n if (\n isObject(part.source) &&\n part.source.type === \"file\" &&\n typeof part.source.value === \"string\"\n ) {\n fileSourceParts.push({ index: mediaIndex++, part });\n } else if (partSourceToString(part.source)) {\n mediaIndex++;\n }\n }\n\n const leadingText =\n textParts.length === 0 ||\n (textParts.length === 1 &&\n textParts[0]!.index === 0 &&\n textParts[0]!.text !== \"\");\n return { fileSourceParts, textParts: leadingText ? [] : textParts };\n}\n\nfunction toSnapshotAttachments(content: unknown): SnapshotAttachment[] {\n if (!Array.isArray(content)) return [];\n\n const attachments: SnapshotAttachment[] = [];\n for (const rawPart of content) {\n if (!isObject(rawPart)) continue;\n const part = normalizeInputPart(rawPart);\n if (!part) continue;\n const type = getString(part, \"type\");\n if (type === undefined || !mediaInputTypes.has(type)) continue;\n const source = partSourceToString(part.source);\n if (!source) continue;\n\n const { filename, providerMetadata } = readPartMetadata(part.metadata);\n const id = attachments.length.toString();\n\n if (type === \"image\") {\n attachments.push({\n id,\n type: \"image\",\n name: filename ?? \"image\",\n ...(source.mimeType !== undefined && { contentType: source.mimeType }),\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: source.value,\n ...(filename !== undefined && { filename }),\n ...(providerMetadata && { providerMetadata }),\n },\n ],\n });\n continue;\n }\n\n const mimeType = source.mimeType ?? \"application/octet-stream\";\n attachments.push({\n id,\n type: type === \"document\" ? \"document\" : \"file\",\n name: filename ?? \"file\",\n contentType: mimeType,\n status: { type: \"complete\" },\n content: [\n {\n type: \"file\",\n data: source.value,\n mimeType,\n ...(source.isUrl && { sourceType: \"url\" as const }),\n ...(filename !== undefined && { filename }),\n ...(providerMetadata && { providerMetadata }),\n },\n ],\n });\n }\n return attachments;\n}\n\nfunction readContentSlots(\n value: unknown,\n): { index: number; entry: Record<string, unknown> }[] {\n if (!Array.isArray(value)) return [];\n return value.flatMap((entry) =>\n isObject(entry) &&\n typeof entry.index === \"number\" &&\n Number.isInteger(entry.index) &&\n entry.index >= 0\n ? [{ index: entry.index, entry }]\n : [],\n );\n}\n\nfunction buildUserContent(message: ThreadMessageLike): string | ContentPart[] {\n const contentParts = Array.isArray(message.content) ? message.content : [];\n\n const attachments = message.attachments ?? [];\n\n const converted: ContentPart[] = [];\n\n // Promote string-form content to a leading text part so it survives when\n // non-text attachments are present (fromAgUiMessages emits string content).\n if (typeof message.content === \"string\" && message.content.length > 0) {\n converted.push({ type: \"text\", text: message.content });\n }\n\n for (const part of contentParts) {\n const input = toContentPart(part, undefined);\n if (input) converted.push(input);\n }\n for (const attachment of attachments) {\n if (!isObject(attachment)) continue;\n const attachmentContent = attachment.content;\n if (!Array.isArray(attachmentContent)) continue;\n const fallbackMime = getString(attachment, \"contentType\");\n for (const part of attachmentContent) {\n const input = toContentPart(part, fallbackMime);\n if (input) converted.push(input);\n }\n }\n\n const namespaced = readNamespacedMetadata(message.metadata);\n const textSlots = readContentSlots(namespaced.textParts).flatMap(\n ({ index, entry }) =>\n typeof entry.text === \"string\"\n ? [{ index, part: { type: \"text\" as const, text: entry.text } }]\n : [],\n );\n const mergedText = converted\n .flatMap((part) => (part.type === \"text\" ? [part.text] : []))\n .join(\"\\n\");\n const restoresText =\n textSlots.length > 0 &&\n textSlots.map(({ part }) => part.text).join(\"\\n\") === mergedText;\n const fileSourceSlots = readContentSlots(namespaced.fileSourceParts).flatMap(\n ({ index, entry: { part } }) =>\n isObject(part) &&\n mediaInputTypes.has(getString(part, \"type\") ?? \"\") &&\n isObject(part.source) &&\n part.source.type === \"file\" &&\n typeof part.source.value === \"string\"\n ? [{ index, part: part as ContentPart }]\n : [],\n );\n const ordered = restoresText\n ? converted.filter((part) => part.type !== \"text\")\n : converted;\n for (const { index, part } of fileSourceSlots.sort(\n (a, b) => a.index - b.index,\n )) {\n const mediaPositions = ordered.flatMap((contentPart, position) =>\n contentPart.type !== \"text\" ? [position] : [],\n );\n ordered.splice(mediaPositions[index] ?? ordered.length, 0, part);\n }\n if (restoresText) {\n for (const { index, part } of textSlots.sort((a, b) => a.index - b.index)) {\n ordered.splice(Math.min(index, ordered.length), 0, part);\n }\n }\n\n if (restoresText || ordered.some((part) => part.type !== \"text\"))\n return ordered;\n\n // All-text path: collapse to plain string. Join text parts collected from\n // both content and attachments so attachment-sourced text is not dropped.\n if (converted.length === 0) return extractText(message.content);\n return converted\n .filter(\n (part): part is { type: \"text\"; text: string } => part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\");\n}\n\nfunction toToolCallPart(value: unknown): ToolCallPart | null {\n if (!isObject(value)) return null;\n const rawFunction = isObject(value.function) ? value.function : null;\n const toolCallId = getString(value, \"toolCallId\") ?? getString(value, \"id\");\n const toolName =\n getString(value, \"toolName\") ??\n getString(value, \"name\") ??\n (rawFunction ? getString(rawFunction, \"name\") : undefined) ??\n \"tool\";\n const argsText =\n getString(value, \"argsText\") ??\n getString(value, \"arguments\") ??\n (rawFunction ? getString(rawFunction, \"arguments\") : undefined);\n\n const parsedArgs =\n typeof argsText === \"string\" ? parseJSONText(argsText) : undefined;\n const args =\n isObject(parsedArgs) && !Array.isArray(parsedArgs)\n ? (parsedArgs as ReadonlyJSONObject)\n : isObject(value.args) && !Array.isArray(value.args)\n ? (value.args as ReadonlyJSONObject)\n : undefined;\n const part: ToolCallPart = {\n type: \"tool-call\",\n ...(toolCallId !== undefined ? { toolCallId } : {}),\n toolName,\n argsText: argsText ?? JSON.stringify(args ?? {}),\n ...(args !== undefined ? { args } : {}),\n };\n\n if (value.type === \"tool-call\") {\n const result = value.result;\n const isError = value.isError;\n if (result !== undefined) part.result = result;\n if (typeof isError === \"boolean\") part.isError = isError;\n }\n\n return part;\n}\n\nfunction extractAssistantToolCalls(\n message: Record<string, unknown>,\n): ToolCallPart[] {\n const parts: ToolCallPart[] = [];\n const seenToolCallIds = new Set<string>();\n const pushPart = (part: ToolCallPart | null) => {\n if (!part) return;\n const id = part.toolCallId ?? generateId();\n if (seenToolCallIds.has(id)) return;\n seenToolCallIds.add(id);\n parts.push({\n ...part,\n toolCallId: id,\n });\n };\n\n const content = message.content;\n if (Array.isArray(content)) {\n for (const part of content) {\n if (isObject(part) && part.type === \"tool-call\") {\n pushPart(toToolCallPart(part));\n }\n }\n }\n\n const toolCalls = Array.isArray(message.toolCalls)\n ? message.toolCalls\n : Array.isArray(message.tool_calls)\n ? message.tool_calls\n : [];\n for (const call of toolCalls) {\n pushPart(toToolCallPart(call));\n }\n\n return parts;\n}\n\nfunction validateInterrupts(value: unknown): AgUiInterrupt[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const valid = value.filter(\n (entry): entry is AgUiInterrupt =>\n isObject(entry) &&\n typeof entry.id === \"string\" &&\n typeof entry.reason === \"string\",\n );\n return valid.length > 0 ? valid : undefined;\n}\n\nfunction readPersistedInterrupts(\n metadata: unknown,\n): AgUiInterrupt[] | undefined {\n if (!isObject(metadata)) return undefined;\n const custom = metadata.custom;\n if (!isObject(custom)) return undefined;\n const namespaced = custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return undefined;\n return validateInterrupts(namespaced.interrupts);\n}\n\nfunction readPersistedPendingToolCallIds(\n metadata: unknown,\n): string[] | undefined {\n const value = readNamespacedMetadata(metadata).pendingToolCallIds;\n return Array.isArray(value) &&\n value.length > 0 &&\n value.every((id): id is string => typeof id === \"string\")\n ? value\n : undefined;\n}\n\nfunction readOpaqueReasoning(metadata: unknown): AgUiOpaqueReasoning[] {\n if (!isObject(metadata)) return [];\n const custom = metadata.custom;\n if (!isObject(custom)) return [];\n const namespaced = custom[AG_UI_METADATA_NAMESPACE];\n if (!isObject(namespaced)) return [];\n const entries = namespaced.opaqueReasoning;\n if (!Array.isArray(entries)) return [];\n return entries.flatMap((entry) => {\n if (!isObject(entry)) return [];\n const id = getString(entry, \"id\");\n const encryptedValue = getString(entry, \"encryptedValue\");\n if (!id?.trim() || !encryptedValue?.trim()) return [];\n const metadata = toAgUiWireMetadata(entry.metadata);\n return [\n {\n id,\n encryptedValue,\n ...(metadata ? { metadata } : {}),\n ...(entry.after === true ? { after: true } : {}),\n },\n ];\n });\n}\n\nfunction withOpaqueReasoning(\n message: CoreThreadMessageLike,\n opaqueReasoning: AgUiOpaqueReasoning[],\n): CoreThreadMessageLike {\n const metadata = isObject(message.metadata) ? message.metadata : {};\n const custom = isObject(metadata.custom) ? metadata.custom : {};\n const namespaced = isObject(custom[AG_UI_METADATA_NAMESPACE])\n ? (custom[AG_UI_METADATA_NAMESPACE] as Record<string, unknown>)\n : {};\n return {\n ...message,\n metadata: {\n ...metadata,\n custom: {\n ...custom,\n [AG_UI_METADATA_NAMESPACE]: { ...namespaced, opaqueReasoning },\n },\n },\n } as CoreThreadMessageLike;\n}\n\nfunction toAssistantSnapshotMessage(\n rawMessage: Record<string, unknown>,\n): CoreThreadMessageLike {\n const text = extractText(rawMessage.content);\n const custom = toSnapshotCustom(rawMessage.metadata);\n const interrupts = readPersistedInterrupts({ custom });\n const restoredToolCalls = extractAssistantToolCalls(rawMessage);\n const approvals = projectAgUiToolApprovals(\n interrupts,\n new Set(\n restoredToolCalls\n .map((part) => part.toolCallId)\n .filter((id): id is string => !!id),\n ),\n );\n const toolCallParts = restoredToolCalls.map((part) => {\n const approval = part.toolCallId\n ? approvals.get(part.toolCallId)\n : undefined;\n return approval ? { ...part, approval } : part;\n });\n const assistantContent = [\n ...(text.length > 0 ? [{ type: \"text\" as const, text }] : []),\n ...toolCallParts,\n ];\n const messageName = getString(rawMessage, \"name\");\n const namespaced = isObject(custom[AG_UI_METADATA_NAMESPACE])\n ? { ...custom[AG_UI_METADATA_NAMESPACE] }\n : {};\n if (interrupts) namespaced.interrupts = interrupts;\n else delete namespaced.interrupts;\n const messageCustom = { ...custom };\n if (Object.keys(namespaced).length > 0) {\n messageCustom[AG_UI_METADATA_NAMESPACE] = namespaced;\n } else {\n delete messageCustom[AG_UI_METADATA_NAMESPACE];\n }\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: assistantContent.length > 0 ? assistantContent : \"\",\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(Object.keys(messageCustom).length > 0\n ? { metadata: { custom: messageCustom } }\n : {}),\n };\n}\n\nfunction toUserOrSystemSnapshotMessage(\n role: \"user\" | \"system\" | \"developer\",\n rawMessage: Record<string, unknown>,\n): CoreThreadMessageLike {\n const messageName = getString(rawMessage, \"name\");\n const { fileSourceParts, textParts } =\n role === \"user\"\n ? toUserContentLayout(rawMessage.content)\n : { fileSourceParts: [], textParts: [] };\n const custom = toSnapshotCustom(rawMessage.metadata, {\n ...(role === \"developer\" ? { role: \"developer\" } : {}),\n ...(fileSourceParts.length > 0 ? { fileSourceParts } : {}),\n ...(textParts.length > 0 ? { textParts } : {}),\n });\n const attachments =\n role === \"user\" ? toSnapshotAttachments(rawMessage.content) : [];\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n // The internal message model has no developer role; it rides as a system\n // message with its wire role kept in metadata so the export restores it.\n role: role === \"developer\" ? \"system\" : role,\n content: extractText(rawMessage.content),\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(attachments.length > 0 ? { attachments } : {}),\n ...(Object.keys(custom).length > 0 ? { metadata: { custom } } : {}),\n };\n}\n\nfunction attachA2uiSurfaces(\n message: CoreThreadMessageLike,\n state: A2uiState,\n): CoreThreadMessageLike {\n const a2uiParts: ToolCallPart[] = [];\n for (const [surfaceId, surface] of state) {\n const { toolCall } = surfaceToPresentToolCall(surfaceId, surface);\n if (!toolCall) continue;\n a2uiParts.push({\n type: \"tool-call\",\n ...toolCall,\n });\n }\n\n const content = Array.isArray(message.content) ? message.content : [];\n const preserved = content.filter(\n (part) =>\n !(\n isObject(part) &&\n part.type === \"tool-call\" &&\n typeof part.toolCallId === \"string\" &&\n part.toolCallId.startsWith(\"a2ui:\")\n ),\n );\n return { ...message, content: [...preserved, ...a2uiParts] };\n}\n\n// A tool call that arrives without a `parentMessageId` has no record to join, so\n// the client opens one keyed by the call id. An assistant record whose own id is\n// a call it carries is that container: an id the client invented for the call\n// rather than a boundary an agent drew. The prose of the turn lands in records\n// of its own on either side of it, and nothing on the wire binds them to the\n// run that produced them.\nfunction isSyntheticToolCallContainer(message: CoreThreadMessageLike): boolean {\n if (message.role !== \"assistant\" || !Array.isArray(message.content))\n return false;\n let carriesOwnId = false;\n for (const part of message.content) {\n if (!isObject(part)) continue;\n // The container is opened empty, so text on the record means an agent\n // addressed it and the id is one it chose.\n if (part.type === \"text\") return false;\n if (\n part.type === \"tool-call\" &&\n getString(part, \"toolCallId\") === message.id\n ) {\n carriesOwnId = true;\n }\n }\n return carriesOwnId;\n}\n\nfunction carriesPart(message: CoreThreadMessageLike, type: string): boolean {\n return (\n Array.isArray(message.content) &&\n message.content.some((part) => isObject(part) && part.type === type)\n );\n}\n\nfunction carriesText(message: CoreThreadMessageLike): boolean {\n return carriesPart(message, \"text\");\n}\n\n// A container joins the assistant record ahead of it when that record holds\n// prose or calls of the turn. A released reasoning record holds neither: its\n// part leaves the export under the record's own id, so a message merged under\n// that id would put two records with one id on the wire.\nfunction opensTurn(message: CoreThreadMessageLike): boolean {\n return (\n message.role === \"assistant\" &&\n (carriesText(message) || carriesPart(message, \"tool-call\"))\n );\n}\n\n// The parts of the answer fold onto the container ahead of them. A record\n// carrying a tool call an agent addressed is a boundary of its own and keeps\n// its message.\nfunction answersToolCallContainer(message: CoreThreadMessageLike): boolean {\n if (message.role !== \"assistant\" || !Array.isArray(message.content))\n return false;\n if (message.content.length === 0) return false;\n return !message.content.some(\n (part) => isObject(part) && part.type === \"tool-call\",\n );\n}\n\nfunction readCustomMetadata(metadata: unknown): Record<string, unknown> {\n if (!isObject(metadata) || !isObject(metadata.custom)) return {};\n return metadata.custom;\n}\n\nfunction readNamespacedMetadata(metadata: unknown): Record<string, unknown> {\n const namespaced = readCustomMetadata(metadata)[AG_UI_METADATA_NAMESPACE];\n return isObject(namespaced) ? namespaced : {};\n}\n\nfunction foldTurnRecords(\n previous: CoreThreadMessageLike,\n message: CoreThreadMessageLike,\n): CoreThreadMessageLike {\n const interrupts = [\n ...(readPersistedInterrupts(previous.metadata) ?? []),\n ...(readPersistedInterrupts(message.metadata) ?? []),\n ];\n // An entry that rode a record behind the turn's calls sat ahead of content\n // that now follows them, so it is replayed after the merged record and its\n // tool results rather than ahead of a message that no longer starts there.\n // One that rode the container opening the turn sat ahead of every call and\n // stays ahead of the record.\n const trailsCalls = carriesPart(previous, \"tool-call\");\n const opaqueReasoning = [\n ...readOpaqueReasoning(previous.metadata),\n ...readOpaqueReasoning(message.metadata).map((entry) =>\n trailsCalls ? { ...entry, after: true } : entry,\n ),\n ];\n const namespaced = {\n ...readNamespacedMetadata(previous.metadata),\n ...readNamespacedMetadata(message.metadata),\n ...(interrupts.length > 0 ? { interrupts } : {}),\n ...(opaqueReasoning.length > 0 ? { opaqueReasoning } : {}),\n } satisfies AgUiCustomMetadata & Record<string, unknown>;\n const custom = {\n ...readCustomMetadata(previous.metadata),\n ...readCustomMetadata(message.metadata),\n ...(Object.keys(namespaced).length > 0\n ? { [AG_UI_METADATA_NAMESPACE]: namespaced }\n : {}),\n };\n const metadata = {\n ...(isObject(previous.metadata) ? previous.metadata : {}),\n ...(isObject(message.metadata) ? message.metadata : {}),\n ...(Object.keys(custom).length > 0 ? { custom } : {}),\n };\n return {\n ...previous,\n ...message,\n // A container's id names a call rather than the turn, so the record the\n // agent addressed its prose to wins: that is the id the next run has to\n // carry for the agent to recognize the message it wrote.\n id: carriesText(message) ? message.id : previous.id,\n content: [\n ...(Array.isArray(previous.content) ? previous.content : []),\n ...(Array.isArray(message.content) ? message.content : []),\n ],\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n } as CoreThreadMessageLike;\n}\n\nexport type FromAgUiMessagesOptions = {\n /**\n * Whether to convert `reasoning` messages into visible reasoning parts.\n * Matches the `showThinking` option of `useAgUiRuntime`. Defaults to `true`.\n */\n showThinking?: boolean;\n};\n\nexport function fromAgUiMessages(\n messages: readonly unknown[],\n options?: FromAgUiMessagesOptions,\n): CoreThreadMessageLike[] {\n const showThinking = options?.showThinking ?? true;\n const converted: CoreThreadMessageLike[] = [];\n const a2uiBuckets = new Map<string, A2uiState>();\n const a2uiBucketOwnerIndices = new Map<string, number>();\n const activityParts = new Map<\n string,\n { ownerIndex: number; part: { type: \"data\"; name: string; data: unknown } }\n >();\n // A zero-data-retention run carries its payload in encryptedValue with no\n // readable content, so the record has no part to become and rides on the\n // neighbouring message instead of being dropped. The anchor is the index the\n // next pushed message will occupy, which is where it sat on the wire.\n const opaqueReasoning: (AgUiOpaqueReasoning & { anchor: number })[] = [];\n // A reasoning record belongs to the assistant record that follows it, which is\n // the binding the export writes and the one the reference integrations read\n // back. Holding it until that assistant arrives rebuilds the pair as the\n // single message the live run produced.\n const pendingReasoning: {\n id: string | undefined;\n part: ReasoningMessagePart;\n }[] = [];\n\n const flushPendingReasoning = () => {\n for (const { id, part } of pendingReasoning) {\n converted.push({\n id: id ?? generateId(),\n role: \"assistant\",\n content: [part],\n });\n }\n pendingReasoning.length = 0;\n };\n\n const withPendingReasoning = (\n message: CoreThreadMessageLike,\n ): CoreThreadMessageLike => {\n if (pendingReasoning.length === 0) return message;\n const parts = pendingReasoning.map(({ part }) => part);\n pendingReasoning.length = 0;\n return {\n ...message,\n content: [\n ...parts,\n ...(Array.isArray(message.content) ? message.content : []),\n ],\n };\n };\n\n for (const rawMessage of messages) {\n if (!isObject(rawMessage)) continue;\n const role = getString(rawMessage, \"role\");\n if (!role) continue;\n\n if (role === \"tool\") {\n flushPendingReasoning();\n const toolCallId = getToolCallId(rawMessage) ?? `tool-${generateId()}`;\n const toolMessageId = getString(rawMessage, \"id\");\n const modelContent = Array.isArray(rawMessage.content)\n ? toolContentText(rawMessage.content as ContentPart[])\n : extractText(rawMessage.content);\n const mcpResult = parseMcpToolCallResult(\n rawMessage,\n Array.isArray(rawMessage.content)\n ? (rawMessage.content as ContentPart[])\n : modelContent,\n );\n const toolModelContent = mcpResult\n ? [{ type: \"text\" as const, text: modelContent }]\n : undefined;\n const result =\n mcpResult ??\n (Array.isArray(rawMessage.content)\n ? rawMessage.content\n : rawMessage.result !== undefined\n ? rawMessage.result\n : typeof rawMessage.content === \"string\"\n ? parseJSONText(rawMessage.content)\n : rawMessage.content);\n const isError =\n typeof rawMessage.error === \"string\" ||\n rawMessage.isError === true ||\n rawMessage.status === \"error\"\n ? true\n : rawMessage.isError === false\n ? false\n : undefined;\n const mcpAppUri = readMcpAppResourceUri(mcpResult?._meta);\n const mcpApp =\n mcpAppUri !== undefined ? { resourceUri: mcpAppUri } : undefined;\n const messageMetadata = toAgUiWireMetadata(rawMessage.metadata);\n\n let updated = false;\n for (\n let messageIndex = converted.length - 1;\n messageIndex >= 0 && !updated;\n messageIndex--\n ) {\n const message = converted[messageIndex];\n if (\n !message ||\n message.role !== \"assistant\" ||\n !Array.isArray(message.content)\n )\n continue;\n\n for (\n let partIndex = message.content.length - 1;\n partIndex >= 0;\n partIndex--\n ) {\n const part = message.content[partIndex];\n if (!isObject(part) || part.type !== \"tool-call\") continue;\n if (getString(part, \"toolCallId\") !== toolCallId) continue;\n\n const { modelContent: _modelContent, ...partWithoutModelContent } =\n part as ToolCallPart;\n const updatedPart: ToolCallPart = {\n ...(Array.isArray(rawMessage.content) && !mcpResult\n ? partWithoutModelContent\n : (part as ToolCallPart)),\n result,\n ...(toolModelContent ? { modelContent: toolModelContent } : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(toolMessageId !== undefined\n ? { unstable_toolMessageId: toolMessageId }\n : {}),\n ...(mcpApp ? { mcp: { app: mcpApp } } : {}),\n ...(messageMetadata\n ? {\n providerMetadata: withAgUiPartMessageMetadata(\n (part as ToolCallPart).providerMetadata,\n messageMetadata,\n ),\n }\n : {}),\n };\n const updatedContent = message.content.map((contentPart, index) =>\n index === partIndex ? updatedPart : contentPart,\n );\n converted[messageIndex] = { ...message, content: updatedContent };\n updated = true;\n break;\n }\n }\n\n if (updated) {\n continue;\n }\n\n const id = toolMessageId ?? toolCallId;\n const toolName =\n getString(rawMessage, \"name\") ??\n getString(rawMessage, \"toolName\") ??\n \"tool\";\n converted.push({\n id: `${id}:assistant`,\n role: \"assistant\",\n content: [\n {\n type: \"tool-call\",\n toolCallId,\n toolName,\n args: {},\n argsText: \"{}\",\n result,\n ...(toolModelContent ? { modelContent: toolModelContent } : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(toolMessageId !== undefined\n ? { unstable_toolMessageId: toolMessageId }\n : {}),\n ...(mcpApp ? { mcp: { app: mcpApp } } : {}),\n ...(messageMetadata\n ? {\n providerMetadata: withAgUiPartMessageMetadata(\n undefined,\n messageMetadata,\n ),\n }\n : {}),\n },\n ],\n });\n continue;\n }\n\n if (role === \"activity\") {\n const activityType = getString(rawMessage, \"activityType\");\n if (activityType === undefined || activityType === MCP_APPS_ACTIVITY_TYPE)\n continue;\n\n // A surface belongs to the turn that painted it, and held reasoning is a\n // nearer antecedent than the previous turn's assistant record, so it is\n // released here rather than folded past this record.\n flushPendingReasoning();\n\n let ownerIndex = -1;\n for (let i = converted.length - 1; i >= 0; i--) {\n const candidate = converted[i];\n if (candidate && candidate.role === \"assistant\") {\n ownerIndex = i;\n break;\n }\n }\n if (ownerIndex === -1) continue;\n\n const owner = converted[ownerIndex]!;\n if (activityType !== A2UI_SURFACE_ACTIVITY_TYPE) {\n const bucketKey =\n getString(rawMessage, \"id\") ?? `agui-activity:${activityType}`;\n const part = {\n type: \"data\" as const,\n name: `agui-activity/${activityType}`,\n data: rawMessage.content,\n };\n const existing = activityParts.get(bucketKey);\n const existingOwner = existing && converted[existing.ownerIndex];\n const existingIndex =\n existingOwner && Array.isArray(existingOwner.content)\n ? existingOwner.content.indexOf(existing.part)\n : -1;\n if (existing && existingOwner && existingIndex !== -1) {\n const content = [...(existingOwner.content as unknown[])];\n content[existingIndex] = part;\n converted[existing.ownerIndex] = {\n ...existingOwner,\n content: content as typeof existingOwner.content,\n };\n activityParts.set(bucketKey, {\n ownerIndex: existing.ownerIndex,\n part,\n });\n continue;\n }\n\n const content = Array.isArray(owner.content) ? owner.content : [];\n activityParts.set(bucketKey, { ownerIndex, part });\n converted[ownerIndex] = {\n ...owner,\n content: [...content, part],\n };\n continue;\n }\n\n const activityContent = isObject(rawMessage.content)\n ? (rawMessage.content as Record<string, unknown>)\n : null;\n const operations = activityContent?.[\"a2ui_operations\"];\n if (!Array.isArray(operations)) continue;\n const bucketKey = getString(rawMessage, \"id\") ?? \"a2ui:anonymous\";\n const { state } = applyA2uiOperations(new Map(), operations);\n a2uiBuckets.delete(bucketKey);\n a2uiBucketOwnerIndices.delete(bucketKey);\n a2uiBuckets.set(bucketKey, state);\n a2uiBucketOwnerIndices.set(bucketKey, ownerIndex);\n\n const ownerState = new Map<string, A2uiSurfaceState>();\n for (const [candidateBucketKey, candidateState] of a2uiBuckets) {\n if (a2uiBucketOwnerIndices.get(candidateBucketKey) !== ownerIndex)\n continue;\n for (const [surfaceId, surface] of candidateState) {\n ownerState.set(surfaceId, surface);\n }\n }\n converted[ownerIndex] = attachA2uiSurfaces(owner, ownerState);\n continue;\n }\n\n if (role === \"assistant\") {\n converted.push(\n withPendingReasoning(toAssistantSnapshotMessage(rawMessage)),\n );\n continue;\n }\n\n if (role === \"reasoning\") {\n const text = extractText(rawMessage.content);\n const encryptedValue = getString(rawMessage, \"encryptedValue\");\n const messageMetadata = toAgUiWireMetadata(rawMessage.metadata);\n if (text.trim().length === 0) {\n // showThinking hides reasoning; this record is never rendered anyway,\n // and dropping it would deny the provider the payload it needs to\n // accept the next run.\n const opaqueId = getString(rawMessage, \"id\");\n if (opaqueId?.trim() && encryptedValue?.trim()) {\n // The anchor counts materialized messages, so anything still held\n // takes its own slot rather than folding past this record.\n flushPendingReasoning();\n opaqueReasoning.push({\n id: opaqueId,\n encryptedValue,\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n anchor: converted.length,\n });\n }\n continue;\n }\n // Gate visible reasoning on showThinking so a cold reload matches the\n // live run: the aggregator never stores reasoning parts when it is off.\n // A signature on a hidden record is still transport state, so it is kept\n // opaque rather than discarded with the text.\n if (!showThinking) {\n const hiddenId = getString(rawMessage, \"id\");\n if (hiddenId?.trim() && encryptedValue?.trim()) {\n opaqueReasoning.push({\n id: hiddenId,\n encryptedValue,\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n anchor: converted.length,\n });\n }\n continue;\n }\n const rawReasoningId = getString(rawMessage, \"id\");\n // A blank id still wins over a synthesized one on export, which would put\n // an unaddressable record on the wire.\n const reasoningId = rawReasoningId?.trim() ? rawReasoningId : undefined;\n // The fold costs the record its own message id, so it rides the part\n // instead: the export re-emits each block under the id it arrived with.\n const meta = {\n ...(reasoningId !== undefined ? { reasoningId } : {}),\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n ...(messageMetadata\n ? { messageMetadata: messageMetadata as ReadonlyJSONObject }\n : {}),\n };\n pendingReasoning.push({\n id: reasoningId,\n part: {\n type: \"reasoning\",\n text,\n ...(Object.keys(meta).length > 0\n ? { providerMetadata: { [AG_UI_METADATA_NAMESPACE]: meta } }\n : {}),\n },\n });\n continue;\n }\n\n if (role === \"user\" || role === \"system\" || role === \"developer\") {\n flushPendingReasoning();\n converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));\n }\n }\n\n flushPendingReasoning();\n\n for (const { anchor, ...entry } of opaqueReasoning) {\n // Nothing followed it on the wire, so it trails the last message instead.\n const trailing = anchor >= converted.length;\n const index = trailing ? converted.length - 1 : anchor;\n const target = converted[index];\n if (!target) continue;\n converted[index] = withOpaqueReasoning(target, [\n ...readOpaqueReasoning(target.metadata),\n ...(trailing ? [{ ...entry, after: true }] : [entry]),\n ]);\n }\n\n // A turn that called a tool without addressing a record sits on the wire as\n // a container beside the records around it, which the live run renders as\n // one message: the container joins the assistant record ahead of it, and\n // what follows a container joins it until the turn carries text, where a\n // further text record opens a message of its own as it does live.\n const folded: CoreThreadMessageLike[] = [];\n for (const message of converted) {\n const previous = folded[folded.length - 1];\n if (\n previous !== undefined &&\n (isSyntheticToolCallContainer(message)\n ? opensTurn(previous)\n : isSyntheticToolCallContainer(previous) &&\n answersToolCallContainer(message))\n ) {\n folded[folded.length - 1] = foldTurnRecords(previous, message);\n continue;\n }\n folded.push(message);\n }\n\n for (let i = 0; i < folded.length; i++) {\n const message = folded[i]!;\n if (message.role !== \"assistant\") continue;\n\n const hasInterrupt =\n readPersistedInterrupts(message.metadata) !== undefined;\n const pendingToolCallIds = readPersistedPendingToolCallIds(\n message.metadata,\n );\n const hasPendingToolCall =\n Array.isArray(message.content) &&\n message.content.some(\n (part) =>\n isObject(part) &&\n part.type === \"tool-call\" &&\n part.result === undefined &&\n (pendingToolCallIds === undefined ||\n pendingToolCallIds.includes(getString(part, \"toolCallId\") ?? \"\")),\n );\n\n if (hasInterrupt || hasPendingToolCall) {\n folded[i] = {\n ...message,\n status: getAutoStatus(\n false,\n false,\n hasInterrupt,\n hasPendingToolCall,\n undefined,\n ),\n };\n }\n }\n\n return folded;\n}\n\nfunction convertAssistantMessage(\n message: NormalizedThreadMessageLike,\n converted: AgUiMessage[],\n): void {\n const content = extractText(message.content);\n const contentArray = Array.isArray(message.content) ? message.content : [];\n\n const toolCallParts = contentArray.filter(\n (part): part is ToolCallPart =>\n part?.type === \"tool-call\" &&\n !(\n typeof part.toolCallId === \"string\" &&\n part.toolCallId.startsWith(\"a2ui:\")\n ),\n );\n\n const toolCalls = toolCallParts.map((part) => ({\n ...normalizeToolCall(part),\n part,\n }));\n\n // An AG-UI assistant record has no reasoning field, so reasoning leaves as\n // the standalone record it arrived as, ahead of the assistant it belongs to.\n const shellIsDropped = content.length === 0 && toolCalls.length === 0;\n let reasoningIndex = 0;\n for (const part of contentArray) {\n if (!isObject(part) || part.type !== \"reasoning\") continue;\n const text = getString(part, \"text\") ?? \"\";\n if (text.trim().length === 0) continue;\n const { encryptedValue, reasoningId, messageMetadata } =\n readAgUiReasoningMeta(part.providerMetadata);\n converted.push({\n // The wire id is what a signature was issued against, so it wins over a\n // synthesized one whenever the run carried it.\n id: reasoningId?.trim()\n ? reasoningId\n : shellIsDropped && reasoningIndex === 0\n ? message.id\n : `${message.id}:reasoning-${reasoningIndex}`,\n role: \"reasoning\",\n content: text,\n ...(encryptedValue !== undefined ? { encryptedValue } : {}),\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n });\n reasoningIndex++;\n }\n\n // Some providers reject a replayed blank assistant turn, even when it carries metadata.\n if (shellIsDropped) {\n return;\n }\n\n // A subagent's tool calls live on nested assistant messages. Before\n // subagent attribution they flattened to root and went out with this\n // assistant record as their antecedent, so the resume payload restores\n // exactly that shape: the calls join this record's toolCalls and their\n // results follow as tool records — never a tool record without its call.\n // The nested assistant content itself is backend-owned state and is not\n // re-sent.\n const nestedToolCalls: {\n id: string;\n call: AgUiToolCall;\n part: ToolCallPart;\n }[] = [];\n for (const { part } of toolCalls) {\n for (const { part: nestedToolCall } of walkToolCallTree(\n part.messages ?? [],\n { shouldDescend: isExportableNestedToolCall },\n )) {\n if (!isExportableNestedToolCall(nestedToolCall)) continue;\n nestedToolCalls.push({\n ...normalizeToolCall(nestedToolCall),\n part: nestedToolCall,\n });\n }\n }\n\n converted.push({\n id: message.id,\n role: \"assistant\",\n content,\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n ...(toolCalls.length + nestedToolCalls.length > 0\n ? {\n toolCalls: [...toolCalls, ...nestedToolCalls].map(\n (entry) => entry.call,\n ),\n }\n : {}),\n });\n\n for (const { id: toolCallId, part } of toolCalls) {\n emitToolResult(toolCallId, part, converted);\n }\n for (const { id: toolCallId, part } of nestedToolCalls) {\n // A result recorded while the call's approval gate is still open must not\n // reach the backend as if the gate had been decided.\n const gateOpen =\n part.approval != null &&\n part.approval.approved === undefined &&\n part.approval.resolution === undefined;\n if (gateOpen) continue;\n emitToolResult(toolCallId, part, converted);\n }\n}\n\nfunction isToolContentParts(value: unknown): value is ContentPart[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n value.every(\n (part) =>\n isObject(part) &&\n (part.type === \"text\"\n ? typeof part.text === \"string\"\n : mediaInputTypes.has(getString(part, \"type\") ?? \"\") &&\n isObject(part.source) &&\n typeof part.source.value === \"string\"),\n )\n );\n}\n\nfunction emitToolResult(\n toolCallId: string,\n part: ToolCallPart,\n converted: AgUiMessage[],\n): void {\n if (part.result === undefined) return;\n\n let resultContent: string | ContentPart[];\n if (part.modelContent?.some((content) => content.type === \"file\")) {\n resultContent = part.modelContent.flatMap((content) => {\n const contentPart = toContentPart(\n content,\n content.type === \"file\" ? content.mediaType : undefined,\n );\n return contentPart ? [contentPart] : [];\n });\n } else if (part.modelContent !== undefined) {\n resultContent = extractText(part.modelContent);\n } else if (isToolContentParts(part.result)) {\n resultContent = part.result;\n } else if (typeof part.result === \"string\") {\n resultContent = part.result;\n } else {\n resultContent = JSON.stringify(part.result);\n }\n const messageMetadata = readAgUiPartMessageMetadata(part.providerMetadata);\n\n converted.push({\n id: part.unstable_toolMessageId ?? `${toolCallId}:tool`,\n role: \"tool\",\n content: resultContent,\n toolCallId,\n ...(part.isError\n ? {\n error: Array.isArray(resultContent)\n ? toolContentText(resultContent)\n : resultContent,\n }\n : {}),\n ...(messageMetadata ? { metadata: messageMetadata } : {}),\n });\n}\n\nfunction convertToolMessage(\n message: NormalizedThreadMessageLike,\n converted: AgUiMessage[],\n): void {\n const content = isToolContentParts(message.content)\n ? message.content\n : extractText(message.content);\n const toolCallId = message.toolCallId ?? generateId();\n\n converted.push({\n id: message.id,\n role: \"tool\",\n content,\n toolCallId,\n ...(typeof message.error === \"string\" ? { error: message.error } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n}\n\nexport function toAgUiMessages(\n messages: readonly ThreadMessageLike[],\n): AgUiMessage[] {\n const converted: AgUiMessage[] = [];\n\n for (const rawMessage of messages) {\n const message: NormalizedThreadMessageLike = {\n ...rawMessage,\n id: rawMessage.id ?? generateId(),\n };\n const opaqueReasoning = readOpaqueReasoning(message.metadata);\n const toOpaqueRecord = (entry: AgUiOpaqueReasoning): AgUiMessage => ({\n id: entry.id,\n role: \"reasoning\",\n content: \"\",\n encryptedValue: entry.encryptedValue,\n ...(entry.metadata ? { metadata: entry.metadata } : {}),\n });\n for (const entry of opaqueReasoning) {\n if (entry.after !== true) converted.push(toOpaqueRecord(entry));\n }\n const flushTrailingOpaqueReasoning = () => {\n for (const entry of opaqueReasoning) {\n if (entry.after === true) converted.push(toOpaqueRecord(entry));\n }\n };\n\n if (message.role === \"assistant\") {\n convertAssistantMessage(message, converted);\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"tool\") {\n convertToolMessage(message, converted);\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"user\") {\n converted.push({\n id: message.id,\n role: \"user\",\n content: buildUserContent(message),\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"system\" || message.role === \"developer\") {\n const custom = isObject(message.metadata)\n ? message.metadata.custom\n : undefined;\n const namespaced = isObject(custom)\n ? custom[AG_UI_METADATA_NAMESPACE]\n : undefined;\n const wireRole =\n message.role === \"system\" &&\n isObject(namespaced) &&\n namespaced.role === \"developer\"\n ? (\"developer\" as const)\n : message.role;\n converted.push({\n id: message.id,\n role: wireRole,\n content: extractText(message.content),\n ...(message.name ? { name: message.name } : {}),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n if (message.role === \"reasoning\") {\n converted.push({\n id: message.id,\n role: \"reasoning\",\n content: extractText(message.content),\n ...withAgUiMessageMetadata(message.metadata),\n });\n flushTrailingOpaqueReasoning();\n continue;\n }\n\n flushTrailingOpaqueReasoning();\n }\n\n return converted;\n}\n\ntype AgUiTool = NonNullable<RunAgentParameters[\"tools\"]>[number];\n\nexport function toAgUiTools(\n tools: Record<string, Tool> | undefined,\n): AgUiTool[] {\n if (!tools) return [];\n\n const toolsSchema = toToolsJSONSchema(tools);\n return Object.entries(toolsSchema).map(([name, tool]) => ({\n name,\n description: tool.description ?? \"\",\n parameters: tool.parameters,\n }));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ThreadAssistantMessage, ToolCallMessagePart } from "@assistant-ui/core";
|
|
2
|
+
type Content = ThreadAssistantMessage["content"];
|
|
3
|
+
type Part = Content[number];
|
|
4
|
+
export declare function indexReplayToolOwners(owners: readonly ThreadAssistantMessage[]): ReadonlyMap<string, string>;
|
|
5
|
+
export declare function groupReplayToolContent(owners: readonly ThreadAssistantMessage[], content: Content, fallbackMessageId: string): Map<string, Part[]>;
|
|
6
|
+
export declare function preserveToolResult(previous: ToolCallMessagePart, next: ToolCallMessagePart): ToolCallMessagePart;
|
|
7
|
+
export declare function createReplayContentMerger(): (previous: Content, next: Content) => Content;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=replay-content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-content.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/replay-content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EAEtB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAQ5B,KAAK,OAAO,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;AACjD,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE5B,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,sBAAsB,EAAE,GACxC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAS7B;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,sBAAsB,EAAE,EACzC,OAAO,EAAE,OAAO,EAChB,iBAAiB,EAAE,MAAM,GACxB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAarB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,mBAAmB,GACxB,mBAAmB,CAWrB;AAqKD,wBAAgB,yBAAyB,IAAI,CAC3C,QAAQ,EAAE,OAAO,EACjB,IAAI,EAAE,OAAO,KACV,OAAO,CAUX"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { preserveToolApprovalDecision } from "./tool-approval.js";
|
|
2
|
+
import { iterateToolCallParts, mapToolCallPartsDeep } from "@assistant-ui/core/internal";
|
|
3
|
+
// src/runtime/adapter/replay-content.ts
|
|
4
|
+
function indexReplayToolOwners(owners) {
|
|
5
|
+
const ownerByToolCallId = /* @__PURE__ */ new Map();
|
|
6
|
+
for (const owner of owners) for (const part of iterateToolCallParts(owner.content)) if (!ownerByToolCallId.has(part.toolCallId)) ownerByToolCallId.set(part.toolCallId, owner.id);
|
|
7
|
+
return ownerByToolCallId;
|
|
8
|
+
}
|
|
9
|
+
function groupReplayToolContent(owners, content, fallbackMessageId) {
|
|
10
|
+
const ownerByToolCallId = indexReplayToolOwners(owners);
|
|
11
|
+
const grouped = /* @__PURE__ */ new Map([[fallbackMessageId, []]]);
|
|
12
|
+
for (const part of content) {
|
|
13
|
+
const ownerId = part.type === "tool-call" ? ownerByToolCallId.get(part.toolCallId) ?? fallbackMessageId : fallbackMessageId;
|
|
14
|
+
const parts = grouped.get(ownerId) ?? [];
|
|
15
|
+
parts.push(part);
|
|
16
|
+
grouped.set(ownerId, parts);
|
|
17
|
+
}
|
|
18
|
+
return grouped;
|
|
19
|
+
}
|
|
20
|
+
function preserveToolResult(previous, next) {
|
|
21
|
+
if (previous.result === void 0 || next.result !== void 0) return next;
|
|
22
|
+
return {
|
|
23
|
+
...next,
|
|
24
|
+
result: previous.result,
|
|
25
|
+
...previous.artifact !== void 0 ? { artifact: previous.artifact } : {},
|
|
26
|
+
...previous.isError !== void 0 ? { isError: previous.isError } : {},
|
|
27
|
+
...previous.modelContent !== void 0 ? { modelContent: previous.modelContent } : {}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function mergeOrdered(previous, next, merge) {
|
|
31
|
+
const old = new Map(previous.map(([value, key]) => [key, value]));
|
|
32
|
+
const indexes = new Map(next.map(([, key], index) => [key, index]));
|
|
33
|
+
const insertions = Array.from({ length: next.length + 1 }, () => []);
|
|
34
|
+
let predecessor = -1;
|
|
35
|
+
for (const [value, key] of previous) {
|
|
36
|
+
const index = indexes.get(key);
|
|
37
|
+
if (index === void 0) insertions[predecessor + 1].push(value);
|
|
38
|
+
else predecessor = index;
|
|
39
|
+
}
|
|
40
|
+
const result = [];
|
|
41
|
+
for (const [index, [value, key]] of next.entries()) {
|
|
42
|
+
const prior = old.get(key);
|
|
43
|
+
result.push(...insertions[index], prior === void 0 ? value : merge(prior, value));
|
|
44
|
+
}
|
|
45
|
+
result.push(...insertions[next.length]);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function mergeMessages(previous, next) {
|
|
49
|
+
return mergeOrdered(previous.map((message) => [message, message.id]), next.map((message) => [message, message.id]), (old, fresh) => old.role === "assistant" && fresh.role === "assistant" ? {
|
|
50
|
+
...fresh,
|
|
51
|
+
content: mergeReplayContent(old.content, fresh.content)
|
|
52
|
+
} : fresh);
|
|
53
|
+
}
|
|
54
|
+
function mergeTool(previous, next) {
|
|
55
|
+
const result = preserveToolResult(previous, next);
|
|
56
|
+
const approval = preserveToolApprovalDecision(previous, next);
|
|
57
|
+
return {
|
|
58
|
+
...result,
|
|
59
|
+
...approval ? { approval } : {},
|
|
60
|
+
...result.unstable_interactions === void 0 && previous.unstable_interactions !== void 0 ? { unstable_interactions: previous.unstable_interactions } : {},
|
|
61
|
+
...previous.messages !== void 0 || next.messages !== void 0 ? { messages: mergeMessages(previous.messages ?? [], next.messages ?? []) } : {}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function partKey(part) {
|
|
65
|
+
if (part.type === "tool-call") return `tool:${part.toolCallId}`;
|
|
66
|
+
if (part.type === "text" || part.type === "reasoning") return part.type;
|
|
67
|
+
if ("id" in part && typeof part.id === "string" && part.id) return `${part.type}:${part.id}`;
|
|
68
|
+
if (part.type === "data") return `data:${part.name}`;
|
|
69
|
+
return part.type;
|
|
70
|
+
}
|
|
71
|
+
function keyed(content) {
|
|
72
|
+
const ordinals = /* @__PURE__ */ new Map();
|
|
73
|
+
return content.map((part) => {
|
|
74
|
+
const base = partKey(part);
|
|
75
|
+
const ordinal = ordinals.get(base) ?? 0;
|
|
76
|
+
ordinals.set(base, ordinal + 1);
|
|
77
|
+
return [part, `${base}:${ordinal}`];
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function identity(part, key, scope) {
|
|
81
|
+
return JSON.stringify(part.type === "tool-call" ? ["tool", part.toolCallId] : [...scope, key]);
|
|
82
|
+
}
|
|
83
|
+
function visitMessages(messages, scope, visit) {
|
|
84
|
+
for (const message of messages) {
|
|
85
|
+
const path = [
|
|
86
|
+
...scope,
|
|
87
|
+
"message",
|
|
88
|
+
message.id
|
|
89
|
+
];
|
|
90
|
+
visit(JSON.stringify(path));
|
|
91
|
+
if (message.role === "assistant") visitContent(message.content, path, visit);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function visitContent(content, scope, visit) {
|
|
95
|
+
for (const [part, key] of keyed(content)) {
|
|
96
|
+
visit(identity(part, key, scope));
|
|
97
|
+
if (part.type === "tool-call" && part.messages) visitMessages(part.messages, ["tool", part.toolCallId], visit);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function pruneMessages(messages, scope, present, owned) {
|
|
101
|
+
let hasCurrent = false;
|
|
102
|
+
return {
|
|
103
|
+
messages: messages.flatMap((message) => {
|
|
104
|
+
const path = [
|
|
105
|
+
...scope,
|
|
106
|
+
"message",
|
|
107
|
+
message.id
|
|
108
|
+
];
|
|
109
|
+
const key = JSON.stringify(path);
|
|
110
|
+
const nested = message.role === "assistant" ? pruneContent(message.content, path, present, owned) : void 0;
|
|
111
|
+
const current = present.has(key) || (nested?.hasCurrent ?? false);
|
|
112
|
+
if (owned.has(key) && !current) return [];
|
|
113
|
+
hasCurrent ||= current;
|
|
114
|
+
return [nested && message.role === "assistant" ? {
|
|
115
|
+
...message,
|
|
116
|
+
content: nested.content
|
|
117
|
+
} : message];
|
|
118
|
+
}),
|
|
119
|
+
hasCurrent
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function pruneContent(content, scope, present, owned) {
|
|
123
|
+
let hasCurrent = false;
|
|
124
|
+
return {
|
|
125
|
+
content: keyed(content).flatMap(([part, localKey]) => {
|
|
126
|
+
const key = identity(part, localKey, scope);
|
|
127
|
+
const nested = part.type === "tool-call" && part.messages ? pruneMessages(part.messages, ["tool", part.toolCallId], present, owned) : void 0;
|
|
128
|
+
const current = present.has(key) || (nested?.hasCurrent ?? false);
|
|
129
|
+
if (owned.has(key) && !current) return [];
|
|
130
|
+
hasCurrent ||= current;
|
|
131
|
+
return [nested ? {
|
|
132
|
+
...part,
|
|
133
|
+
messages: nested.messages
|
|
134
|
+
} : part];
|
|
135
|
+
}),
|
|
136
|
+
hasCurrent
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function createReplayContentMerger() {
|
|
140
|
+
const owned = /* @__PURE__ */ new Set();
|
|
141
|
+
return (previous, next) => {
|
|
142
|
+
const present = /* @__PURE__ */ new Set();
|
|
143
|
+
visitContent(next, [], (key) => present.add(key));
|
|
144
|
+
for (const key of present) owned.add(key);
|
|
145
|
+
return pruneContent(mergeReplayContent(previous, next), [], present, owned).content;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function nestedToolIds(content) {
|
|
149
|
+
const nestedIds = /* @__PURE__ */ new Set();
|
|
150
|
+
for (const part of content) {
|
|
151
|
+
if (part.type !== "tool-call") continue;
|
|
152
|
+
for (const message of part.messages ?? []) {
|
|
153
|
+
if (message.role !== "assistant") continue;
|
|
154
|
+
for (const child of iterateToolCallParts(message.content)) nestedIds.add(child.toolCallId);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return nestedIds;
|
|
158
|
+
}
|
|
159
|
+
function mergeReplayContent(previous, next) {
|
|
160
|
+
const nestedIds = nestedToolIds(previous);
|
|
161
|
+
const incomingNestedIds = nestedToolIds(next);
|
|
162
|
+
const movingRoots = new Map(previous.flatMap((part) => part.type === "tool-call" && incomingNestedIds.has(part.toolCallId) ? [[part.toolCallId, part]] : []));
|
|
163
|
+
const flattened = /* @__PURE__ */ new Map();
|
|
164
|
+
for (const part of next) if (part.type === "tool-call" && nestedIds.has(part.toolCallId)) flattened.set(part.toolCallId, part);
|
|
165
|
+
const prior = (flattened.size ? mapToolCallPartsDeep(previous, (part) => {
|
|
166
|
+
const fresh = flattened.get(part.toolCallId);
|
|
167
|
+
return fresh ? mergeTool(part, fresh) : part;
|
|
168
|
+
}).content : previous).filter((part) => part.type !== "tool-call" || !movingRoots.has(part.toolCallId));
|
|
169
|
+
let incoming = next.filter((part) => part.type !== "tool-call" || !flattened.has(part.toolCallId));
|
|
170
|
+
if (movingRoots.size) incoming = [...mapToolCallPartsDeep(incoming, (part) => {
|
|
171
|
+
const prior = movingRoots.get(part.toolCallId);
|
|
172
|
+
return prior ? mergeTool(prior, part) : part;
|
|
173
|
+
}).content];
|
|
174
|
+
return mergeOrdered(keyed(prior), keyed(incoming), (old, fresh) => {
|
|
175
|
+
if (old.type === "tool-call" && fresh.type === "tool-call") return mergeTool(old, fresh);
|
|
176
|
+
if ((old.type === "text" || old.type === "reasoning") && (fresh.type === "text" || fresh.type === "reasoning") && old.text.startsWith(fresh.text) && old.text.length > fresh.text.length) return {
|
|
177
|
+
...fresh,
|
|
178
|
+
text: old.text
|
|
179
|
+
};
|
|
180
|
+
return fresh;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
export { createReplayContentMerger, groupReplayToolContent, indexReplayToolOwners, preserveToolResult };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=replay-content.js.map
|