@assistant-ui/react-ag-ui 0.0.54 → 0.0.57
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/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts +25 -15
- package/dist/runtime/AgUiThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtime/AgUiThreadRuntimeCore.js +257 -210
- package/dist/runtime/AgUiThreadRuntimeCore.js.map +1 -1
- package/dist/runtime/adapter/conversions.d.ts +13 -3
- package/dist/runtime/adapter/conversions.d.ts.map +1 -1
- package/dist/runtime/adapter/conversions.js +77 -39
- package/dist/runtime/adapter/conversions.js.map +1 -1
- package/dist/runtime/adapter/run-aggregator.d.ts +23 -2
- package/dist/runtime/adapter/run-aggregator.d.ts.map +1 -1
- package/dist/runtime/adapter/run-aggregator.js +155 -41
- package/dist/runtime/adapter/run-aggregator.js.map +1 -1
- package/dist/runtime/adapter/subscriber.d.ts +3 -0
- package/dist/runtime/adapter/subscriber.d.ts.map +1 -1
- package/dist/runtime/adapter/subscriber.js +9 -0
- package/dist/runtime/adapter/subscriber.js.map +1 -1
- package/dist/runtime/adapter/tool-approval.d.ts +56 -0
- package/dist/runtime/adapter/tool-approval.d.ts.map +1 -0
- package/dist/runtime/adapter/tool-approval.js +244 -0
- package/dist/runtime/adapter/tool-approval.js.map +1 -0
- package/dist/runtime/event-parser.d.ts.map +1 -1
- package/dist/runtime/event-parser.js +2 -1
- package/dist/runtime/event-parser.js.map +1 -1
- package/dist/runtime/interrupt-internals.d.ts +8 -0
- package/dist/runtime/interrupt-internals.d.ts.map +1 -0
- package/dist/runtime/interrupt-internals.js +25 -0
- package/dist/runtime/interrupt-internals.js.map +1 -0
- package/dist/useAgUiRuntime.js +14 -9
- package/dist/useAgUiRuntime.js.map +1 -1
- package/package.json +9 -9
- package/src/index.ts +8 -2
- package/src/runtime/AgUiThreadRuntimeCore.test.ts +105 -0
- package/src/runtime/AgUiThreadRuntimeCore.ts +436 -272
- package/src/runtime/adapter/conversions.content.test.ts +61 -3
- package/src/runtime/adapter/conversions.ts +123 -57
- package/src/runtime/adapter/run-aggregator.approval.test.ts +103 -0
- package/src/runtime/adapter/run-aggregator.ts +234 -47
- package/src/runtime/adapter/subscriber.ts +14 -0
- package/src/runtime/adapter/tool-approval.test.ts +681 -0
- package/src/runtime/adapter/tool-approval.ts +366 -0
- package/src/runtime/event-parser.ts +10 -1
- package/src/runtime/interrupt-internals.ts +35 -0
- package/src/useAgUiRuntime.approval.test.tsx +885 -0
- package/src/useAgUiRuntime.history.test.tsx +76 -0
- package/src/useAgUiRuntime.ts +15 -9
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { parseMcpToolCallResult, readMcpAppResourceUri } from "../mcp-tool-result.js";
|
|
3
|
+
import { projectAgUiToolApprovals } from "./tool-approval.js";
|
|
3
4
|
import { AG_UI_METADATA_NAMESPACE } from "./run-aggregator.js";
|
|
4
|
-
import {
|
|
5
|
+
import { generateId } from "@assistant-ui/core";
|
|
6
|
+
import { getAutoStatus, parseDataUrl, resolveFilePartSource } from "@assistant-ui/core/internal";
|
|
5
7
|
import { applyA2uiOperations, convertSurfaceToUISpec } from "@assistant-ui/react-generative-ui/a2ui";
|
|
6
8
|
import { toToolsJSONSchema } from "assistant-stream";
|
|
7
9
|
//#region src/runtime/adapter/conversions.ts
|
|
@@ -47,9 +49,6 @@ function parseJSONText(value) {
|
|
|
47
49
|
return value;
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
|
-
function generateId() {
|
|
51
|
-
return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);
|
|
52
|
-
}
|
|
53
52
|
function normalizeToolCall(part) {
|
|
54
53
|
const id = part.toolCallId ?? generateId();
|
|
55
54
|
const argsText = typeof part.argsText === "string" ? part.argsText : JSON.stringify(part.args ?? {});
|
|
@@ -77,19 +76,23 @@ function mediaTypeForMime(mimeType) {
|
|
|
77
76
|
return "document";
|
|
78
77
|
}
|
|
79
78
|
function buildInputSource(value, declaredMimeType, sourceType) {
|
|
80
|
-
|
|
79
|
+
const source = resolveFilePartSource({
|
|
80
|
+
data: value,
|
|
81
|
+
mimeType: declaredMimeType ?? "application/octet-stream",
|
|
82
|
+
sourceType
|
|
83
|
+
});
|
|
84
|
+
if (source.kind === "url") return declaredMimeType !== void 0 ? {
|
|
81
85
|
type: "url",
|
|
82
|
-
value,
|
|
86
|
+
value: source.url,
|
|
83
87
|
mimeType: declaredMimeType
|
|
84
88
|
} : {
|
|
85
89
|
type: "url",
|
|
86
|
-
value
|
|
90
|
+
value: source.url
|
|
87
91
|
};
|
|
88
|
-
const parsed = parseDataUrl(value);
|
|
89
92
|
return {
|
|
90
93
|
type: "data",
|
|
91
|
-
value:
|
|
92
|
-
mimeType:
|
|
94
|
+
value: source.data,
|
|
95
|
+
mimeType: source.mimeType
|
|
93
96
|
};
|
|
94
97
|
}
|
|
95
98
|
function toInputContent(part, fallbackMimeType) {
|
|
@@ -375,13 +378,21 @@ function withOpaqueReasoning(message, opaqueReasoning) {
|
|
|
375
378
|
}
|
|
376
379
|
function toAssistantSnapshotMessage(rawMessage) {
|
|
377
380
|
const text = extractText(rawMessage.content);
|
|
378
|
-
const
|
|
381
|
+
const interrupts = readPersistedInterrupts(rawMessage.metadata);
|
|
382
|
+
const restoredToolCalls = extractAssistantToolCalls(rawMessage);
|
|
383
|
+
const approvals = projectAgUiToolApprovals(interrupts, new Set(restoredToolCalls.map((part) => part.toolCallId).filter((id) => !!id)));
|
|
384
|
+
const toolCallParts = restoredToolCalls.map((part) => {
|
|
385
|
+
const approval = part.toolCallId ? approvals.get(part.toolCallId) : void 0;
|
|
386
|
+
return approval ? {
|
|
387
|
+
...part,
|
|
388
|
+
approval
|
|
389
|
+
} : part;
|
|
390
|
+
});
|
|
379
391
|
const assistantContent = [...text.length > 0 ? [{
|
|
380
392
|
type: "text",
|
|
381
393
|
text
|
|
382
394
|
}] : [], ...toolCallParts];
|
|
383
395
|
const messageName = getString(rawMessage, "name");
|
|
384
|
-
const interrupts = readPersistedInterrupts(rawMessage.metadata);
|
|
385
396
|
return {
|
|
386
397
|
id: getString(rawMessage, "id") ?? generateId(),
|
|
387
398
|
role: "assistant",
|
|
@@ -395,10 +406,11 @@ function toUserOrSystemSnapshotMessage(role, rawMessage) {
|
|
|
395
406
|
const attachments = role === "user" ? toSnapshotAttachments(rawMessage.content) : [];
|
|
396
407
|
return {
|
|
397
408
|
id: getString(rawMessage, "id") ?? generateId(),
|
|
398
|
-
role,
|
|
409
|
+
role: role === "developer" ? "system" : role,
|
|
399
410
|
content: extractText(rawMessage.content),
|
|
400
411
|
...messageName !== void 0 ? { name: messageName } : {},
|
|
401
|
-
...attachments.length > 0 ? { attachments } : {}
|
|
412
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
413
|
+
...role === "developer" ? { metadata: { custom: { [AG_UI_METADATA_NAMESPACE]: { role: "developer" } } } } : {}
|
|
402
414
|
};
|
|
403
415
|
}
|
|
404
416
|
function attachA2uiSurfaces(message, state) {
|
|
@@ -554,7 +566,7 @@ function fromAgUiMessages(messages, options) {
|
|
|
554
566
|
});
|
|
555
567
|
continue;
|
|
556
568
|
}
|
|
557
|
-
if (role === "user" || role === "system") converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));
|
|
569
|
+
if (role === "user" || role === "system" || role === "developer") converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));
|
|
558
570
|
}
|
|
559
571
|
for (const { anchor, ...entry } of opaqueReasoning) {
|
|
560
572
|
const trailing = anchor >= converted.length;
|
|
@@ -601,42 +613,43 @@ function convertAssistantMessage(message, converted) {
|
|
|
601
613
|
reasoningIndex++;
|
|
602
614
|
}
|
|
603
615
|
if (shellIsDropped) return;
|
|
604
|
-
|
|
616
|
+
converted.push({
|
|
605
617
|
id: message.id,
|
|
606
618
|
role: "assistant",
|
|
607
|
-
content
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
converted.push(assistantMessage);
|
|
619
|
+
content,
|
|
620
|
+
...message.name ? { name: message.name } : {},
|
|
621
|
+
...toolCalls.length > 0 ? { toolCalls: toolCalls.map((entry) => entry.call) } : {}
|
|
622
|
+
});
|
|
612
623
|
for (const { id: toolCallId, part } of toolCalls) {
|
|
613
624
|
if (part.result === void 0) continue;
|
|
614
625
|
const resultContent = part.modelContent !== void 0 ? extractText(part.modelContent) : typeof part.result === "string" ? part.result : JSON.stringify(part.result);
|
|
615
|
-
|
|
626
|
+
converted.push({
|
|
616
627
|
id: part.unstable_toolMessageId ?? `${toolCallId}:tool`,
|
|
617
628
|
role: "tool",
|
|
618
629
|
content: resultContent,
|
|
619
|
-
toolCallId
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
converted.push(toolMessage);
|
|
630
|
+
toolCallId,
|
|
631
|
+
...part.isError ? { error: resultContent } : {}
|
|
632
|
+
});
|
|
623
633
|
}
|
|
624
634
|
}
|
|
625
635
|
function convertToolMessage(message, converted) {
|
|
626
636
|
const content = extractText(message.content);
|
|
627
637
|
const toolCallId = message.toolCallId ?? generateId();
|
|
628
|
-
|
|
638
|
+
converted.push({
|
|
629
639
|
id: message.id,
|
|
630
640
|
role: "tool",
|
|
631
641
|
content,
|
|
632
|
-
toolCallId
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
converted.push(toolMessage);
|
|
642
|
+
toolCallId,
|
|
643
|
+
...typeof message.error === "string" ? { error: message.error } : {}
|
|
644
|
+
});
|
|
636
645
|
}
|
|
637
646
|
function toAgUiMessages(messages) {
|
|
638
647
|
const converted = [];
|
|
639
|
-
for (const
|
|
648
|
+
for (const rawMessage of messages) {
|
|
649
|
+
const message = {
|
|
650
|
+
...rawMessage,
|
|
651
|
+
id: rawMessage.id ?? generateId()
|
|
652
|
+
};
|
|
640
653
|
const opaqueReasoning = readOpaqueReasoning(message.metadata);
|
|
641
654
|
const toOpaqueRecord = (entry) => ({
|
|
642
655
|
id: entry.id,
|
|
@@ -658,13 +671,38 @@ function toAgUiMessages(messages) {
|
|
|
658
671
|
flushTrailingOpaqueReasoning();
|
|
659
672
|
continue;
|
|
660
673
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
674
|
+
if (message.role === "user") {
|
|
675
|
+
converted.push({
|
|
676
|
+
id: message.id,
|
|
677
|
+
role: "user",
|
|
678
|
+
content: buildUserContent(message),
|
|
679
|
+
...message.name ? { name: message.name } : {}
|
|
680
|
+
});
|
|
681
|
+
flushTrailingOpaqueReasoning();
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
if (message.role === "system" || message.role === "developer") {
|
|
685
|
+
const custom = isObject(message.metadata) ? message.metadata.custom : void 0;
|
|
686
|
+
const namespaced = isObject(custom) ? custom[AG_UI_METADATA_NAMESPACE] : void 0;
|
|
687
|
+
const wireRole = message.role === "system" && isObject(namespaced) && namespaced.role === "developer" ? "developer" : message.role;
|
|
688
|
+
converted.push({
|
|
689
|
+
id: message.id,
|
|
690
|
+
role: wireRole,
|
|
691
|
+
content: extractText(message.content),
|
|
692
|
+
...message.name ? { name: message.name } : {}
|
|
693
|
+
});
|
|
694
|
+
flushTrailingOpaqueReasoning();
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
if (message.role === "reasoning") {
|
|
698
|
+
converted.push({
|
|
699
|
+
id: message.id,
|
|
700
|
+
role: "reasoning",
|
|
701
|
+
content: extractText(message.content)
|
|
702
|
+
});
|
|
703
|
+
flushTrailingOpaqueReasoning();
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
668
706
|
flushTrailingOpaqueReasoning();
|
|
669
707
|
}
|
|
670
708
|
return converted;
|
|
@@ -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 type {\n ThreadMessageLike as CoreThreadMessageLike,\n PartProviderMetadata,\n ToolCallMessagePartMcpMetadata,\n ToolModelContentPart,\n} from \"@assistant-ui/core\";\nimport {\n getAutoStatus,\n httpUrlPattern,\n parseDataUrl,\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 type AgUiCustomMetadata,\n type AgUiOpaqueReasoning,\n} from \"./run-aggregator\";\nimport {\n applyA2uiOperations,\n convertSurfaceToUISpec,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/react-generative-ui/a2ui\";\nimport type { AgUiInterrupt } from \"../types\";\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;\n role: string;\n content: unknown;\n metadata?: unknown;\n name?: string;\n toolCallId?: string;\n error?: string;\n attachments?: readonly AttachmentLike[];\n};\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: string;\n content: string | InputContent[];\n name?: string;\n toolCalls?: AgUiToolCall[];\n }\n | {\n id: string;\n role: \"reasoning\";\n content: string;\n encryptedValue?: string;\n }\n | {\n id: string;\n role: \"tool\";\n content: string;\n toolCallId: string;\n error?: string;\n };\n\ntype ToolCallPart = {\n type: \"tool-call\";\n toolCallId?: string;\n toolName: string;\n argsText?: string;\n args?: ReadonlyJSONObject;\n result?: unknown;\n isError?: boolean;\n modelContent?: readonly ToolModelContentPart[];\n unstable_toolMessageId?: string;\n mcp?: ToolCallMessagePartMcpMetadata;\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\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 };\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 generateId(): string {\n return (\n (globalThis.crypto as { randomUUID?: () => string })?.randomUUID?.() ??\n Math.random().toString(36).slice(2)\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\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.\nfunction buildInputSource(\n value: string,\n declaredMimeType: string | undefined,\n sourceType?: string,\n): InputContentSource {\n if (sourceType === \"url\" || httpUrlPattern.test(value)) {\n return declaredMimeType !== undefined\n ? { type: \"url\", value, mimeType: declaredMimeType }\n : { type: \"url\", value };\n }\n const parsed = parseDataUrl(value);\n return {\n type: \"data\",\n value: parsed?.data ?? value,\n mimeType:\n parsed?.mimeType ?? declaredMimeType ?? \"application/octet-stream\",\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 return {\n type: \"image\",\n source: buildInputSource(image, fallbackMimeType),\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\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 return [\n { id, encryptedValue, ...(entry.after === true ? { after: true } : {}) },\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 toolCallParts = extractAssistantToolCalls(rawMessage);\n const assistantContent = [\n ...(text.length > 0 ? [{ type: \"text\" as const, text }] : []),\n ...toolCallParts,\n ];\n const messageName = getString(rawMessage, \"name\");\n const interrupts = readPersistedInterrupts(rawMessage.metadata);\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: assistantContent.length > 0 ? assistantContent : \"\",\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(interrupts\n ? {\n metadata: {\n custom: {\n [AG_UI_METADATA_NAMESPACE]: {\n interrupts,\n } satisfies AgUiCustomMetadata,\n },\n },\n }\n : {}),\n };\n}\n\nfunction toUserOrSystemSnapshotMessage(\n role: \"user\" | \"system\",\n rawMessage: Record<string, unknown>,\n): CoreThreadMessageLike {\n const messageName = getString(rawMessage, \"name\");\n const attachments =\n role === \"user\" ? toSnapshotAttachments(rawMessage.content) : [];\n return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n role,\n content: extractText(rawMessage.content),\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(attachments.length > 0 ? { attachments } : {}),\n };\n}\n\n// Rebuilds the a2ui:<surfaceId> \"present\" tool-call parts for one owning\n// assistant message from a bucket of rebuilt surface state, mirroring the\n// live RunAggregator.synthesizeA2uiToolCalls shape. Non-a2ui parts (text,\n// other tool calls) are preserved; existing a2ui parts are replaced wholesale\n// so create/update/delete within the bucket all converge on the rebuilt set.\nfunction attachA2uiSurfaces(\n message: CoreThreadMessageLike,\n state: A2uiState,\n): CoreThreadMessageLike {\n const a2uiParts: ToolCallPart[] = [];\n for (const [surfaceId, surface] of state) {\n const { spec } = convertSurfaceToUISpec(surface);\n if (!spec) continue;\n a2uiParts.push({\n type: \"tool-call\",\n toolCallId: `a2ui:${surfaceId}`,\n toolName: \"present\",\n args: spec as unknown as ReadonlyJSONObject,\n argsText: JSON.stringify(spec),\n result: {},\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\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 // 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\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 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\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 };\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 },\n ],\n });\n continue;\n }\n\n if (role === \"activity\") {\n // Only a2ui-surface activity messages have an assistant-part equivalent\n // to rehydrate; other activity types still have no surface to repaint.\n const activityType = getString(rawMessage, \"activityType\");\n if (activityType !== A2UI_SURFACE_ACTIVITY_TYPE) continue;\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\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 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(toAssistantSnapshotMessage(rawMessage));\n continue;\n }\n\n if (role === \"reasoning\") {\n const text = extractText(rawMessage.content);\n const encryptedValue = getString(rawMessage, \"encryptedValue\");\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 opaqueReasoning.push({\n id: opaqueId,\n encryptedValue,\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 anchor: converted.length,\n });\n }\n continue;\n }\n converted.push({\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: [\n {\n type: \"reasoning\",\n text,\n ...(encryptedValue !== undefined\n ? {\n providerMetadata: {\n [AG_UI_METADATA_NAMESPACE]: { encryptedValue },\n },\n }\n : {}),\n },\n ],\n });\n continue;\n }\n\n if (role === \"user\" || role === \"system\") {\n converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));\n }\n }\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 for (let i = 0; i < converted.length; i++) {\n const message = converted[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 converted[i] = {\n ...message,\n status: getAutoStatus(\n false,\n false,\n hasInterrupt,\n hasPendingToolCall,\n undefined,\n ),\n };\n }\n }\n\n return converted;\n}\n\nfunction convertAssistantMessage(\n message: ThreadMessageLike,\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 } = readAgUiReasoningMeta(\n part.providerMetadata,\n );\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 });\n reasoningIndex++;\n }\n\n // Drop assistant messages with no text or tool calls (e.g. an imported\n // reasoning-only entry) so they are not re-sent as a blank assistant turn.\n if (shellIsDropped) {\n return;\n }\n\n const assistantMessage: AgUiMessage = {\n id: message.id,\n role: \"assistant\",\n content,\n };\n if (message.name) {\n assistantMessage.name = message.name;\n }\n if (toolCalls.length > 0) {\n assistantMessage.toolCalls = toolCalls.map((entry) => entry.call);\n }\n converted.push(assistantMessage);\n\n for (const { id: toolCallId, part } of toolCalls) {\n if (part.result === undefined) continue;\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\n const toolMessage: AgUiMessage = {\n id: part.unstable_toolMessageId ?? `${toolCallId}:tool`,\n role: \"tool\",\n content: resultContent,\n toolCallId,\n };\n if (part.isError) {\n toolMessage.error = resultContent;\n }\n converted.push(toolMessage);\n }\n}\n\nfunction convertToolMessage(\n message: ThreadMessageLike,\n converted: AgUiMessage[],\n): void {\n const content = extractText(message.content);\n const toolCallId = message.toolCallId ?? generateId();\n\n const toolMessage: AgUiMessage = {\n id: message.id,\n role: \"tool\",\n content,\n toolCallId,\n };\n if (typeof message.error === \"string\") {\n toolMessage.error = message.error;\n }\n converted.push(toolMessage);\n}\n\nexport function toAgUiMessages(\n messages: readonly ThreadMessageLike[],\n): AgUiMessage[] {\n const converted: AgUiMessage[] = [];\n\n for (const message of messages) {\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 });\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 const genericMessage: AgUiMessage = {\n id: message.id,\n role: message.role,\n content:\n message.role === \"user\"\n ? buildUserContent(message)\n : extractText(message.content),\n };\n if (message.name) {\n genericMessage.name = message.name;\n }\n converted.push(genericMessage);\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":";;;;;;;AA8FA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU;AAEzC,MAAM,aAAa,QAAiC,QAAgB;CAClE,MAAM,QAAQ,OAAO;CACrB,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;AAEA,MAAM,iBAAiB,WACrB,UAAU,QAAQ,YAAY,KAAK,UAAU,QAAQ,cAAc;AAErE,MAAM,qBAAqB,qBAA8B;CACvD,IAAI,CAAC,SAAS,gBAAgB,GAAG,OAAO,KAAA;CACxC,MAAM,aAAa,iBAAiB;CACpC,OAAO,SAAS,UAAU,IAAI,aAAa,KAAA;AAC7C;AAEA,MAAM,yBAAyB,qBAA8B;CAC3D,MAAM,aAAa,kBAAkB,gBAAgB;CACrD,IAAI,CAAC,YAAY,OAAO,CAAC;CACzB,OAAO;EACL,gBAAgB,UAAU,YAAY,gBAAgB;EACtD,aAAa,UAAU,YAAY,aAAa;CAClD;AACF;AAKA,MAAM,sBACJ,MACA,aACG;CACH,MAAM,WAAW;EACf,GAAG,kBAAkB,KAAK,gBAAgB;EAC1C,GAAI,aAAa,KAAA,KAAa,EAAE,SAAS;CAC3C;CACA,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,SAAS,IAAI,WAAW,KAAA;AACvD;AAKA,MAAM,qBACJ,aAIG;CACH,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO,CAAC;CACjC,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;CACzC,OAAO;EACL,UAAU,UAAU,UAAU,UAAU;EACxC,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,EAClC,kBAAkB,GAAA,SACY,KAC9B,EACF;CACF;AACF;AAEA,SAAS,cAAc,OAAwB;CAC7C,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,aAAqB;CAC5B,OACG,WAAW,QAA0C,aAAa,KACnE,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;AAEtC;AAEA,SAAS,kBAAkB,MAGzB;CACA,MAAM,KAAK,KAAK,cAAc,WAAW;CACzC,MAAM,WACJ,OAAO,KAAK,aAAa,WACrB,KAAK,WACL,KAAK,UAAU,KAAK,QAAQ,CAAC,CAAC;CAEpC,OAAO;EACL;EACA,MAAM;GACJ;GACA,MAAM;GACN,UAAU;IACR,MAAM,KAAK,YAAY;IACvB,WAAW;GACb;EACF;CACF;AACF;AAEA,SAAS,YAAY,SAA0B;CAC7C,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO;CAEpC,OAAO,QACJ,QACE,SACC,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,QACnD,CAAC,CACA,KAAK,SAAS,KAAK,IAAI,CAAC,CACxB,KAAK,IAAI;AACd;AAQA,SAAS,iBAAiB,UAA8C;CACtE,IAAI,UAAU,WAAW,QAAQ,GAAG,OAAO;CAC3C,IAAI,UAAU,WAAW,QAAQ,GAAG,OAAO;CAC3C,IAAI,UAAU,WAAW,QAAQ,GAAG,OAAO;CAC3C,OAAO;AACT;AAMA,SAAS,iBACP,OACA,kBACA,YACoB;CACpB,IAAI,eAAe,SAAS,eAAe,KAAK,KAAK,GACnD,OAAO,qBAAqB,KAAA,IACxB;EAAE,MAAM;EAAO;EAAO,UAAU;CAAiB,IACjD;EAAE,MAAM;EAAO;CAAM;CAE3B,MAAM,SAAS,aAAa,KAAK;CACjC,OAAO;EACL,MAAM;EACN,OAAO,QAAQ,QAAQ;EACvB,UACE,QAAQ,YAAY,oBAAoB;CAC5C;AACF;AAEA,SAAS,eACP,MACA,kBACqB;CACrB,IAAI,CAAC,SAAS,IAAI,GAAG,OAAO;CAC5B,MAAM,OAAO,UAAU,MAAM,MAAM;CAEnC,IAAI,SAAS,QAAQ;EACnB,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,OAAO;GAAE,MAAM;GAAQ;EAAK;CAC9B;CAEA,IAAI,SAAS,SAAS;EACpB,MAAM,QAAQ,UAAU,MAAM,OAAO;EACrC,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,MAAM,WAAW,mBAAmB,MAAM,UAAU,MAAM,UAAU,CAAC;EACrE,OAAO;GACL,MAAM;GACN,QAAQ,iBAAiB,OAAO,gBAAgB;GAChD,GAAI,YAAY,EAAE,SAAS;EAC7B;CACF;CAEA,IAAI,SAAS,QAAQ;EACnB,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,MAAM,mBAAmB,UAAU,MAAM,UAAU,KAAK;EACxD,MAAM,WAAW,UAAU,MAAM,UAAU;EAC3C,MAAM,SAAS,iBACb,MACA,kBACA,UAAU,MAAM,YAAY,CAC9B;EACA,MAAM,WAAW,mBAAmB,MAAM,QAAQ;EAClD,QAAQ,iBAAiB,OAAO,QAAQ,GAAxC;GACE,KAAK,SACH,OAAO;IAAE,MAAM;IAAS;IAAQ,GAAI,YAAY,EAAE,SAAS;GAAG;GAChE,KAAK,SACH,OAAO;IAAE,MAAM;IAAS;IAAQ,GAAI,YAAY,EAAE,SAAS;GAAG;GAChE,KAAK,SACH,OAAO;IAAE,MAAM;IAAS;IAAQ,GAAI,YAAY,EAAE,SAAS;GAAG;GAChE,SACE,OAAO;IAAE,MAAM;IAAY;IAAQ,GAAI,YAAY,EAAE,SAAS;GAAG;EACrE;CACF;CAEA,IAAI,SAAS,SAAS;EACpB,MAAM,QAAQ,KAAK;EACnB,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,OAAO,UAAU,OAAO,MAAM;EACpC,MAAM,SAAS,UAAU,OAAO,QAAQ;EACxC,IAAI,SAAS,KAAA,KAAa,WAAW,KAAA,GAAW,OAAO;EACvD,OAAO;GACL,MAAM;GACN,QAAQ,iBACN,aAAa,IAAI,CAAC,EAAE,QAAQ,MAC5B,SAAS,QACX;EACF;CACF;CAEA,OAAO;AACT;AAMA,MAAM,kCAAkB,IAAI,IAAI;CAAC;CAAS;CAAS;CAAS;AAAU,CAAC;AAGvE,SAAS,oBACP,OAC8D;CAC9D,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,MAAM,cAAc,UAAU,OAAO,OAAO;CAC5C,IAAI,gBAAgB,KAAA,GAAW,OAAO;CACtC,MAAM,WAAW,UAAU,OAAO,UAAU;CAC5C,MAAM,OAAO,UAAU,OAAO,MAAM;CACpC,IAAI,SAAS,OACX,OAAO;EACL,OAAO;EACP,OAAO;EACP,GAAI,aAAa,KAAA,KAAa,EAAE,SAAS;CAC3C;CAEF,IAAI,SAAS,QAAQ;EACnB,MAAM,mBAAmB,YAAY;EACrC,OAAO;GACL,OAAO,QAAQ,iBAAiB,UAAU;GAC1C,UAAU;EACZ;CACF;CACA,OAAO;AACT;AAGA,SAAS,uBACP,MACgC;CAChC,MAAM,WAAW,UAAU,MAAM,UAAU;CAC3C,IAAI,aAAa,KAAA,GAAW,OAAO;CACnC,MAAM,OAAO,UAAU,MAAM,MAAM;CACnC,MAAM,MAAM,UAAU,MAAM,KAAK;CACjC,MAAM,SAAS,OACX;EAAE,MAAM;EAAQ,OAAO;EAAM;CAAS,IACtC,MACE;EAAE,MAAM;EAAO,OAAO;EAAK;CAAS,IACpC;CACN,IAAI,CAAC,QAAQ,OAAO;CACpB,MAAM,WAAW,UAAU,MAAM,UAAU;CAC3C,OAAO;EACL,MAAM,iBAAiB,QAAQ;EAC/B;EACA,GAAI,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE;CAC3C;AACF;AAEA,SAAS,sBAAsB,SAAwC;CACrE,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO,CAAC;CAErC,MAAM,cAAoC,CAAC;CAC3C,KAAK,MAAM,WAAW,SAAS;EAC7B,IAAI,CAAC,SAAS,OAAO,GAAG;EACxB,MAAM,OACJ,UAAU,SAAS,MAAM,MAAM,WAC3B,uBAAuB,OAAO,IAC9B;EACN,IAAI,CAAC,MAAM;EACX,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,IAAI,SAAS,KAAA,KAAa,CAAC,gBAAgB,IAAI,IAAI,GAAG;EACtD,MAAM,SAAS,oBAAoB,KAAK,MAAM;EAC9C,IAAI,CAAC,QAAQ;EAEb,MAAM,EAAE,UAAU,qBAAqB,kBAAkB,KAAK,QAAQ;EACtE,MAAM,KAAK,YAAY,OAAO,SAAS;EAEvC,IAAI,SAAS,SAAS;GACpB,YAAY,KAAK;IACf;IACA,MAAM;IACN,MAAM,YAAY;IAClB,GAAI,OAAO,aAAa,KAAA,KAAa,EAAE,aAAa,OAAO,SAAS;IACpE,QAAQ,EAAE,MAAM,WAAW;IAC3B,SAAS,CACP;KACE,MAAM;KACN,OAAO,OAAO;KACd,GAAI,aAAa,KAAA,KAAa,EAAE,SAAS;KACzC,GAAI,oBAAoB,EAAE,iBAAiB;IAC7C,CACF;GACF,CAAC;GACD;EACF;EAEA,MAAM,WAAW,OAAO,YAAY;EACpC,YAAY,KAAK;GACf;GACA,MAAM,SAAS,aAAa,aAAa;GACzC,MAAM,YAAY;GAClB,aAAa;GACb,QAAQ,EAAE,MAAM,WAAW;GAC3B,SAAS,CACP;IACE,MAAM;IACN,MAAM,OAAO;IACb;IACA,GAAI,OAAO,SAAS,EAAE,YAAY,MAAe;IACjD,GAAI,aAAa,KAAA,KAAa,EAAE,SAAS;IACzC,GAAI,oBAAoB,EAAE,iBAAiB;GAC7C,CACF;EACF,CAAC;CACH;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,SAAqD;CAC7E,MAAM,eAAe,MAAM,QAAQ,QAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC;CAEzE,MAAM,cAAc,QAAQ,eAAe,CAAC;CAE5C,MAAM,YAA4B,CAAC;CAInC,IAAI,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,SAAS,GAClE,UAAU,KAAK;EAAE,MAAM;EAAQ,MAAM,QAAQ;CAAQ,CAAC;CAGxD,KAAK,MAAM,QAAQ,cAAc;EAC/B,MAAM,QAAQ,eAAe,MAAM,KAAA,CAAS;EAC5C,IAAI,OAAO,UAAU,KAAK,KAAK;CACjC;CACA,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,CAAC,SAAS,UAAU,GAAG;EAC3B,MAAM,oBAAoB,WAAW;EACrC,IAAI,CAAC,MAAM,QAAQ,iBAAiB,GAAG;EACvC,MAAM,eAAe,UAAU,YAAY,aAAa;EACxD,KAAK,MAAM,QAAQ,mBAAmB;GACpC,MAAM,QAAQ,eAAe,MAAM,YAAY;GAC/C,IAAI,OAAO,UAAU,KAAK,KAAK;EACjC;CACF;CAGA,IADmB,UAAU,MAAM,SAAS,KAAK,SAAS,MAC7C,GAAG,OAAO;CAIvB,IAAI,UAAU,WAAW,GAAG,OAAO,YAAY,QAAQ,OAAO;CAC9D,OAAO,UACJ,QACE,SAAiD,KAAK,SAAS,MAClE,CAAC,CACA,KAAK,SAAS,KAAK,IAAI,CAAC,CACxB,KAAK,IAAI;AACd;AAEA,SAAS,eAAe,OAAqC;CAC3D,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,MAAM,cAAc,SAAS,MAAM,QAAQ,IAAI,MAAM,WAAW;CAChE,MAAM,aAAa,UAAU,OAAO,YAAY,KAAK,UAAU,OAAO,IAAI;CAC1E,MAAM,WACJ,UAAU,OAAO,UAAU,KAC3B,UAAU,OAAO,MAAM,MACtB,cAAc,UAAU,aAAa,MAAM,IAAI,KAAA,MAChD;CACF,MAAM,WACJ,UAAU,OAAO,UAAU,KAC3B,UAAU,OAAO,WAAW,MAC3B,cAAc,UAAU,aAAa,WAAW,IAAI,KAAA;CAEvD,MAAM,aACJ,OAAO,aAAa,WAAW,cAAc,QAAQ,IAAI,KAAA;CAC3D,MAAM,OACJ,SAAS,UAAU,KAAK,CAAC,MAAM,QAAQ,UAAU,IAC5C,aACD,SAAS,MAAM,IAAI,KAAK,CAAC,MAAM,QAAQ,MAAM,IAAI,IAC9C,MAAM,OACP,KAAA;CAER,MAAM,OAAqB;EACzB,MAAM;EACN,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;EACjD;EACA,UAAU,YAAY,KAAK,UAAU,QAAQ,CAAC,CAAC;EAC/C,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;CACvC;CAEA,IAAI,MAAM,SAAS,aAAa;EAC9B,MAAM,SAAS,MAAM;EACrB,MAAM,UAAU,MAAM;EACtB,IAAI,WAAW,KAAA,GAAW,KAAK,SAAS;EACxC,IAAI,OAAO,YAAY,WAAW,KAAK,UAAU;CACnD;CAEA,OAAO;AACT;AAEA,SAAS,0BACP,SACgB;CAChB,MAAM,QAAwB,CAAC;CAC/B,MAAM,kCAAkB,IAAI,IAAY;CACxC,MAAM,YAAY,SAA8B;EAC9C,IAAI,CAAC,MAAM;EACX,MAAM,KAAK,KAAK,cAAc,WAAW;EACzC,IAAI,gBAAgB,IAAI,EAAE,GAAG;EAC7B,gBAAgB,IAAI,EAAE;EACtB,MAAM,KAAK;GACT,GAAG;GACH,YAAY;EACd,CAAC;CACH;CAEA,MAAM,UAAU,QAAQ;CACxB,IAAI,MAAM,QAAQ,OAAO,GAClB;OAAA,MAAM,QAAQ,SACjB,IAAI,SAAS,IAAI,KAAK,KAAK,SAAS,aAClC,SAAS,eAAe,IAAI,CAAC;CAAA;CAKnC,MAAM,YAAY,MAAM,QAAQ,QAAQ,SAAS,IAC7C,QAAQ,YACR,MAAM,QAAQ,QAAQ,UAAU,IAC9B,QAAQ,aACR,CAAC;CACP,KAAK,MAAM,QAAQ,WACjB,SAAS,eAAe,IAAI,CAAC;CAG/B,OAAO;AACT;AAEA,SAAS,mBAAmB,OAA6C;CACvE,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;CAClC,MAAM,QAAQ,MAAM,QACjB,UACC,SAAS,KAAK,KACd,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,WAAW,QAC5B;CACA,OAAO,MAAM,SAAS,IAAI,QAAQ,KAAA;AACpC;AAEA,SAAS,wBACP,UAC6B;CAC7B,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO,KAAA;CAChC,MAAM,SAAS,SAAS;CACxB,IAAI,CAAC,SAAS,MAAM,GAAG,OAAO,KAAA;CAC9B,MAAM,aAAa,OAAO;CAC1B,IAAI,CAAC,SAAS,UAAU,GAAG,OAAO,KAAA;CAClC,OAAO,mBAAmB,WAAW,UAAU;AACjD;AAEA,SAAS,oBAAoB,UAA0C;CACrE,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO,CAAC;CACjC,MAAM,SAAS,SAAS;CACxB,IAAI,CAAC,SAAS,MAAM,GAAG,OAAO,CAAC;CAC/B,MAAM,aAAa,OAAO;CAC1B,IAAI,CAAC,SAAS,UAAU,GAAG,OAAO,CAAC;CACnC,MAAM,UAAU,WAAW;CAC3B,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG,OAAO,CAAC;CACrC,OAAO,QAAQ,SAAS,UAAU;EAChC,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,CAAC;EAC9B,MAAM,KAAK,UAAU,OAAO,IAAI;EAChC,MAAM,iBAAiB,UAAU,OAAO,gBAAgB;EACxD,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,gBAAgB,KAAK,GAAG,OAAO,CAAC;EACpD,OAAO,CACL;GAAE;GAAI;GAAgB,GAAI,MAAM,UAAU,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;EAAG,CACzE;CACF,CAAC;AACH;AAEA,SAAS,oBACP,SACA,iBACuB;CACvB,MAAM,WAAW,SAAS,QAAQ,QAAQ,IAAI,QAAQ,WAAW,CAAC;CAClE,MAAM,SAAS,SAAS,SAAS,MAAM,IAAI,SAAS,SAAS,CAAC;CAC9D,MAAM,aAAa,SAAS,OAAA,OAAgC,IACvD,OAAO,4BACR,CAAC;CACL,OAAO;EACL,GAAG;EACH,UAAU;GACR,GAAG;GACH,QAAQ;IACN,GAAG;KACF,2BAA2B;KAAE,GAAG;KAAY;IAAgB;GAC/D;EACF;CACF;AACF;AAEA,SAAS,2BACP,YACuB;CACvB,MAAM,OAAO,YAAY,WAAW,OAAO;CAC3C,MAAM,gBAAgB,0BAA0B,UAAU;CAC1D,MAAM,mBAAmB,CACvB,GAAI,KAAK,SAAS,IAAI,CAAC;EAAE,MAAM;EAAiB;CAAK,CAAC,IAAI,CAAC,GAC3D,GAAG,aACL;CACA,MAAM,cAAc,UAAU,YAAY,MAAM;CAChD,MAAM,aAAa,wBAAwB,WAAW,QAAQ;CAC9D,OAAO;EACL,IAAI,UAAU,YAAY,IAAI,KAAK,WAAW;EAC9C,MAAM;EACN,SAAS,iBAAiB,SAAS,IAAI,mBAAmB;EAC1D,GAAI,gBAAgB,KAAA,IAAY,EAAE,MAAM,YAAY,IAAI,CAAC;EACzD,GAAI,aACA,EACE,UAAU,EACR,QAAQ,GACL,2BAA2B,EAC1B,WACF,EACF,EACF,EACF,IACA,CAAC;CACP;AACF;AAEA,SAAS,8BACP,MACA,YACuB;CACvB,MAAM,cAAc,UAAU,YAAY,MAAM;CAChD,MAAM,cACJ,SAAS,SAAS,sBAAsB,WAAW,OAAO,IAAI,CAAC;CACjE,OAAO;EACL,IAAI,UAAU,YAAY,IAAI,KAAK,WAAW;EAC9C;EACA,SAAS,YAAY,WAAW,OAAO;EACvC,GAAI,gBAAgB,KAAA,IAAY,EAAE,MAAM,YAAY,IAAI,CAAC;EACzD,GAAI,YAAY,SAAS,IAAI,EAAE,YAAY,IAAI,CAAC;CAClD;AACF;AAOA,SAAS,mBACP,SACA,OACuB;CACvB,MAAM,YAA4B,CAAC;CACnC,KAAK,MAAM,CAAC,WAAW,YAAY,OAAO;EACxC,MAAM,EAAE,SAAS,uBAAuB,OAAO;EAC/C,IAAI,CAAC,MAAM;EACX,UAAU,KAAK;GACb,MAAM;GACN,YAAY,QAAQ;GACpB,UAAU;GACV,MAAM;GACN,UAAU,KAAK,UAAU,IAAI;GAC7B,QAAQ,CAAC;EACX,CAAC;CACH;CAGA,MAAM,aADU,MAAM,QAAQ,QAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC,EAAA,CAC1C,QACvB,SACC,EACE,SAAS,IAAI,KACb,KAAK,SAAS,eACd,OAAO,KAAK,eAAe,YAC3B,KAAK,WAAW,WAAW,OAAO,EAExC;CACA,OAAO;EAAE,GAAG;EAAS,SAAS,CAAC,GAAG,WAAW,GAAG,SAAS;CAAE;AAC7D;AAUA,SAAgB,iBACd,UACA,SACyB;CACzB,MAAM,eAAe,SAAS,gBAAgB;CAC9C,MAAM,YAAqC,CAAC;CAC5C,MAAM,8BAAc,IAAI,IAAuB;CAC/C,MAAM,yCAAyB,IAAI,IAAoB;CAKvD,MAAM,kBAAgE,CAAC;CAEvE,KAAK,MAAM,cAAc,UAAU;EACjC,IAAI,CAAC,SAAS,UAAU,GAAG;EAC3B,MAAM,OAAO,UAAU,YAAY,MAAM;EACzC,IAAI,CAAC,MAAM;EAEX,IAAI,SAAS,QAAQ;GACnB,MAAM,aAAa,cAAc,UAAU,KAAK,QAAQ,WAAW;GACnE,MAAM,gBAAgB,UAAU,YAAY,IAAI;GAChD,MAAM,eAAe,YAAY,WAAW,OAAO;GACnD,MAAM,YAAY,uBAAuB,YAAY,YAAY;GACjE,MAAM,kBAAkB,YACpB,CAAC;IAAE,MAAM;IAAiB,MAAM;GAAa,CAAC,IAC9C,KAAA;GACJ,MAAM,SACJ,cACC,WAAW,WAAW,KAAA,IACnB,WAAW,SACX,OAAO,WAAW,YAAY,WAC5B,cAAc,WAAW,OAAO,IAChC,WAAW;GACnB,MAAM,UACJ,OAAO,WAAW,UAAU,YAC5B,WAAW,YAAY,QACvB,WAAW,WAAW,UAClB,OACA,WAAW,YAAY,QACrB,QACA,KAAA;GACR,MAAM,YAAY,sBAAsB,WAAW,KAAK;GACxD,MAAM,SACJ,cAAc,KAAA,IAAY,EAAE,aAAa,UAAU,IAAI,KAAA;GAEzD,IAAI,UAAU;GACd,KACE,IAAI,eAAe,UAAU,SAAS,GACtC,gBAAgB,KAAK,CAAC,SACtB,gBACA;IACA,MAAM,UAAU,UAAU;IAC1B,IACE,CAAC,WACD,QAAQ,SAAS,eACjB,CAAC,MAAM,QAAQ,QAAQ,OAAO,GAE9B;IAEF,KACE,IAAI,YAAY,QAAQ,QAAQ,SAAS,GACzC,aAAa,GACb,aACA;KACA,MAAM,OAAO,QAAQ,QAAQ;KAC7B,IAAI,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS,aAAa;KAClD,IAAI,UAAU,MAAM,YAAY,MAAM,YAAY;KAElD,MAAM,cAA4B;MAChC,GAAI;MACJ;MACA,GAAI,kBAAkB,EAAE,cAAc,gBAAgB,IAAI,CAAC;MAC3D,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;MAC3C,GAAI,kBAAkB,KAAA,IAClB,EAAE,wBAAwB,cAAc,IACxC,CAAC;MACL,GAAI,SAAS,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,IAAI,CAAC;KAC3C;KACA,MAAM,iBAAiB,QAAQ,QAAQ,KAAK,aAAa,UACvD,UAAU,YAAY,cAAc,WACtC;KACA,UAAU,gBAAgB;MAAE,GAAG;MAAS,SAAS;KAAe;KAChE,UAAU;KACV;IACF;GACF;GAEA,IAAI,SACF;GAGF,MAAM,KAAK,iBAAiB;GAC5B,MAAM,WACJ,UAAU,YAAY,MAAM,KAC5B,UAAU,YAAY,UAAU,KAChC;GACF,UAAU,KAAK;IACb,IAAI,GAAG,GAAG;IACV,MAAM;IACN,SAAS,CACP;KACE,MAAM;KACN;KACA;KACA,MAAM,CAAC;KACP,UAAU;KACV;KACA,GAAI,kBAAkB,EAAE,cAAc,gBAAgB,IAAI,CAAC;KAC3D,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;KAC3C,GAAI,kBAAkB,KAAA,IAClB,EAAE,wBAAwB,cAAc,IACxC,CAAC;KACL,GAAI,SAAS,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,IAAI,CAAC;IAC3C,CACF;GACF,CAAC;GACD;EACF;EAEA,IAAI,SAAS,YAAY;GAIvB,IADqB,UAAU,YAAY,cAC5B,MAAA,gBAAkC;GAIjD,MAAM,cAHkB,SAAS,WAAW,OAAO,IAC9C,WAAW,UACZ,KAAA,GACiC;GACrC,IAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;GAEhC,IAAI,aAAa;GACjB,KAAK,IAAI,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;IAC9C,MAAM,YAAY,UAAU;IAC5B,IAAI,aAAa,UAAU,SAAS,aAAa;KAC/C,aAAa;KACb;IACF;GACF;GACA,IAAI,eAAe,IAAI;GAEvB,MAAM,QAAQ,UAAU;GACxB,MAAM,YAAY,UAAU,YAAY,IAAI,KAAK;GACjD,MAAM,EAAE,UAAU,oCAAoB,IAAI,IAAI,GAAG,UAAU;GAC3D,YAAY,OAAO,SAAS;GAC5B,uBAAuB,OAAO,SAAS;GACvC,YAAY,IAAI,WAAW,KAAK;GAChC,uBAAuB,IAAI,WAAW,UAAU;GAEhD,MAAM,6BAAa,IAAI,IAA8B;GACrD,KAAK,MAAM,CAAC,oBAAoB,mBAAmB,aAAa;IAC9D,IAAI,uBAAuB,IAAI,kBAAkB,MAAM,YACrD;IACF,KAAK,MAAM,CAAC,WAAW,YAAY,gBACjC,WAAW,IAAI,WAAW,OAAO;GAErC;GACA,UAAU,cAAc,mBAAmB,OAAO,UAAU;GAC5D;EACF;EAEA,IAAI,SAAS,aAAa;GACxB,UAAU,KAAK,2BAA2B,UAAU,CAAC;GACrD;EACF;EAEA,IAAI,SAAS,aAAa;GACxB,MAAM,OAAO,YAAY,WAAW,OAAO;GAC3C,MAAM,iBAAiB,UAAU,YAAY,gBAAgB;GAC7D,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG;IAI5B,MAAM,WAAW,UAAU,YAAY,IAAI;IAC3C,IAAI,UAAU,KAAK,KAAK,gBAAgB,KAAK,GAC3C,gBAAgB,KAAK;KACnB,IAAI;KACJ;KACA,QAAQ,UAAU;IACpB,CAAC;IAEH;GACF;GAKA,IAAI,CAAC,cAAc;IACjB,MAAM,WAAW,UAAU,YAAY,IAAI;IAC3C,IAAI,UAAU,KAAK,KAAK,gBAAgB,KAAK,GAC3C,gBAAgB,KAAK;KACnB,IAAI;KACJ;KACA,QAAQ,UAAU;IACpB,CAAC;IAEH;GACF;GACA,UAAU,KAAK;IACb,IAAI,UAAU,YAAY,IAAI,KAAK,WAAW;IAC9C,MAAM;IACN,SAAS,CACP;KACE,MAAM;KACN;KACA,GAAI,mBAAmB,KAAA,IACnB,EACE,kBAAkB,GACf,2BAA2B,EAAE,eAAe,EAC/C,EACF,IACA,CAAC;IACP,CACF;GACF,CAAC;GACD;EACF;EAEA,IAAI,SAAS,UAAU,SAAS,UAC9B,UAAU,KAAK,8BAA8B,MAAM,UAAU,CAAC;CAElE;CAEA,KAAK,MAAM,EAAE,QAAQ,GAAG,WAAW,iBAAiB;EAElD,MAAM,WAAW,UAAU,UAAU;EACrC,MAAM,QAAQ,WAAW,UAAU,SAAS,IAAI;EAChD,MAAM,SAAS,UAAU;EACzB,IAAI,CAAC,QAAQ;EACb,UAAU,SAAS,oBAAoB,QAAQ,CAC7C,GAAG,oBAAoB,OAAO,QAAQ,GACtC,GAAI,WAAW,CAAC;GAAE,GAAG;GAAO,OAAO;EAAK,CAAC,IAAI,CAAC,KAAK,CACrD,CAAC;CACH;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,UAAU,UAAU;EAC1B,IAAI,QAAQ,SAAS,aAAa;EAElC,MAAM,eACJ,wBAAwB,QAAQ,QAAQ,MAAM,KAAA;EAChD,MAAM,qBACJ,MAAM,QAAQ,QAAQ,OAAO,KAC7B,QAAQ,QAAQ,MACb,SACC,SAAS,IAAI,KACb,KAAK,SAAS,eACd,KAAK,WAAW,KAAA,CACpB;EAEF,IAAI,gBAAgB,oBAClB,UAAU,KAAK;GACb,GAAG;GACH,QAAQ,cACN,OACA,OACA,cACA,oBACA,KAAA,CACF;EACF;CAEJ;CAEA,OAAO;AACT;AAEA,SAAS,wBACP,SACA,WACM;CACN,MAAM,UAAU,YAAY,QAAQ,OAAO;CAC3C,MAAM,eAAe,MAAM,QAAQ,QAAQ,OAAO,IAAI,QAAQ,UAAU,CAAC;CAWzE,MAAM,YATgB,aAAa,QAChC,SACC,MAAM,SAAS,eACf,EACE,OAAO,KAAK,eAAe,YAC3B,KAAK,WAAW,WAAW,OAAO,EAIV,CAAC,CAAC,KAAK,UAAU;EAC7C,GAAG,kBAAkB,IAAI;EACzB;CACF,EAAE;CAIF,MAAM,iBAAiB,QAAQ,WAAW,KAAK,UAAU,WAAW;CACpE,IAAI,iBAAiB;CACrB,KAAK,MAAM,QAAQ,cAAc;EAC/B,IAAI,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS,aAAa;EAClD,MAAM,OAAO,UAAU,MAAM,MAAM,KAAK;EACxC,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG;EAC9B,MAAM,EAAE,gBAAgB,gBAAgB,sBACtC,KAAK,gBACP;EACA,UAAU,KAAK;GAGb,IAAI,aAAa,KAAK,IAClB,cACA,kBAAkB,mBAAmB,IACnC,QAAQ,KACR,GAAG,QAAQ,GAAG,aAAa;GACjC,MAAM;GACN,SAAS;GACT,GAAI,mBAAmB,KAAA,IAAY,EAAE,eAAe,IAAI,CAAC;EAC3D,CAAC;EACD;CACF;CAIA,IAAI,gBACF;CAGF,MAAM,mBAAgC;EACpC,IAAI,QAAQ;EACZ,MAAM;EACN;CACF;CACA,IAAI,QAAQ,MACV,iBAAiB,OAAO,QAAQ;CAElC,IAAI,UAAU,SAAS,GACrB,iBAAiB,YAAY,UAAU,KAAK,UAAU,MAAM,IAAI;CAElE,UAAU,KAAK,gBAAgB;CAE/B,KAAK,MAAM,EAAE,IAAI,YAAY,UAAU,WAAW;EAChD,IAAI,KAAK,WAAW,KAAA,GAAW;EAE/B,MAAM,gBACJ,KAAK,iBAAiB,KAAA,IAClB,YAAY,KAAK,YAAY,IAC7B,OAAO,KAAK,WAAW,WACrB,KAAK,SACL,KAAK,UAAU,KAAK,MAAM;EAElC,MAAM,cAA2B;GAC/B,IAAI,KAAK,0BAA0B,GAAG,WAAW;GACjD,MAAM;GACN,SAAS;GACT;EACF;EACA,IAAI,KAAK,SACP,YAAY,QAAQ;EAEtB,UAAU,KAAK,WAAW;CAC5B;AACF;AAEA,SAAS,mBACP,SACA,WACM;CACN,MAAM,UAAU,YAAY,QAAQ,OAAO;CAC3C,MAAM,aAAa,QAAQ,cAAc,WAAW;CAEpD,MAAM,cAA2B;EAC/B,IAAI,QAAQ;EACZ,MAAM;EACN;EACA;CACF;CACA,IAAI,OAAO,QAAQ,UAAU,UAC3B,YAAY,QAAQ,QAAQ;CAE9B,UAAU,KAAK,WAAW;AAC5B;AAEA,SAAgB,eACd,UACe;CACf,MAAM,YAA2B,CAAC;CAElC,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,kBAAkB,oBAAoB,QAAQ,QAAQ;EAC5D,MAAM,kBAAkB,WAA6C;GACnE,IAAI,MAAM;GACV,MAAM;GACN,SAAS;GACT,gBAAgB,MAAM;EACxB;EACA,KAAK,MAAM,SAAS,iBAClB,IAAI,MAAM,UAAU,MAAM,UAAU,KAAK,eAAe,KAAK,CAAC;EAEhE,MAAM,qCAAqC;GACzC,KAAK,MAAM,SAAS,iBAClB,IAAI,MAAM,UAAU,MAAM,UAAU,KAAK,eAAe,KAAK,CAAC;EAElE;EAEA,IAAI,QAAQ,SAAS,aAAa;GAChC,wBAAwB,SAAS,SAAS;GAC1C,6BAA6B;GAC7B;EACF;EAEA,IAAI,QAAQ,SAAS,QAAQ;GAC3B,mBAAmB,SAAS,SAAS;GACrC,6BAA6B;GAC7B;EACF;EAEA,MAAM,iBAA8B;GAClC,IAAI,QAAQ;GACZ,MAAM,QAAQ;GACd,SACE,QAAQ,SAAS,SACb,iBAAiB,OAAO,IACxB,YAAY,QAAQ,OAAO;EACnC;EACA,IAAI,QAAQ,MACV,eAAe,OAAO,QAAQ;EAEhC,UAAU,KAAK,cAAc;EAC7B,6BAA6B;CAC/B;CAEA,OAAO;AACT;AAIA,SAAgB,YACd,OACY;CACZ,IAAI,CAAC,OAAO,OAAO,CAAC;CAEpB,MAAM,cAAc,kBAAkB,KAAK;CAC3C,OAAO,OAAO,QAAQ,WAAW,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW;EACxD;EACA,aAAa,KAAK,eAAe;EACjC,YAAY,KAAK;CACnB,EAAE;AACJ"}
|
|
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 ToolCallMessagePartMcpMetadata,\n ToolModelContentPart,\n} from \"@assistant-ui/core\";\nimport {\n getAutoStatus,\n parseDataUrl,\n resolveFilePartSource,\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 type AgUiCustomMetadata,\n type AgUiOpaqueReasoning,\n} from \"./run-aggregator\";\nimport {\n applyA2uiOperations,\n convertSurfaceToUISpec,\n type A2uiState,\n type A2uiSurfaceState,\n} from \"@assistant-ui/react-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;\n role: string;\n content: unknown;\n metadata?: unknown;\n name?: string;\n toolCallId?: string;\n error?: string;\n attachments?: readonly AttachmentLike[];\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 }\n | {\n id: string;\n role: \"assistant\";\n content: string;\n name?: string;\n toolCalls?: AgUiToolCall[];\n }\n | {\n id: string;\n role: \"system\" | \"developer\";\n content: string;\n name?: string;\n }\n | {\n id: string;\n role: \"reasoning\";\n content: string;\n encryptedValue?: string;\n }\n | {\n id: string;\n role: \"tool\";\n content: string;\n toolCallId: string;\n error?: string;\n };\n\ntype ToolCallPart = {\n type: \"tool-call\";\n toolCallId?: string;\n toolName: string;\n argsText?: string;\n args?: ReadonlyJSONObject;\n result?: unknown;\n isError?: boolean;\n modelContent?: readonly ToolModelContentPart[];\n unstable_toolMessageId?: string;\n mcp?: ToolCallMessagePartMcpMetadata;\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\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 };\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\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.\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 });\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 return {\n type: \"image\",\n source: buildInputSource(image, fallbackMimeType),\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\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 return [\n { id, encryptedValue, ...(entry.after === true ? { after: true } : {}) },\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 interrupts = readPersistedInterrupts(rawMessage.metadata);\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 return {\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: assistantContent.length > 0 ? assistantContent : \"\",\n ...(messageName !== undefined ? { name: messageName } : {}),\n ...(interrupts\n ? {\n metadata: {\n custom: {\n [AG_UI_METADATA_NAMESPACE]: {\n interrupts,\n } satisfies AgUiCustomMetadata,\n },\n },\n }\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 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 ...(role === \"developer\"\n ? {\n metadata: {\n custom: {\n [AG_UI_METADATA_NAMESPACE]: {\n role: \"developer\",\n } satisfies AgUiCustomMetadata,\n },\n },\n }\n : {}),\n };\n}\n\n// Rebuilds the a2ui:<surfaceId> \"present\" tool-call parts for one owning\n// assistant message from a bucket of rebuilt surface state, mirroring the\n// live RunAggregator.synthesizeA2uiToolCalls shape. Non-a2ui parts (text,\n// other tool calls) are preserved; existing a2ui parts are replaced wholesale\n// so create/update/delete within the bucket all converge on the rebuilt set.\nfunction attachA2uiSurfaces(\n message: CoreThreadMessageLike,\n state: A2uiState,\n): CoreThreadMessageLike {\n const a2uiParts: ToolCallPart[] = [];\n for (const [surfaceId, surface] of state) {\n const { spec } = convertSurfaceToUISpec(surface);\n if (!spec) continue;\n a2uiParts.push({\n type: \"tool-call\",\n toolCallId: `a2ui:${surfaceId}`,\n toolName: \"present\",\n args: spec as unknown as ReadonlyJSONObject,\n argsText: JSON.stringify(spec),\n result: {},\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\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 // 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\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 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\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 };\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 },\n ],\n });\n continue;\n }\n\n if (role === \"activity\") {\n // Only a2ui-surface activity messages have an assistant-part equivalent\n // to rehydrate; other activity types still have no surface to repaint.\n const activityType = getString(rawMessage, \"activityType\");\n if (activityType !== A2UI_SURFACE_ACTIVITY_TYPE) continue;\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\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 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(toAssistantSnapshotMessage(rawMessage));\n continue;\n }\n\n if (role === \"reasoning\") {\n const text = extractText(rawMessage.content);\n const encryptedValue = getString(rawMessage, \"encryptedValue\");\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 opaqueReasoning.push({\n id: opaqueId,\n encryptedValue,\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 anchor: converted.length,\n });\n }\n continue;\n }\n converted.push({\n id: getString(rawMessage, \"id\") ?? generateId(),\n role: \"assistant\",\n content: [\n {\n type: \"reasoning\",\n text,\n ...(encryptedValue !== undefined\n ? {\n providerMetadata: {\n [AG_UI_METADATA_NAMESPACE]: { encryptedValue },\n },\n }\n : {}),\n },\n ],\n });\n continue;\n }\n\n if (role === \"user\" || role === \"system\" || role === \"developer\") {\n converted.push(toUserOrSystemSnapshotMessage(role, rawMessage));\n }\n }\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 for (let i = 0; i < converted.length; i++) {\n const message = converted[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 converted[i] = {\n ...message,\n status: getAutoStatus(\n false,\n false,\n hasInterrupt,\n hasPendingToolCall,\n undefined,\n ),\n };\n }\n }\n\n return converted;\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 } = readAgUiReasoningMeta(\n part.providerMetadata,\n );\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 });\n reasoningIndex++;\n }\n\n // Drop assistant messages with no text or tool calls (e.g. an imported\n // reasoning-only entry) so they are not re-sent as a blank assistant turn.\n if (shellIsDropped) {\n return;\n }\n\n converted.push({\n id: message.id,\n role: \"assistant\",\n content,\n ...(message.name ? { name: message.name } : {}),\n ...(toolCalls.length > 0\n ? { toolCalls: toolCalls.map((entry) => entry.call) }\n : {}),\n });\n\n for (const { id: toolCallId, part } of toolCalls) {\n if (part.result === undefined) continue;\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\n converted.push({\n id: part.unstable_toolMessageId ?? `${toolCallId}:tool`,\n role: \"tool\",\n content: resultContent,\n toolCallId,\n ...(part.isError ? { error: resultContent } : {}),\n });\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 });\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 });\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 });\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 });\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 });\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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"}
|
|
@@ -9,6 +9,9 @@ type AgUiOpaqueReasoning = {
|
|
|
9
9
|
after?: boolean;
|
|
10
10
|
};
|
|
11
11
|
type AgUiCustomMetadata = {
|
|
12
|
+
/** Wire role restored on export for messages the internal model cannot
|
|
13
|
+
* represent (a developer record rides as a system message). */
|
|
14
|
+
role?: "developer";
|
|
12
15
|
interrupts?: AgUiInterrupt[];
|
|
13
16
|
opaqueReasoning?: AgUiOpaqueReasoning[];
|
|
14
17
|
};
|
|
@@ -21,24 +24,39 @@ type RunAggregatorOptions = {
|
|
|
21
24
|
logger: Logger;
|
|
22
25
|
emit: Emit;
|
|
23
26
|
onServerMessageId?: (messageId: string) => void;
|
|
27
|
+
onTextMessageStart?: (messageId: string) => void;
|
|
24
28
|
};
|
|
25
29
|
/**
|
|
26
30
|
* Collects AG-UI events into assistant-ui run snapshots that can be yielded from a ChatModelAdapter.
|
|
27
31
|
*
|
|
28
32
|
* The aggregator keeps a single assistant message worth of parts. Each incoming event updates the parts and
|
|
29
|
-
* emits a fresh snapshot through the provided `emit` callback.
|
|
33
|
+
* emits a fresh snapshot through the provided `emit` callback. `CUSTOM` events
|
|
34
|
+
* become canonical data parts; integration plumbing names such as
|
|
35
|
+
* `on_interrupt`, `PredictState`, `Exit`, `hook_error`, `state_update_error`,
|
|
36
|
+
* `system:*`, and `MultiAgentHandoff` are forwarded the same way, so apps only
|
|
37
|
+
* need data renderers for names they own.
|
|
30
38
|
*/
|
|
31
39
|
declare class RunAggregator {
|
|
32
40
|
private readonly emitUpdate;
|
|
33
41
|
private readonly showThinking;
|
|
34
42
|
private readonly logger;
|
|
35
43
|
private readonly onServerMessageId;
|
|
44
|
+
private readonly onTextMessageStart;
|
|
36
45
|
private status;
|
|
37
46
|
private interrupts;
|
|
38
47
|
private readonly textParts;
|
|
39
48
|
private activeTextMessageId;
|
|
40
49
|
private readonly reasoningParts;
|
|
41
50
|
private readonly reasoningSignatures;
|
|
51
|
+
private readonly reasoningSignatureIds;
|
|
52
|
+
private readonly hiddenSignatures;
|
|
53
|
+
private readonly hiddenSignatureAnchors;
|
|
54
|
+
private readonly hiddenBlockAnchors;
|
|
55
|
+
private hiddenAnonymousAnchor;
|
|
56
|
+
private readonly hiddenReasoningIds;
|
|
57
|
+
private hiddenActiveReasoning;
|
|
58
|
+
private hasEmittedOpaqueReasoning;
|
|
59
|
+
private readonly loggedDroppedOpaqueIds;
|
|
42
60
|
private readonly reasoningMessageIds;
|
|
43
61
|
private readonly anonymousReasoningKeys;
|
|
44
62
|
private activeReasoningKey;
|
|
@@ -50,6 +68,8 @@ declare class RunAggregator {
|
|
|
50
68
|
private readonly partOrder;
|
|
51
69
|
private textPartCounter;
|
|
52
70
|
private serverMessageIdReported;
|
|
71
|
+
private reportedServerMessageId;
|
|
72
|
+
private lastTextMessageId;
|
|
53
73
|
private streamStartTime;
|
|
54
74
|
private firstTokenTime;
|
|
55
75
|
private totalChunks;
|
|
@@ -60,11 +80,12 @@ declare class RunAggregator {
|
|
|
60
80
|
private synthesizeA2uiToolCalls;
|
|
61
81
|
private reportServerMessageId;
|
|
62
82
|
private clearTextParts;
|
|
83
|
+
private resetMessageParts;
|
|
84
|
+
private beginDistinctTextMessage;
|
|
63
85
|
private generateTextKey;
|
|
64
86
|
private startTextMessage;
|
|
65
87
|
private resolveTextMessageId;
|
|
66
88
|
private ensureTextPart;
|
|
67
|
-
private markTextPartTouched;
|
|
68
89
|
private appendText;
|
|
69
90
|
private startToolCall;
|
|
70
91
|
private insertToolPart;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-aggregator.d.ts","names":[],"sources":["../../../src/runtime/adapter/run-aggregator.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"run-aggregator.d.ts","names":[],"sources":["../../../src/runtime/adapter/run-aggregator.ts"],"mappings":";;;;cAqBa;KAED;EACV;EACA;EACA;;KAGU;;;EAGV;EACA,aAAa;EACb,kBAAkB;;KAGf,QAAQ,QAAQ;cAiBR;cAEA;cAEA,gBACX,mBACC,SAAS;KAGA;EACV;EACA,QAAQ;EACR,MAAM;EACN,qBAAqB;EACrB,sBAAsB;;;;;;;;;;;;cAaX;mBACM;mBACA;mBACA;mBACA;mBACA;UAIT;UACA;mBACS;UACT;mBACS;mBACA;mBACA;mBAKA;mBACA;mBACA;UACT;mBACS;UACT;UACA;mBACS;mBACA;mBACA;UACT;UACA;mBACS;mBACA;mBACA;UACT;mBACS;UAMT;UACA;UACA;UACA;UAEA;UACA;UACA;EAEI,YAAA,SAAS;EAQrB,YAAY;EAIZ,OAAO,OAAO;UA+PN;UAmBA;UA+CA;UAWA;UAIA;UA0BA;UAaA;UAKA;UAOA;UAiBA;UAWA;UAOA;UAiCA;UA2BA;UAgBA;UAsDA;UA2KA;UASA;UAgCA;UAiCA;UAwBA;;iBAUM,aAAa"}
|