@assistant-ui/ai-sdk 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +1 -1
  2. package/dist/converters/convertMessage.d.ts +2 -0
  3. package/dist/converters/convertMessage.d.ts.map +1 -1
  4. package/dist/converters/convertMessage.js +15 -4
  5. package/dist/converters/convertMessage.js.map +1 -1
  6. package/dist/converters/toCreateMessage.d.ts.map +1 -1
  7. package/dist/converters/toCreateMessage.js +2 -1
  8. package/dist/converters/toCreateMessage.js.map +1 -1
  9. package/dist/runtime/AISDKChat.d.ts.map +1 -1
  10. package/dist/runtime/AISDKChat.js.map +1 -1
  11. package/dist/runtime/AISDKThreads.js.map +1 -1
  12. package/dist/runtime/sdkIdentity.js +1 -1
  13. package/dist/runtime/useAISDKRuntime.d.ts +8 -1
  14. package/dist/runtime/useAISDKRuntime.d.ts.map +1 -1
  15. package/dist/runtime/useAISDKRuntime.js +212 -34
  16. package/dist/runtime/useAISDKRuntime.js.map +1 -1
  17. package/dist/runtime/useChatRuntime.js +1 -1
  18. package/dist/runtime/useChatRuntime.js.map +1 -1
  19. package/dist/runtime/useChatThread.d.ts.map +1 -1
  20. package/dist/runtime/useChatThread.js +40 -10
  21. package/dist/runtime/useChatThread.js.map +1 -1
  22. package/dist/runtime/useExternalHistory.d.ts.map +1 -1
  23. package/dist/runtime/useExternalHistory.js +2 -1
  24. package/dist/runtime/useExternalHistory.js.map +1 -1
  25. package/dist/runtime/useResourceCleanup.js.map +1 -1
  26. package/dist/runtime/useStreamingTiming.js.map +1 -1
  27. package/dist/transport/AssistantChatTransport.d.ts.map +1 -1
  28. package/dist/transport/AssistantChatTransport.js +9 -2
  29. package/dist/transport/AssistantChatTransport.js.map +1 -1
  30. package/dist/transport/resumable.js.map +1 -1
  31. package/dist/usage.js.map +1 -1
  32. package/package.json +15 -12
  33. package/src/converters/convertMessage.test.ts +99 -0
  34. package/src/converters/convertMessage.ts +27 -2
  35. package/src/converters/toCreateMessage.test.ts +13 -0
  36. package/src/converters/toCreateMessage.ts +1 -0
  37. package/src/runtime/AISDKChat.ts +0 -4
  38. package/src/runtime/AISDKThreads.test.ts +26 -0
  39. package/src/runtime/useAISDKRuntime.approval.integration.test.tsx +1588 -19
  40. package/src/runtime/useAISDKRuntime.approval.test.tsx +27 -0
  41. package/src/runtime/useAISDKRuntime.fast-refresh.test.tsx +182 -0
  42. package/src/runtime/useAISDKRuntime.ts +397 -28
  43. package/src/runtime/useChatRuntime.fast-refresh.test.tsx +94 -0
  44. package/src/runtime/useChatRuntime.integration.test.tsx +134 -112
  45. package/src/runtime/useChatRuntime.test.ts +7 -7
  46. package/src/runtime/useChatThread.test.ts +166 -2
  47. package/src/runtime/useChatThread.transport.test.tsx +5 -2
  48. package/src/runtime/useChatThread.ts +56 -17
  49. package/src/runtime/useExternalHistory.ts +12 -1
  50. package/src/transport/AssistantChatTransport.test.ts +164 -0
  51. package/src/transport/AssistantChatTransport.ts +22 -2
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 AgentbaseAI Inc.
3
+ Copyright (c) 2026 AgentbaseAI Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,6 +18,8 @@ export type AISDKMessageConverterMetadata = useExternalMessageConverter.Metadata
18
18
  toolInteractions?: ReadonlyMap<string, Unstable_ToolInteractionLog>;
19
19
  supportsRichToolApprovalResponses?: boolean;
20
20
  toolApprovalResponses?: ReadonlyMap<string, RespondToToolApprovalOptions>;
21
+ cancelledToolApprovalIds?: ReadonlySet<string>;
22
+ cancelledStatusMessageIds?: ReadonlySet<string>;
21
23
  /** Id of the currently-streaming message, flagged optimistic (#4037). */
22
24
  optimisticMessageId?: string | undefined;
23
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessage.d.ts","sourceRoot":"","sources":["../../src/converters/convertMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AACZ,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAYL,KAAK,cAAc,EAEnB,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EACjC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AA6BhC,MAAM,MAAM,6BAA6B,GACvC,2BAA2B,CAAC,QAAQ,GAAG;IACrC,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3D;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IACpE,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;IAC1E,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,CAAC;AAkhBJ,eAAO,MAAM,qBAAqB;;;;;;;;+HApkBX,qDACD;8HAE+B,qDAE7C;;;CAioBP,CAAC"}
1
+ {"version":3,"file":"convertMessage.d.ts","sourceRoot":"","sources":["../../src/converters/convertMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AACZ,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAYL,KAAK,cAAc,EAEnB,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EACjC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,wBAAwB,CAAC;AA6BhC,MAAM,MAAM,6BAA6B,GACvC,2BAA2B,CAAC,QAAQ,GAAG;IACrC,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3D;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrD,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IACpE,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,qBAAqB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;IAC1E,wBAAwB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C,yBAAyB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,CAAC;AAgiBJ,eAAO,MAAM,qBAAqB;;;;;;;;+HAplBX,qDACD;8HAE+B,qDAE7C;;;CA0pBP,CAAC"}
@@ -28,7 +28,9 @@ const toThreadMetadata = (metadata) => {
28
28
  return result;
29
29
  };
30
30
  function stripClosingDelimiters(json) {
31
- return json.replace(/[}\]"]+$/, "");
31
+ let end = json.length;
32
+ while (end > 0 && "}]\"".includes(json[end - 1])) end--;
33
+ return json.slice(0, end);
32
34
  }
33
35
  const MCP_APP_METADATA_CACHE_MAX = 100;
34
36
  function extractMcpAppMetadata(part, cache) {
@@ -113,12 +115,16 @@ const readApprovalDescriptor = (descriptor) => {
113
115
  for (const key of APPROVAL_DESCRIPTOR_FIELDS) if (Object.hasOwn(descriptor, key)) fields[key] = descriptor[key];
114
116
  return fields;
115
117
  };
116
- function getToolApprovalAndInterrupt(part, toolStatus, supportsRichToolApprovalResponses, toolApprovalResponses) {
118
+ function getToolApprovalAndInterrupt(part, toolStatus, supportsRichToolApprovalResponses, toolApprovalResponses, cancelledToolApprovalIds) {
117
119
  if (part.approval) {
118
- const approval = {
120
+ const rawApproval = {
119
121
  ...readApprovalDescriptor(part.approval.descriptor),
120
122
  ...part.approval
121
123
  };
124
+ const approval = typeof rawApproval.id === "string" && rawApproval.approved === void 0 && rawApproval.resolution === void 0 && cancelledToolApprovalIds?.has(rawApproval.id) ? {
125
+ ...rawApproval,
126
+ resolution: "cancelled"
127
+ } : rawApproval;
122
128
  const response = typeof approval.id === "string" && approval.approved === void 0 && approval.resolution !== "cancelled" && approval.resolution !== "expired" ? toolApprovalResponses?.get(approval.id) : void 0;
123
129
  const { id, prompt, approved, reason, isAutomatic, resolution, display, allowFreeform, dismissible, options, optionId, text, ...additionalApprovalFields } = response ? {
124
130
  ...approval,
@@ -233,7 +239,7 @@ function convertParts(message, metadata) {
233
239
  ...modelContent !== void 0 && { modelContent },
234
240
  ...mcpApp && { mcp: { app: mcpApp } },
235
241
  ...part.callProviderMetadata != null ? { providerMetadata: part.callProviderMetadata } : void 0,
236
- ...getToolApprovalAndInterrupt(part, toolStatus, metadata.supportsRichToolApprovalResponses === true, metadata.toolApprovalResponses)
242
+ ...getToolApprovalAndInterrupt(part, toolStatus, metadata.supportsRichToolApprovalResponses === true, metadata.toolApprovalResponses, metadata.cancelledToolApprovalIds)
237
243
  };
238
244
  }
239
245
  if (part.type === "source-url") return {
@@ -261,6 +267,7 @@ function convertParts(message, metadata) {
261
267
  };
262
268
  if (part.type.startsWith("data-")) return {
263
269
  type: "data",
270
+ ..."id" in part && typeof part.id === "string" ? { id: part.id } : void 0,
264
271
  name: part.type.substring(5),
265
272
  data: part.data
266
273
  };
@@ -327,6 +334,10 @@ const AISDKMessageConverter = createMessageConverter((message, metadata) => {
327
334
  id: message.id,
328
335
  createdAt,
329
336
  content,
337
+ ...message.role === "assistant" && metadata.cancelledStatusMessageIds?.has(message.id) ? { status: {
338
+ type: "incomplete",
339
+ reason: "cancelled"
340
+ } } : void 0,
330
341
  metadata: {
331
342
  ...toThreadMetadata(message.metadata),
332
343
  ...timing && { timing },
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessage.js","names":["isToolUIPart","isReasoningFileUIPart","isCustomContentUIPart","getToolName","UIMessage","createMessageConverter","unstable_createMessageConverter","useExternalMessageConverter","isMcpAppUri","ReasoningMessagePart","ToolApprovalOption","ToolCallMessagePart","TextMessagePart","DataMessagePart","PartProviderMetadata","SourceMessagePart","SourceProviderMetadata","FileMessagePart","ThreadMessageLike","McpAppMetadata","MessagePartStreamStatus","RespondToToolApprovalOptions","Unstable_ToolInteractionLog","stableStringifyToolArgs","parsePartialJsonObject","ReadonlyJSONObject","unwrapModelContentEnvelope","MessageMetadata","THREAD_METADATA_KEYS","Set","toThreadMetadata","metadata","undefined","result","Record","extra","Object","create","key","value","entries","has","keys","length","custom","AISDKMessageConverterMetadata","Metadata","toolArgsKeyOrderCache","Map","toolArgsTextCache","WeakMap","toolLastInputCache","mcpAppMetadataCache","toolArtifacts","ReadonlyMap","toolInteractions","supportsRichToolApprovalResponses","toolApprovalResponses","optimisticMessageId","stripClosingDelimiters","json","replace","MCP_APP_METADATA_CACHE_MAX","extractMcpAppMetadata","part","cache","meta","callProviderMetadata","mcp","app","a","output","outMeta","_meta","ui","uiMeta","resourceUri","Array","isArray","visibility","flat","cacheKey","cached","get","delete","set","out","K","mimeType","filter","v","serverId","size","oldest","next","normalizeToolApprovalOptions","options","flatMap","option","id","kind","confirm","confirmDetails","label","description","grants","grant","title","APPROVAL_DESCRIPTOR_FIELDS","const","readApprovalDescriptor","descriptor","fields","hasOwn","getToolApprovalAndInterrupt","approval","toolStatus","type","payload","NonNullable","interrupt","response","approved","resolution","prompt","reason","isAutomatic","display","allowFreeform","dismissible","optionId","text","additionalApprovalFields","normalizedOptions","requestReason","MessageContent","Exclude","uiPartStateToStatus","state","convertParts","message","parts","converted","p","role","map","status","providerMetadata","toolName","toolCallId","argsKeyOrderCacheKey","rawInput","input","args","modelContent","isError","unwrapped","error","errorText","argsText","frozen","frozenText","toolStatuses","mcpApp","artifact","interactions","unstable_interactions","preliminary","isPreliminary","sourceType","sourceId","url","data","mediaType","filename","startsWith","name","substring","console","warn","Boolean","seenToolCallIds","add","AISDKMessageConverter","createdAt","Date","content","attachments","idx","isImage","toString","image","contentType","timing","messageTiming","isOptimistic"],"sources":["../../src/converters/convertMessage.ts"],"sourcesContent":["import {\n isToolUIPart,\n isReasoningFileUIPart,\n isCustomContentUIPart,\n getToolName,\n type UIMessage,\n} from \"ai\";\nimport {\n createMessageConverter as unstable_createMessageConverter,\n type useExternalMessageConverter,\n} from \"@assistant-ui/core/react\";\nimport {\n isMcpAppUri,\n type ReasoningMessagePart,\n type ToolApprovalOption,\n type ToolCallMessagePart,\n type TextMessagePart,\n type DataMessagePart,\n type PartProviderMetadata,\n type SourceMessagePart,\n type SourceProviderMetadata,\n type FileMessagePart,\n type ThreadMessageLike,\n type McpAppMetadata,\n type MessagePartStreamStatus,\n type RespondToToolApprovalOptions,\n type Unstable_ToolInteractionLog,\n} from \"@assistant-ui/core\";\nimport { stableStringifyToolArgs } from \"@assistant-ui/core/internal\";\nimport {\n parsePartialJsonObject,\n type ReadonlyJSONObject,\n} from \"assistant-stream/utils\";\nimport { unwrapModelContentEnvelope } from \"./modelContentEnvelope\";\n\ntype MessageMetadata = ThreadMessageLike[\"metadata\"];\n\nconst THREAD_METADATA_KEYS = new Set([\n \"unstable_state\",\n \"unstable_annotations\",\n \"unstable_data\",\n \"steps\",\n \"timing\",\n \"submittedFeedback\",\n \"isOptimistic\",\n \"modality\",\n \"custom\",\n]);\n\nconst toThreadMetadata = (metadata: unknown): MessageMetadata => {\n if (!metadata || typeof metadata !== \"object\") return undefined;\n const result: Record<string, unknown> = {};\n const extra = Object.create(null) as Record<string, unknown>;\n for (const [key, value] of Object.entries(metadata)) {\n (THREAD_METADATA_KEYS.has(key) ? result : extra)[key] = value;\n }\n if (Object.keys(extra).length > 0) {\n result.custom = { ...extra, ...(result.custom as object | undefined) };\n }\n return result as MessageMetadata;\n};\nexport type AISDKMessageConverterMetadata =\n useExternalMessageConverter.Metadata & {\n toolArgsKeyOrderCache?: Map<string, Map<string, string[]>>;\n /**\n * Frozen `argsText` keyed weakly by a settled tool call's input object, then\n * by call, since the text carries the call's streamed key order. A known\n * call/input pair skips serialization; the entries become collectible once\n * the input is unreachable. A fresh input object re-serializes in its own\n * deterministic key order.\n */\n toolArgsTextCache?: WeakMap<ReadonlyJSONObject, Map<string, string>>;\n toolLastInputCache?: Map<string, ReadonlyJSONObject>;\n mcpAppMetadataCache?: Map<string, McpAppMetadata>;\n toolArtifacts?: ReadonlyMap<string, unknown>;\n toolInteractions?: ReadonlyMap<string, Unstable_ToolInteractionLog>;\n supportsRichToolApprovalResponses?: boolean;\n toolApprovalResponses?: ReadonlyMap<string, RespondToToolApprovalOptions>;\n /** Id of the currently-streaming message, flagged optimistic (#4037). */\n optimisticMessageId?: string | undefined;\n };\n\nfunction stripClosingDelimiters(json: string): string {\n return json.replace(/[}\\]\"]+$/, \"\");\n}\n\nconst MCP_APP_METADATA_CACHE_MAX = 100;\n\nfunction extractMcpAppMetadata(\n part: unknown,\n cache: Map<string, McpAppMetadata> | undefined,\n): McpAppMetadata | undefined {\n if (!part || typeof part !== \"object\") return undefined;\n const meta = (part as { callProviderMetadata?: unknown })\n .callProviderMetadata;\n const mcp =\n meta && typeof meta === \"object\"\n ? (meta as { mcp?: unknown }).mcp\n : undefined;\n const app =\n mcp && typeof mcp === \"object\" ? (mcp as { app?: unknown }).app : undefined;\n let a: Record<string, unknown>;\n if (app && typeof app === \"object\") {\n a = app as Record<string, unknown>;\n } else {\n // MCP-UI tools surface the pointer on result._meta: canonical nested\n // `ui.resourceUri`, or the deprecated flat `\"ui/resourceUri\"` key.\n const output = (part as { output?: unknown }).output;\n const outMeta =\n output && typeof output === \"object\"\n ? (output as { _meta?: unknown })._meta\n : undefined;\n const ui =\n outMeta && typeof outMeta === \"object\"\n ? (outMeta as Record<string, unknown>)[\"ui\"]\n : undefined;\n if (\n ui &&\n typeof ui === \"object\" &&\n typeof (ui as Record<string, unknown>)[\"resourceUri\"] === \"string\" &&\n isMcpAppUri((ui as Record<string, unknown>)[\"resourceUri\"] as string)\n ) {\n // Only the spec'd ui fields cross from the result body; serverId is a\n // routing key and stays transport-derived via callProviderMetadata.\n const uiMeta = ui as Record<string, unknown>;\n a = {\n resourceUri: uiMeta[\"resourceUri\"],\n ...(Array.isArray(uiMeta[\"visibility\"])\n ? { visibility: uiMeta[\"visibility\"] }\n : {}),\n };\n } else {\n const flat =\n outMeta && typeof outMeta === \"object\"\n ? (outMeta as Record<string, unknown>)[\"ui/resourceUri\"]\n : undefined;\n if (typeof flat !== \"string\" || !isMcpAppUri(flat)) return undefined;\n a = { resourceUri: flat };\n }\n }\n if (typeof a[\"resourceUri\"] !== \"string\") return undefined;\n if (!isMcpAppUri(a[\"resourceUri\"])) return undefined;\n const cacheKey = `${typeof a[\"serverId\"] === \"string\" ? a[\"serverId\"] : \"\"} ${a[\"resourceUri\"]}`;\n const cached = cache?.get(cacheKey);\n if (cached) {\n cache!.delete(cacheKey);\n cache!.set(cacheKey, cached);\n return cached;\n }\n const out: { -readonly [K in keyof McpAppMetadata]: McpAppMetadata[K] } = {\n resourceUri: a[\"resourceUri\"],\n };\n if (typeof a[\"mimeType\"] === \"string\") out.mimeType = a[\"mimeType\"];\n if (Array.isArray(a[\"visibility\"])) {\n out.visibility = a[\"visibility\"].filter(\n (v): v is \"model\" | \"app\" => v === \"model\" || v === \"app\",\n );\n }\n if (typeof a[\"serverId\"] === \"string\" && a[\"serverId\"].length > 0)\n out.serverId = a[\"serverId\"];\n if (cache) {\n if (cache.size >= MCP_APP_METADATA_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n cache.set(cacheKey, out);\n }\n return out;\n}\n\nconst normalizeToolApprovalOptions = (\n options: unknown,\n): readonly ToolApprovalOption[] | undefined => {\n if (!Array.isArray(options)) return undefined;\n\n return options.flatMap<ToolApprovalOption>((value) => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return [];\n const option = value as Record<string, unknown>;\n if (typeof option.id !== \"string\" || typeof option.kind !== \"string\")\n return [];\n\n const confirm = option.confirm;\n const confirmDetails =\n confirm && typeof confirm === \"object\" && !Array.isArray(confirm)\n ? (confirm as Record<string, unknown>)\n : undefined;\n\n return [\n {\n id: option.id,\n kind: option.kind,\n ...(typeof option.label === \"string\" && { label: option.label }),\n ...(typeof option.description === \"string\" && {\n description: option.description,\n }),\n ...(Array.isArray(option.grants) && {\n grants: option.grants.filter(\n (grant): grant is string => typeof grant === \"string\",\n ),\n }),\n ...(typeof confirm === \"boolean\"\n ? { confirm }\n : confirmDetails\n ? {\n confirm: {\n ...(typeof confirmDetails.title === \"string\" && {\n title: confirmDetails.title,\n }),\n ...(typeof confirmDetails.description === \"string\" && {\n description: confirmDetails.description,\n }),\n },\n }\n : {}),\n },\n ];\n });\n};\n\nconst APPROVAL_DESCRIPTOR_FIELDS = [\n \"prompt\",\n \"display\",\n \"allowFreeform\",\n \"dismissible\",\n \"options\",\n \"optionId\",\n \"text\",\n \"resolution\",\n] as const;\n\n// The AI SDK's approval object declares none of the core request and answer\n// fields and `validateUIMessages` strips unknown ones, so a host streams or\n// persists them inside the opaque `approvalDescriptor`. Only those fields are\n// read from it: a descriptor cannot approve its own request.\nconst readApprovalDescriptor = (\n descriptor: unknown,\n): Record<string, unknown> => {\n if (\n !descriptor ||\n typeof descriptor !== \"object\" ||\n Array.isArray(descriptor)\n )\n return {};\n const fields: Record<string, unknown> = {};\n for (const key of APPROVAL_DESCRIPTOR_FIELDS) {\n if (Object.hasOwn(descriptor, key))\n fields[key] = (descriptor as Record<string, unknown>)[key];\n }\n return fields;\n};\n\nfunction getToolApprovalAndInterrupt(\n part: {\n approval?: Record<string, unknown> | undefined;\n },\n toolStatus: { type: string; payload?: unknown } | undefined,\n supportsRichToolApprovalResponses: boolean,\n toolApprovalResponses:\n | ReadonlyMap<string, RespondToToolApprovalOptions>\n | undefined,\n): {\n approval?: NonNullable<ToolCallMessagePart[\"approval\"]>;\n interrupt?: NonNullable<ToolCallMessagePart[\"interrupt\"]>;\n} {\n if (part.approval) {\n const approval = {\n ...readApprovalDescriptor(part.approval.descriptor),\n ...part.approval,\n };\n const response =\n typeof approval.id === \"string\" &&\n approval.approved === undefined &&\n approval.resolution !== \"cancelled\" &&\n approval.resolution !== \"expired\"\n ? toolApprovalResponses?.get(approval.id)\n : undefined;\n // The built-in AI SDK channel sends only id, approved and reason back to\n // the server, so a request shape promising any other answer would render\n // controls whose response cannot travel.\n const {\n id,\n prompt,\n approved,\n reason,\n isAutomatic,\n resolution,\n display,\n allowFreeform,\n dismissible,\n options,\n optionId,\n text,\n ...additionalApprovalFields\n } = response\n ? {\n ...approval,\n approved: response.approved,\n ...(response.reason != null && { reason: response.reason }),\n ...(response.optionId != null && { optionId: response.optionId }),\n ...(response.text != null && { text: response.text }),\n }\n : approval;\n const normalizedOptions = supportsRichToolApprovalResponses\n ? normalizeToolApprovalOptions(options)\n : undefined;\n const requestReason = additionalApprovalFields.requestReason;\n if (typeof id === \"string\")\n return {\n approval: {\n ...additionalApprovalFields,\n id,\n ...(typeof prompt === \"string\"\n ? { prompt }\n : typeof requestReason === \"string\"\n ? { prompt: requestReason }\n : {}),\n ...(typeof approved === \"boolean\" && { approved }),\n ...(typeof reason === \"string\" && { reason }),\n ...(isAutomatic === true && { isAutomatic: true }),\n ...(supportsRichToolApprovalResponses && {\n ...((display === \"decision\" ||\n display === \"select\" ||\n display === \"text\") && { display }),\n ...(typeof allowFreeform === \"boolean\" && { allowFreeform }),\n ...(typeof dismissible === \"boolean\" && { dismissible }),\n ...(normalizedOptions && { options: normalizedOptions }),\n ...(typeof optionId === \"string\" && { optionId }),\n ...(typeof text === \"string\" && { text }),\n }),\n ...((resolution === \"cancelled\" || resolution === \"expired\") && {\n resolution,\n }),\n } as NonNullable<ToolCallMessagePart[\"approval\"]>,\n };\n }\n\n if (toolStatus?.type === \"interrupt\") {\n return {\n interrupt: toolStatus.payload as NonNullable<\n ToolCallMessagePart[\"interrupt\"]\n >,\n };\n }\n\n return {};\n}\n\ntype MessageContent = Exclude<ThreadMessageLike[\"content\"], string>;\n\nconst uiPartStateToStatus = (\n state: \"streaming\" | \"done\" | undefined,\n): MessagePartStreamStatus | undefined => {\n if (state === \"streaming\") return { type: \"running\" };\n if (state === \"done\") return { type: \"complete\" };\n return undefined;\n};\n\nfunction convertParts(\n message: UIMessage,\n metadata: AISDKMessageConverterMetadata,\n): MessageContent {\n if (!message.parts || message.parts.length === 0) {\n return [];\n }\n\n const converted = message.parts\n .filter(\n (p) =>\n p.type !== \"step-start\" &&\n (message.role !== \"user\" || p.type !== \"file\"),\n )\n .map((part) => {\n if (part.type === \"text\") {\n const status = uiPartStateToStatus(part.state);\n return {\n type: \"text\",\n text: part.text,\n ...(status != null ? { status } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata: part.providerMetadata as PartProviderMetadata,\n }\n : undefined),\n } satisfies TextMessagePart;\n }\n\n if (part.type === \"reasoning\") {\n const status = uiPartStateToStatus(part.state);\n return {\n type: \"reasoning\",\n text: part.text,\n ...(status != null ? { status } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata: part.providerMetadata as PartProviderMetadata,\n }\n : undefined),\n } satisfies ReasoningMessagePart;\n }\n\n if (isToolUIPart(part)) {\n const toolName = getToolName(part);\n const toolCallId = part.toolCallId;\n const argsKeyOrderCacheKey = `${message.id}:${toolCallId}`;\n\n // A tool call that streamed complete arguments then failed schema\n // validation keeps them in `rawInput`, not `input`; reading `input`\n // alone would convert the error snapshot to `{}` and hide the input.\n const rawInput = (part.input ??\n (\"rawInput\" in part ? part.rawInput : undefined)) as\n | ReadonlyJSONObject\n | null\n | undefined;\n let args: ReadonlyJSONObject;\n if (\n rawInput != null &&\n typeof rawInput === \"object\" &&\n !Array.isArray(rawInput)\n ) {\n args = rawInput;\n metadata.toolLastInputCache?.set(argsKeyOrderCacheKey, args);\n } else {\n args = metadata.toolLastInputCache?.get(argsKeyOrderCacheKey) ?? {};\n }\n\n let result: unknown;\n let modelContent: ToolCallMessagePart[\"modelContent\"];\n let isError = false;\n\n if (part.state === \"output-available\") {\n const unwrapped = unwrapModelContentEnvelope(part.output);\n result = unwrapped.result;\n modelContent = unwrapped.modelContent;\n } else if (part.state === \"output-error\") {\n isError = true;\n result = { error: part.errorText };\n } else if (part.state === \"output-denied\") {\n isError = true;\n result = {\n error:\n (part as { approval?: { reason?: string } }).approval?.reason ||\n \"Tool approval denied\",\n };\n }\n\n let argsText: string;\n if (part.state === \"input-streaming\") {\n argsText = stableStringifyToolArgs(\n metadata.toolArgsKeyOrderCache,\n argsKeyOrderCacheKey,\n args,\n );\n // strip closing delimiters added by the AI SDK's fix-json\n argsText = stripClosingDelimiters(argsText);\n // Re-parse so args carries the partial-JSON meta that marks which\n // field is still mid-arrival, like every argsText-based runtime.\n // The key-order cache appends new keys last, so the trailing field\n // of the stripped text is the streaming frontier.\n args = parsePartialJsonObject(argsText) ?? args;\n } else {\n // A settled part is re-converted whenever its message or the converter\n // metadata changes; the text frozen on its input object skips\n // re-serializing large args while the call keeps that input. Arrival\n // order only matters while args stream, so the key-order entry is\n // released.\n const frozen =\n metadata.toolArgsTextCache?.get(args) ?? new Map<string, string>();\n const frozenText = frozen.get(argsKeyOrderCacheKey);\n if (frozenText !== undefined) {\n argsText = frozenText;\n } else {\n argsText = stableStringifyToolArgs(\n metadata.toolArgsKeyOrderCache,\n argsKeyOrderCacheKey,\n args,\n );\n metadata.toolArgsTextCache?.set(\n args,\n frozen.set(argsKeyOrderCacheKey, argsText),\n );\n }\n metadata.toolArgsKeyOrderCache?.delete(argsKeyOrderCacheKey);\n if (\n part.state === \"output-available\" ||\n part.state === \"output-error\" ||\n part.state === \"output-denied\"\n ) {\n metadata.toolLastInputCache?.delete(argsKeyOrderCacheKey);\n }\n }\n\n const toolStatus = metadata.toolStatuses?.[toolCallId];\n const mcpApp = extractMcpAppMetadata(\n part,\n metadata.mcpAppMetadataCache,\n );\n const artifact = metadata.toolArtifacts?.get(toolCallId);\n const interactions = metadata.toolInteractions?.get(toolCallId);\n return {\n type: \"tool-call\",\n toolName,\n toolCallId,\n argsText,\n args,\n result,\n isError,\n ...(artifact !== undefined && { artifact }),\n ...(interactions !== undefined && {\n unstable_interactions: interactions,\n }),\n ...(part.state === \"output-available\" &&\n part.preliminary === true && { isPreliminary: true }),\n ...(modelContent !== undefined && { modelContent }),\n ...(mcpApp && { mcp: { app: mcpApp } }),\n ...(part.callProviderMetadata != null\n ? {\n providerMetadata:\n part.callProviderMetadata as PartProviderMetadata,\n }\n : undefined),\n ...getToolApprovalAndInterrupt(\n part,\n toolStatus,\n metadata.supportsRichToolApprovalResponses === true,\n metadata.toolApprovalResponses,\n ),\n } satisfies ToolCallMessagePart;\n }\n\n if (part.type === \"source-url\") {\n return {\n type: \"source\",\n sourceType: \"url\",\n id: part.sourceId,\n url: part.url,\n ...(part.title != null ? { title: part.title } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata:\n part.providerMetadata as SourceProviderMetadata,\n }\n : undefined),\n } satisfies SourceMessagePart;\n }\n\n if (part.type === \"file\") {\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType,\n ...(part.filename != null && { filename: part.filename }),\n } satisfies FileMessagePart;\n }\n\n if (part.type === \"source-document\") {\n return {\n type: \"source\",\n sourceType: \"document\",\n id: part.sourceId,\n title: part.title,\n mediaType: part.mediaType,\n ...(part.filename != null ? { filename: part.filename } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata:\n part.providerMetadata as SourceProviderMetadata,\n }\n : undefined),\n } satisfies SourceMessagePart;\n }\n\n if (part.type.startsWith(\"data-\")) {\n return {\n type: \"data\",\n name: part.type.substring(5),\n data: (part as any).data,\n } satisfies DataMessagePart;\n }\n\n if (isReasoningFileUIPart(part)) {\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType,\n } satisfies FileMessagePart;\n }\n\n if (isCustomContentUIPart(part)) {\n return {\n type: \"data\",\n name: part.kind,\n data: part.providerMetadata ?? null,\n } satisfies DataMessagePart;\n }\n\n console.warn(`Unsupported message part type: ${part.type}`);\n return null;\n })\n .filter(Boolean) as MessageContent[number][];\n\n const seenToolCallIds = new Set<string>();\n return converted.filter((part) => {\n if (part.type === \"tool-call\" && part.toolCallId != null) {\n if (seenToolCallIds.has(part.toolCallId)) return false;\n seenToolCallIds.add(part.toolCallId);\n }\n return true;\n });\n}\n\nexport const AISDKMessageConverter = unstable_createMessageConverter(\n (message: UIMessage, metadata: AISDKMessageConverterMetadata) => {\n const createdAt = new Date();\n const content = convertParts(message, metadata);\n\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt,\n content,\n attachments: message.parts\n ?.filter((p) => p.type === \"file\")\n .map((part, idx) => {\n const mediaType = part.mediaType ?? \"unknown/unknown\";\n const isImage = mediaType.startsWith(\"image/\");\n return {\n id: idx.toString(),\n type: isImage ? \"image\" : \"file\",\n name: part.filename ?? \"file\",\n content: [\n isImage\n ? {\n type: \"image\",\n image: part.url,\n filename: part.filename!,\n }\n : {\n type: \"file\",\n filename: part.filename!,\n data: part.url,\n mimeType: mediaType,\n },\n ],\n contentType: mediaType,\n status: { type: \"complete\" as const },\n };\n }),\n metadata: toThreadMetadata(message.metadata),\n };\n\n case \"system\":\n case \"assistant\": {\n const timing = metadata.messageTiming?.[message.id];\n const isOptimistic =\n message.role === \"assistant\" &&\n message.id === metadata.optimisticMessageId;\n return {\n role: message.role,\n id: message.id,\n createdAt,\n content,\n metadata: {\n ...toThreadMetadata(message.metadata),\n ...(timing && { timing }),\n ...(isOptimistic && { isOptimistic: true }),\n },\n };\n }\n\n default:\n console.warn(`Unsupported message role: ${message.role}`);\n return [];\n }\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"convertMessage.js","names":["isToolUIPart","isReasoningFileUIPart","isCustomContentUIPart","getToolName","UIMessage","createMessageConverter","unstable_createMessageConverter","useExternalMessageConverter","isMcpAppUri","ReasoningMessagePart","ToolApprovalOption","ToolCallMessagePart","TextMessagePart","DataMessagePart","PartProviderMetadata","SourceMessagePart","SourceProviderMetadata","FileMessagePart","ThreadMessageLike","McpAppMetadata","MessagePartStreamStatus","RespondToToolApprovalOptions","Unstable_ToolInteractionLog","stableStringifyToolArgs","parsePartialJsonObject","ReadonlyJSONObject","unwrapModelContentEnvelope","MessageMetadata","THREAD_METADATA_KEYS","Set","toThreadMetadata","metadata","undefined","result","Record","extra","Object","create","key","value","entries","has","keys","length","custom","AISDKMessageConverterMetadata","Metadata","toolArgsKeyOrderCache","Map","toolArgsTextCache","WeakMap","toolLastInputCache","mcpAppMetadataCache","toolArtifacts","ReadonlyMap","toolInteractions","supportsRichToolApprovalResponses","toolApprovalResponses","cancelledToolApprovalIds","ReadonlySet","cancelledStatusMessageIds","optimisticMessageId","stripClosingDelimiters","json","end","includes","slice","MCP_APP_METADATA_CACHE_MAX","extractMcpAppMetadata","part","cache","meta","callProviderMetadata","mcp","app","a","output","outMeta","_meta","ui","uiMeta","resourceUri","Array","isArray","visibility","flat","cacheKey","cached","get","delete","set","out","K","mimeType","filter","v","serverId","size","oldest","next","normalizeToolApprovalOptions","options","flatMap","option","id","kind","confirm","confirmDetails","label","description","grants","grant","title","APPROVAL_DESCRIPTOR_FIELDS","const","readApprovalDescriptor","descriptor","fields","hasOwn","getToolApprovalAndInterrupt","approval","toolStatus","type","payload","NonNullable","interrupt","rawApproval","approved","resolution","response","prompt","reason","isAutomatic","display","allowFreeform","dismissible","optionId","text","additionalApprovalFields","normalizedOptions","requestReason","MessageContent","Exclude","uiPartStateToStatus","state","convertParts","message","parts","converted","p","role","map","status","providerMetadata","toolName","toolCallId","argsKeyOrderCacheKey","rawInput","input","args","modelContent","isError","unwrapped","error","errorText","argsText","frozen","frozenText","toolStatuses","mcpApp","artifact","interactions","unstable_interactions","preliminary","isPreliminary","sourceType","sourceId","url","data","mediaType","filename","startsWith","name","substring","console","warn","Boolean","seenToolCallIds","add","AISDKMessageConverter","createdAt","Date","content","attachments","idx","isImage","toString","image","contentType","timing","messageTiming","isOptimistic","unstable_createMessageConverter"],"sources":["../../src/converters/convertMessage.ts"],"sourcesContent":["import {\n isToolUIPart,\n isReasoningFileUIPart,\n isCustomContentUIPart,\n getToolName,\n type UIMessage,\n} from \"ai\";\nimport {\n createMessageConverter as unstable_createMessageConverter,\n type useExternalMessageConverter,\n} from \"@assistant-ui/core/react\";\nimport {\n isMcpAppUri,\n type ReasoningMessagePart,\n type ToolApprovalOption,\n type ToolCallMessagePart,\n type TextMessagePart,\n type DataMessagePart,\n type PartProviderMetadata,\n type SourceMessagePart,\n type SourceProviderMetadata,\n type FileMessagePart,\n type ThreadMessageLike,\n type McpAppMetadata,\n type MessagePartStreamStatus,\n type RespondToToolApprovalOptions,\n type Unstable_ToolInteractionLog,\n} from \"@assistant-ui/core\";\nimport { stableStringifyToolArgs } from \"@assistant-ui/core/internal\";\nimport {\n parsePartialJsonObject,\n type ReadonlyJSONObject,\n} from \"assistant-stream/utils\";\nimport { unwrapModelContentEnvelope } from \"./modelContentEnvelope\";\n\ntype MessageMetadata = ThreadMessageLike[\"metadata\"];\n\nconst THREAD_METADATA_KEYS = new Set([\n \"unstable_state\",\n \"unstable_annotations\",\n \"unstable_data\",\n \"steps\",\n \"timing\",\n \"submittedFeedback\",\n \"isOptimistic\",\n \"modality\",\n \"custom\",\n]);\n\nconst toThreadMetadata = (metadata: unknown): MessageMetadata => {\n if (!metadata || typeof metadata !== \"object\") return undefined;\n const result: Record<string, unknown> = {};\n const extra = Object.create(null) as Record<string, unknown>;\n for (const [key, value] of Object.entries(metadata)) {\n (THREAD_METADATA_KEYS.has(key) ? result : extra)[key] = value;\n }\n if (Object.keys(extra).length > 0) {\n result.custom = { ...extra, ...(result.custom as object | undefined) };\n }\n return result as MessageMetadata;\n};\nexport type AISDKMessageConverterMetadata =\n useExternalMessageConverter.Metadata & {\n toolArgsKeyOrderCache?: Map<string, Map<string, string[]>>;\n /**\n * Frozen `argsText` keyed weakly by a settled tool call's input object, then\n * by call, since the text carries the call's streamed key order. A known\n * call/input pair skips serialization; the entries become collectible once\n * the input is unreachable. A fresh input object re-serializes in its own\n * deterministic key order.\n */\n toolArgsTextCache?: WeakMap<ReadonlyJSONObject, Map<string, string>>;\n toolLastInputCache?: Map<string, ReadonlyJSONObject>;\n mcpAppMetadataCache?: Map<string, McpAppMetadata>;\n toolArtifacts?: ReadonlyMap<string, unknown>;\n toolInteractions?: ReadonlyMap<string, Unstable_ToolInteractionLog>;\n supportsRichToolApprovalResponses?: boolean;\n toolApprovalResponses?: ReadonlyMap<string, RespondToToolApprovalOptions>;\n cancelledToolApprovalIds?: ReadonlySet<string>;\n cancelledStatusMessageIds?: ReadonlySet<string>;\n /** Id of the currently-streaming message, flagged optimistic (#4037). */\n optimisticMessageId?: string | undefined;\n };\n\nfunction stripClosingDelimiters(json: string): string {\n let end = json.length;\n while (end > 0 && '}]\"'.includes(json[end - 1]!)) end--;\n return json.slice(0, end);\n}\n\nconst MCP_APP_METADATA_CACHE_MAX = 100;\n\nfunction extractMcpAppMetadata(\n part: unknown,\n cache: Map<string, McpAppMetadata> | undefined,\n): McpAppMetadata | undefined {\n if (!part || typeof part !== \"object\") return undefined;\n const meta = (part as { callProviderMetadata?: unknown })\n .callProviderMetadata;\n const mcp =\n meta && typeof meta === \"object\"\n ? (meta as { mcp?: unknown }).mcp\n : undefined;\n const app =\n mcp && typeof mcp === \"object\" ? (mcp as { app?: unknown }).app : undefined;\n let a: Record<string, unknown>;\n if (app && typeof app === \"object\") {\n a = app as Record<string, unknown>;\n } else {\n // MCP-UI tools surface the pointer on result._meta: canonical nested\n // `ui.resourceUri`, or the deprecated flat `\"ui/resourceUri\"` key.\n const output = (part as { output?: unknown }).output;\n const outMeta =\n output && typeof output === \"object\"\n ? (output as { _meta?: unknown })._meta\n : undefined;\n const ui =\n outMeta && typeof outMeta === \"object\"\n ? (outMeta as Record<string, unknown>)[\"ui\"]\n : undefined;\n if (\n ui &&\n typeof ui === \"object\" &&\n typeof (ui as Record<string, unknown>)[\"resourceUri\"] === \"string\" &&\n isMcpAppUri((ui as Record<string, unknown>)[\"resourceUri\"] as string)\n ) {\n // Only the spec'd ui fields cross from the result body; serverId is a\n // routing key and stays transport-derived via callProviderMetadata.\n const uiMeta = ui as Record<string, unknown>;\n a = {\n resourceUri: uiMeta[\"resourceUri\"],\n ...(Array.isArray(uiMeta[\"visibility\"])\n ? { visibility: uiMeta[\"visibility\"] }\n : {}),\n };\n } else {\n const flat =\n outMeta && typeof outMeta === \"object\"\n ? (outMeta as Record<string, unknown>)[\"ui/resourceUri\"]\n : undefined;\n if (typeof flat !== \"string\" || !isMcpAppUri(flat)) return undefined;\n a = { resourceUri: flat };\n }\n }\n if (typeof a[\"resourceUri\"] !== \"string\") return undefined;\n if (!isMcpAppUri(a[\"resourceUri\"])) return undefined;\n const cacheKey = `${typeof a[\"serverId\"] === \"string\" ? a[\"serverId\"] : \"\"} ${a[\"resourceUri\"]}`;\n const cached = cache?.get(cacheKey);\n if (cached) {\n cache!.delete(cacheKey);\n cache!.set(cacheKey, cached);\n return cached;\n }\n const out: { -readonly [K in keyof McpAppMetadata]: McpAppMetadata[K] } = {\n resourceUri: a[\"resourceUri\"],\n };\n if (typeof a[\"mimeType\"] === \"string\") out.mimeType = a[\"mimeType\"];\n if (Array.isArray(a[\"visibility\"])) {\n out.visibility = a[\"visibility\"].filter(\n (v): v is \"model\" | \"app\" => v === \"model\" || v === \"app\",\n );\n }\n if (typeof a[\"serverId\"] === \"string\" && a[\"serverId\"].length > 0)\n out.serverId = a[\"serverId\"];\n if (cache) {\n if (cache.size >= MCP_APP_METADATA_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n if (oldest !== undefined) cache.delete(oldest);\n }\n cache.set(cacheKey, out);\n }\n return out;\n}\n\nconst normalizeToolApprovalOptions = (\n options: unknown,\n): readonly ToolApprovalOption[] | undefined => {\n if (!Array.isArray(options)) return undefined;\n\n return options.flatMap<ToolApprovalOption>((value) => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return [];\n const option = value as Record<string, unknown>;\n if (typeof option.id !== \"string\" || typeof option.kind !== \"string\")\n return [];\n\n const confirm = option.confirm;\n const confirmDetails =\n confirm && typeof confirm === \"object\" && !Array.isArray(confirm)\n ? (confirm as Record<string, unknown>)\n : undefined;\n\n return [\n {\n id: option.id,\n kind: option.kind,\n ...(typeof option.label === \"string\" && { label: option.label }),\n ...(typeof option.description === \"string\" && {\n description: option.description,\n }),\n ...(Array.isArray(option.grants) && {\n grants: option.grants.filter(\n (grant): grant is string => typeof grant === \"string\",\n ),\n }),\n ...(typeof confirm === \"boolean\"\n ? { confirm }\n : confirmDetails\n ? {\n confirm: {\n ...(typeof confirmDetails.title === \"string\" && {\n title: confirmDetails.title,\n }),\n ...(typeof confirmDetails.description === \"string\" && {\n description: confirmDetails.description,\n }),\n },\n }\n : {}),\n },\n ];\n });\n};\n\nconst APPROVAL_DESCRIPTOR_FIELDS = [\n \"prompt\",\n \"display\",\n \"allowFreeform\",\n \"dismissible\",\n \"options\",\n \"optionId\",\n \"text\",\n \"resolution\",\n] as const;\n\n// The AI SDK's approval object declares none of the core request and answer\n// fields and `validateUIMessages` strips unknown ones, so a host streams or\n// persists them inside the opaque `approvalDescriptor`. Only those fields are\n// read from it: a descriptor cannot approve its own request.\nconst readApprovalDescriptor = (\n descriptor: unknown,\n): Record<string, unknown> => {\n if (\n !descriptor ||\n typeof descriptor !== \"object\" ||\n Array.isArray(descriptor)\n )\n return {};\n const fields: Record<string, unknown> = {};\n for (const key of APPROVAL_DESCRIPTOR_FIELDS) {\n if (Object.hasOwn(descriptor, key))\n fields[key] = (descriptor as Record<string, unknown>)[key];\n }\n return fields;\n};\n\nfunction getToolApprovalAndInterrupt(\n part: {\n approval?: Record<string, unknown> | undefined;\n },\n toolStatus: { type: string; payload?: unknown } | undefined,\n supportsRichToolApprovalResponses: boolean,\n toolApprovalResponses:\n | ReadonlyMap<string, RespondToToolApprovalOptions>\n | undefined,\n cancelledToolApprovalIds: ReadonlySet<string> | undefined,\n): {\n approval?: NonNullable<ToolCallMessagePart[\"approval\"]>;\n interrupt?: NonNullable<ToolCallMessagePart[\"interrupt\"]>;\n} {\n if (part.approval) {\n const rawApproval = {\n ...readApprovalDescriptor(part.approval.descriptor),\n ...part.approval,\n };\n const approval =\n typeof rawApproval.id === \"string\" &&\n rawApproval.approved === undefined &&\n rawApproval.resolution === undefined &&\n cancelledToolApprovalIds?.has(rawApproval.id)\n ? { ...rawApproval, resolution: \"cancelled\" as const }\n : rawApproval;\n const response =\n typeof approval.id === \"string\" &&\n approval.approved === undefined &&\n approval.resolution !== \"cancelled\" &&\n approval.resolution !== \"expired\"\n ? toolApprovalResponses?.get(approval.id)\n : undefined;\n // The built-in AI SDK channel sends only id, approved and reason back to\n // the server, so a request shape promising any other answer would render\n // controls whose response cannot travel.\n const {\n id,\n prompt,\n approved,\n reason,\n isAutomatic,\n resolution,\n display,\n allowFreeform,\n dismissible,\n options,\n optionId,\n text,\n ...additionalApprovalFields\n } = response\n ? {\n ...approval,\n approved: response.approved,\n ...(response.reason != null && { reason: response.reason }),\n ...(response.optionId != null && { optionId: response.optionId }),\n ...(response.text != null && { text: response.text }),\n }\n : approval;\n const normalizedOptions = supportsRichToolApprovalResponses\n ? normalizeToolApprovalOptions(options)\n : undefined;\n const requestReason = additionalApprovalFields.requestReason;\n if (typeof id === \"string\")\n return {\n approval: {\n ...additionalApprovalFields,\n id,\n ...(typeof prompt === \"string\"\n ? { prompt }\n : typeof requestReason === \"string\"\n ? { prompt: requestReason }\n : {}),\n ...(typeof approved === \"boolean\" && { approved }),\n ...(typeof reason === \"string\" && { reason }),\n ...(isAutomatic === true && { isAutomatic: true }),\n ...(supportsRichToolApprovalResponses && {\n ...((display === \"decision\" ||\n display === \"select\" ||\n display === \"text\") && { display }),\n ...(typeof allowFreeform === \"boolean\" && { allowFreeform }),\n ...(typeof dismissible === \"boolean\" && { dismissible }),\n ...(normalizedOptions && { options: normalizedOptions }),\n ...(typeof optionId === \"string\" && { optionId }),\n ...(typeof text === \"string\" && { text }),\n }),\n ...((resolution === \"cancelled\" || resolution === \"expired\") && {\n resolution,\n }),\n } as NonNullable<ToolCallMessagePart[\"approval\"]>,\n };\n }\n\n if (toolStatus?.type === \"interrupt\") {\n return {\n interrupt: toolStatus.payload as NonNullable<\n ToolCallMessagePart[\"interrupt\"]\n >,\n };\n }\n\n return {};\n}\n\ntype MessageContent = Exclude<ThreadMessageLike[\"content\"], string>;\n\nconst uiPartStateToStatus = (\n state: \"streaming\" | \"done\" | undefined,\n): MessagePartStreamStatus | undefined => {\n if (state === \"streaming\") return { type: \"running\" };\n if (state === \"done\") return { type: \"complete\" };\n return undefined;\n};\n\nfunction convertParts(\n message: UIMessage,\n metadata: AISDKMessageConverterMetadata,\n): MessageContent {\n if (!message.parts || message.parts.length === 0) {\n return [];\n }\n\n const converted = message.parts\n .filter(\n (p) =>\n p.type !== \"step-start\" &&\n (message.role !== \"user\" || p.type !== \"file\"),\n )\n .map((part) => {\n if (part.type === \"text\") {\n const status = uiPartStateToStatus(part.state);\n return {\n type: \"text\",\n text: part.text,\n ...(status != null ? { status } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata: part.providerMetadata as PartProviderMetadata,\n }\n : undefined),\n } satisfies TextMessagePart;\n }\n\n if (part.type === \"reasoning\") {\n const status = uiPartStateToStatus(part.state);\n return {\n type: \"reasoning\",\n text: part.text,\n ...(status != null ? { status } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata: part.providerMetadata as PartProviderMetadata,\n }\n : undefined),\n } satisfies ReasoningMessagePart;\n }\n\n if (isToolUIPart(part)) {\n const toolName = getToolName(part);\n const toolCallId = part.toolCallId;\n const argsKeyOrderCacheKey = `${message.id}:${toolCallId}`;\n\n // A tool call that streamed complete arguments then failed schema\n // validation keeps them in `rawInput`, not `input`; reading `input`\n // alone would convert the error snapshot to `{}` and hide the input.\n const rawInput = (part.input ??\n (\"rawInput\" in part ? part.rawInput : undefined)) as\n | ReadonlyJSONObject\n | null\n | undefined;\n let args: ReadonlyJSONObject;\n if (\n rawInput != null &&\n typeof rawInput === \"object\" &&\n !Array.isArray(rawInput)\n ) {\n args = rawInput;\n metadata.toolLastInputCache?.set(argsKeyOrderCacheKey, args);\n } else {\n args = metadata.toolLastInputCache?.get(argsKeyOrderCacheKey) ?? {};\n }\n\n let result: unknown;\n let modelContent: ToolCallMessagePart[\"modelContent\"];\n let isError = false;\n\n if (part.state === \"output-available\") {\n const unwrapped = unwrapModelContentEnvelope(part.output);\n result = unwrapped.result;\n modelContent = unwrapped.modelContent;\n } else if (part.state === \"output-error\") {\n isError = true;\n result = { error: part.errorText };\n } else if (part.state === \"output-denied\") {\n isError = true;\n result = {\n error:\n (part as { approval?: { reason?: string } }).approval?.reason ||\n \"Tool approval denied\",\n };\n }\n\n let argsText: string;\n if (part.state === \"input-streaming\") {\n argsText = stableStringifyToolArgs(\n metadata.toolArgsKeyOrderCache,\n argsKeyOrderCacheKey,\n args,\n );\n // strip closing delimiters added by the AI SDK's fix-json\n argsText = stripClosingDelimiters(argsText);\n // Re-parse so args carries the partial-JSON meta that marks which\n // field is still mid-arrival, like every argsText-based runtime.\n // The key-order cache appends new keys last, so the trailing field\n // of the stripped text is the streaming frontier.\n args = parsePartialJsonObject(argsText) ?? args;\n } else {\n // A settled part is re-converted whenever its message or the converter\n // metadata changes; the text frozen on its input object skips\n // re-serializing large args while the call keeps that input. Arrival\n // order only matters while args stream, so the key-order entry is\n // released.\n const frozen =\n metadata.toolArgsTextCache?.get(args) ?? new Map<string, string>();\n const frozenText = frozen.get(argsKeyOrderCacheKey);\n if (frozenText !== undefined) {\n argsText = frozenText;\n } else {\n argsText = stableStringifyToolArgs(\n metadata.toolArgsKeyOrderCache,\n argsKeyOrderCacheKey,\n args,\n );\n metadata.toolArgsTextCache?.set(\n args,\n frozen.set(argsKeyOrderCacheKey, argsText),\n );\n }\n metadata.toolArgsKeyOrderCache?.delete(argsKeyOrderCacheKey);\n if (\n part.state === \"output-available\" ||\n part.state === \"output-error\" ||\n part.state === \"output-denied\"\n ) {\n metadata.toolLastInputCache?.delete(argsKeyOrderCacheKey);\n }\n }\n\n const toolStatus = metadata.toolStatuses?.[toolCallId];\n const mcpApp = extractMcpAppMetadata(\n part,\n metadata.mcpAppMetadataCache,\n );\n const artifact = metadata.toolArtifacts?.get(toolCallId);\n const interactions = metadata.toolInteractions?.get(toolCallId);\n return {\n type: \"tool-call\",\n toolName,\n toolCallId,\n argsText,\n args,\n result,\n isError,\n ...(artifact !== undefined && { artifact }),\n ...(interactions !== undefined && {\n unstable_interactions: interactions,\n }),\n ...(part.state === \"output-available\" &&\n part.preliminary === true && { isPreliminary: true }),\n ...(modelContent !== undefined && { modelContent }),\n ...(mcpApp && { mcp: { app: mcpApp } }),\n ...(part.callProviderMetadata != null\n ? {\n providerMetadata:\n part.callProviderMetadata as PartProviderMetadata,\n }\n : undefined),\n ...getToolApprovalAndInterrupt(\n part,\n toolStatus,\n metadata.supportsRichToolApprovalResponses === true,\n metadata.toolApprovalResponses,\n metadata.cancelledToolApprovalIds,\n ),\n } satisfies ToolCallMessagePart;\n }\n\n if (part.type === \"source-url\") {\n return {\n type: \"source\",\n sourceType: \"url\",\n id: part.sourceId,\n url: part.url,\n ...(part.title != null ? { title: part.title } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata:\n part.providerMetadata as SourceProviderMetadata,\n }\n : undefined),\n } satisfies SourceMessagePart;\n }\n\n if (part.type === \"file\") {\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType,\n ...(part.filename != null && { filename: part.filename }),\n } satisfies FileMessagePart;\n }\n\n if (part.type === \"source-document\") {\n return {\n type: \"source\",\n sourceType: \"document\",\n id: part.sourceId,\n title: part.title,\n mediaType: part.mediaType,\n ...(part.filename != null ? { filename: part.filename } : undefined),\n ...(part.providerMetadata != null\n ? {\n providerMetadata:\n part.providerMetadata as SourceProviderMetadata,\n }\n : undefined),\n } satisfies SourceMessagePart;\n }\n\n if (part.type.startsWith(\"data-\")) {\n return {\n type: \"data\",\n ...(\"id\" in part && typeof part.id === \"string\"\n ? { id: part.id }\n : undefined),\n name: part.type.substring(5),\n data: (part as any).data,\n } satisfies DataMessagePart;\n }\n\n if (isReasoningFileUIPart(part)) {\n return {\n type: \"file\",\n data: part.url,\n mimeType: part.mediaType,\n } satisfies FileMessagePart;\n }\n\n if (isCustomContentUIPart(part)) {\n return {\n type: \"data\",\n name: part.kind,\n data: part.providerMetadata ?? null,\n } satisfies DataMessagePart;\n }\n\n console.warn(`Unsupported message part type: ${part.type}`);\n return null;\n })\n .filter(Boolean) as MessageContent[number][];\n\n const seenToolCallIds = new Set<string>();\n return converted.filter((part) => {\n if (part.type === \"tool-call\" && part.toolCallId != null) {\n if (seenToolCallIds.has(part.toolCallId)) return false;\n seenToolCallIds.add(part.toolCallId);\n }\n return true;\n });\n}\n\nexport const AISDKMessageConverter = unstable_createMessageConverter(\n (message: UIMessage, metadata: AISDKMessageConverterMetadata) => {\n const createdAt = new Date();\n const content = convertParts(message, metadata);\n\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt,\n content,\n attachments: message.parts\n ?.filter((p) => p.type === \"file\")\n .map((part, idx) => {\n const mediaType = part.mediaType ?? \"unknown/unknown\";\n const isImage = mediaType.startsWith(\"image/\");\n return {\n id: idx.toString(),\n type: isImage ? \"image\" : \"file\",\n name: part.filename ?? \"file\",\n content: [\n isImage\n ? {\n type: \"image\",\n image: part.url,\n filename: part.filename!,\n }\n : {\n type: \"file\",\n filename: part.filename!,\n data: part.url,\n mimeType: mediaType,\n },\n ],\n contentType: mediaType,\n status: { type: \"complete\" as const },\n };\n }),\n metadata: toThreadMetadata(message.metadata),\n };\n\n case \"system\":\n case \"assistant\": {\n const timing = metadata.messageTiming?.[message.id];\n const isOptimistic =\n message.role === \"assistant\" &&\n message.id === metadata.optimisticMessageId;\n return {\n role: message.role,\n id: message.id,\n createdAt,\n content,\n ...(message.role === \"assistant\" &&\n metadata.cancelledStatusMessageIds?.has(message.id)\n ? {\n status: {\n type: \"incomplete\" as const,\n reason: \"cancelled\" as const,\n },\n }\n : undefined),\n metadata: {\n ...toThreadMetadata(message.metadata),\n ...(timing && { timing }),\n ...(isOptimistic && { isOptimistic: true }),\n },\n };\n }\n\n default:\n console.warn(`Unsupported message role: ${message.role}`);\n return [];\n }\n },\n);\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"toCreateMessage.d.ts","sourceRoot":"","sources":["../../src/converters/toCreateMessage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAOxD,OAAO,KAAK,EACV,eAAe,EAEf,SAAS,EAGV,MAAM,IAAI,CAAC;AAOZ,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,SAAS,aAAa,KACrB,eAAe,CAAC,UAAU,CA6E5B,CAAC"}
1
+ {"version":3,"file":"toCreateMessage.d.ts","sourceRoot":"","sources":["../../src/converters/toCreateMessage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAOxD,OAAO,KAAK,EACV,eAAe,EAEf,SAAS,EAGV,MAAM,IAAI,CAAC;AAOZ,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,SAAS,aAAa,KACrB,eAAe,CAAC,UAAU,CA8E5B,CAAC"}
@@ -45,7 +45,8 @@ const toCreateMessage = (message) => {
45
45
  }
46
46
  case "data": return {
47
47
  type: `data-${part.name}`,
48
- data: part.data
48
+ data: part.data,
49
+ ...part.id !== void 0 && { id: part.id }
49
50
  };
50
51
  default: throw new Error(`Unsupported part type: ${part.type}`);
51
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toCreateMessage.js","names":["AppendMessage","resolveFileMediaType","resolveFilePartSource","resolveImageMediaType","toMediaWireUrl","CreateUIMessage","UIDataTypes","UIMessage","UIMessagePart","UITools","InputPart","contentType","filename","toCreateMessage","message","UI_MESSAGE","inputParts","content","attachments","flatMap","a","map","c","name","parts","part","type","text","mediaType","image","url","data","mimeType","sourceType","audio","format","source","kind","Error","role","metadata"],"sources":["../../src/converters/toCreateMessage.ts"],"sourcesContent":["import type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n resolveFileMediaType,\n resolveFilePartSource,\n resolveImageMediaType,\n toMediaWireUrl,\n} from \"@assistant-ui/core/internal\";\nimport type {\n CreateUIMessage,\n UIDataTypes,\n UIMessage,\n UIMessagePart,\n UITools,\n} from \"ai\";\n\ntype InputPart = AppendMessage[\"content\"][number] & {\n readonly contentType?: string | undefined;\n readonly filename?: string | undefined;\n};\n\nexport const toCreateMessage = <UI_MESSAGE extends UIMessage = UIMessage>(\n message: AppendMessage,\n): CreateUIMessage<UI_MESSAGE> => {\n const inputParts: InputPart[] = [\n ...message.content,\n ...(message.attachments?.flatMap((a) =>\n a.content.map((c) => ({\n ...c,\n filename: a.name,\n contentType: a.contentType,\n })),\n ) ?? []),\n ];\n\n const parts = inputParts.map((part): UIMessagePart<UIDataTypes, UITools> => {\n switch (part.type) {\n case \"text\":\n return {\n type: \"text\",\n text: part.text,\n };\n case \"image\": {\n const mediaType = resolveImageMediaType(part.image, part.contentType);\n return {\n type: \"file\",\n url: toMediaWireUrl(part.image, mediaType),\n ...(part.filename && { filename: part.filename }),\n mediaType,\n };\n }\n case \"file\": {\n // `mimeType` is a plain string, and an adapter reading `file.type` on a\n // file the OS cannot type yields \"\". Same ladder as images: declared,\n // then the envelope, then the floor.\n const mediaType = resolveFileMediaType(part.data, part.mimeType);\n return {\n type: \"file\",\n // An `id` reference is an opaque provider handle, not base64, and\n // this adapter has no way to send one. Left unwrapped so it fails\n // loudly upstream rather than shipping a corrupt payload.\n url:\n part.sourceType === \"id\"\n ? part.data\n : toMediaWireUrl(part.data, mediaType),\n mediaType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"audio\": {\n // A data URL's own media type wins over `mediaType` downstream, so the\n // envelope is rebuilt from the typed format rather than forwarded.\n const mediaType = `audio/${part.audio.format}`;\n const data = part.audio.data;\n const source = resolveFilePartSource({ data, mimeType: mediaType });\n return {\n type: \"file\",\n url:\n source.kind === \"url\"\n ? source.url\n : `data:${mediaType};base64,${source.data}`,\n mediaType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"data\":\n return {\n type: `data-${part.name}`,\n data: part.data,\n };\n default:\n throw new Error(`Unsupported part type: ${part.type}`);\n }\n });\n\n return {\n role: message.role,\n parts,\n metadata: message.metadata,\n } satisfies CreateUIMessage<UIMessage> as CreateUIMessage<UI_MESSAGE>;\n};\n"],"mappings":";;AAoBA,MAAaa,mBACXC,YACgC;CAYhC,MAAMU,QAAQR,CAVZ,GAAGF,QAAQG,SACX,GAAIH,QAAQI,aAAaC,SAASC,MAChCA,EAAEH,QAAQI,KAAKC,OAAO;EACpB,GAAGA;EACHV,UAAUQ,EAAEG;EACZZ,aAAaS,EAAET;CACjB,EAAE,CACJ,KAAK,CAAA,CAGOK,CAAU,CAACK,KAAKI,SAA8C;EAC1E,QAAQA,KAAKC,MAAb;GACE,KAAK,QACH,OAAO;IACLA,MAAM;IACNC,MAAMF,KAAKE;GACb;GACF,KAAK,SAAS;IACZ,MAAMC,YAAYzB,sBAAsBsB,KAAKI,OAAOJ,KAAKd,WAAW;IACpE,OAAO;KACLe,MAAM;KACNI,KAAK1B,eAAeqB,KAAKI,OAAOD,SAAS;KACzC,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;KAC/CgB;IACF;GACF;GACA,KAAK,QAAQ;IAIX,MAAMA,YAAY3B,qBAAqBwB,KAAKM,MAAMN,KAAKO,QAAQ;IAC/D,OAAO;KACLN,MAAM;KAINI,KACEL,KAAKQ,eAAe,OAChBR,KAAKM,OACL3B,eAAeqB,KAAKM,MAAMH,SAAS;KACzCA;KACA,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;IACjD;GACF;GACA,KAAK,SAAS;IAGZ,MAAMgB,YAAY,SAASH,KAAKS,MAAMC;IACtC,MAAMJ,OAAON,KAAKS,MAAMH;IACxB,MAAMK,SAASlC,sBAAsB;KAAE6B;KAAMC,UAAUJ;IAAU,CAAC;IAClE,OAAO;KACLF,MAAM;KACNI,KACEM,OAAOC,SAAS,QACZD,OAAON,MACP,QAAQF,UAAS,UAAWQ,OAAOL;KACzCH;KACA,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;IACjD;GACF;GACA,KAAK,QACH,OAAO;IACLc,MAAM,QAAQD,KAAKF;IACnBQ,MAAMN,KAAKM;GACb;GACF,SACE,MAAM,IAAIO,MAAM,0BAA0Bb,KAAKC,MAAM;EACzD;CACF,CAAC;CAED,OAAO;EACLa,MAAMzB,QAAQyB;EACdf;EACAgB,UAAU1B,QAAQ0B;CACpB;AACF"}
1
+ {"version":3,"file":"toCreateMessage.js","names":["AppendMessage","resolveFileMediaType","resolveFilePartSource","resolveImageMediaType","toMediaWireUrl","CreateUIMessage","UIDataTypes","UIMessage","UIMessagePart","UITools","InputPart","contentType","filename","toCreateMessage","message","UI_MESSAGE","inputParts","content","attachments","flatMap","a","map","c","name","parts","part","type","text","mediaType","image","url","data","mimeType","sourceType","audio","format","source","kind","id","undefined","Error","role","metadata"],"sources":["../../src/converters/toCreateMessage.ts"],"sourcesContent":["import type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n resolveFileMediaType,\n resolveFilePartSource,\n resolveImageMediaType,\n toMediaWireUrl,\n} from \"@assistant-ui/core/internal\";\nimport type {\n CreateUIMessage,\n UIDataTypes,\n UIMessage,\n UIMessagePart,\n UITools,\n} from \"ai\";\n\ntype InputPart = AppendMessage[\"content\"][number] & {\n readonly contentType?: string | undefined;\n readonly filename?: string | undefined;\n};\n\nexport const toCreateMessage = <UI_MESSAGE extends UIMessage = UIMessage>(\n message: AppendMessage,\n): CreateUIMessage<UI_MESSAGE> => {\n const inputParts: InputPart[] = [\n ...message.content,\n ...(message.attachments?.flatMap((a) =>\n a.content.map((c) => ({\n ...c,\n filename: a.name,\n contentType: a.contentType,\n })),\n ) ?? []),\n ];\n\n const parts = inputParts.map((part): UIMessagePart<UIDataTypes, UITools> => {\n switch (part.type) {\n case \"text\":\n return {\n type: \"text\",\n text: part.text,\n };\n case \"image\": {\n const mediaType = resolveImageMediaType(part.image, part.contentType);\n return {\n type: \"file\",\n url: toMediaWireUrl(part.image, mediaType),\n ...(part.filename && { filename: part.filename }),\n mediaType,\n };\n }\n case \"file\": {\n // `mimeType` is a plain string, and an adapter reading `file.type` on a\n // file the OS cannot type yields \"\". Same ladder as images: declared,\n // then the envelope, then the floor.\n const mediaType = resolveFileMediaType(part.data, part.mimeType);\n return {\n type: \"file\",\n // An `id` reference is an opaque provider handle, not base64, and\n // this adapter has no way to send one. Left unwrapped so it fails\n // loudly upstream rather than shipping a corrupt payload.\n url:\n part.sourceType === \"id\"\n ? part.data\n : toMediaWireUrl(part.data, mediaType),\n mediaType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"audio\": {\n // A data URL's own media type wins over `mediaType` downstream, so the\n // envelope is rebuilt from the typed format rather than forwarded.\n const mediaType = `audio/${part.audio.format}`;\n const data = part.audio.data;\n const source = resolveFilePartSource({ data, mimeType: mediaType });\n return {\n type: \"file\",\n url:\n source.kind === \"url\"\n ? source.url\n : `data:${mediaType};base64,${source.data}`,\n mediaType,\n ...(part.filename && { filename: part.filename }),\n };\n }\n case \"data\":\n return {\n type: `data-${part.name}`,\n data: part.data,\n ...(part.id !== undefined && { id: part.id }),\n };\n default:\n throw new Error(`Unsupported part type: ${part.type}`);\n }\n });\n\n return {\n role: message.role,\n parts,\n metadata: message.metadata,\n } satisfies CreateUIMessage<UIMessage> as CreateUIMessage<UI_MESSAGE>;\n};\n"],"mappings":";;AAoBA,MAAaa,mBACXC,YACgC;CAYhC,MAAMU,QAAQR,CAVZ,GAAGF,QAAQG,SACX,GAAIH,QAAQI,aAAaC,SAASC,MAChCA,EAAEH,QAAQI,KAAKC,OAAO;EACpB,GAAGA;EACHV,UAAUQ,EAAEG;EACZZ,aAAaS,EAAET;CACjB,EAAE,CACJ,KAAK,CAAA,CAGOK,CAAU,CAACK,KAAKI,SAA8C;EAC1E,QAAQA,KAAKC,MAAb;GACE,KAAK,QACH,OAAO;IACLA,MAAM;IACNC,MAAMF,KAAKE;GACb;GACF,KAAK,SAAS;IACZ,MAAMC,YAAYzB,sBAAsBsB,KAAKI,OAAOJ,KAAKd,WAAW;IACpE,OAAO;KACLe,MAAM;KACNI,KAAK1B,eAAeqB,KAAKI,OAAOD,SAAS;KACzC,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;KAC/CgB;IACF;GACF;GACA,KAAK,QAAQ;IAIX,MAAMA,YAAY3B,qBAAqBwB,KAAKM,MAAMN,KAAKO,QAAQ;IAC/D,OAAO;KACLN,MAAM;KAINI,KACEL,KAAKQ,eAAe,OAChBR,KAAKM,OACL3B,eAAeqB,KAAKM,MAAMH,SAAS;KACzCA;KACA,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;IACjD;GACF;GACA,KAAK,SAAS;IAGZ,MAAMgB,YAAY,SAASH,KAAKS,MAAMC;IACtC,MAAMJ,OAAON,KAAKS,MAAMH;IACxB,MAAMK,SAASlC,sBAAsB;KAAE6B;KAAMC,UAAUJ;IAAU,CAAC;IAClE,OAAO;KACLF,MAAM;KACNI,KACEM,OAAOC,SAAS,QACZD,OAAON,MACP,QAAQF,UAAS,UAAWQ,OAAOL;KACzCH;KACA,GAAIH,KAAKb,YAAY,EAAEA,UAAUa,KAAKb,SAAS;IACjD;GACF;GACA,KAAK,QACH,OAAO;IACLc,MAAM,QAAQD,KAAKF;IACnBQ,MAAMN,KAAKM;IACX,GAAIN,KAAKa,OAAOC,KAAAA,KAAa,EAAED,IAAIb,KAAKa,GAAG;GAC7C;GACF,SACE,MAAM,IAAIE,MAAM,0BAA0Bf,KAAKC,MAAM;EACzD;CACF,CAAC;CAED,OAAO;EACLe,MAAM3B,QAAQ2B;EACdjB;EACAkB,UAAU5B,QAAQ4B;CACpB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"AISDKChat.d.ts","sourceRoot":"","sources":["../../src/runtime/AISDKChat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM/C,OAAO,EAAiB,KAAK,iBAAiB,EAAE,2BAAwB;AAExE,MAAM,MAAM,gBAAgB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACnE,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAsBhC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GA5BA,UAAU,SAAS,SAAS,gOA4BH,CAAC"}
1
+ {"version":3,"file":"AISDKChat.d.ts","sourceRoot":"","sources":["../../src/runtime/AISDKChat.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM/C,OAAO,EAAiB,KAAK,iBAAiB,EAAE,2BAAwB;AAExE,MAAM,MAAM,gBAAgB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACnE,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAkBhC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAxBA,UAAU,SAAS,SAAS,gOAwBH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AISDKChat.js","names":["c","_c","resource","useResource","useState","generateId","UIMessage","RuntimeAdapter","runtimeAdapterTransformScopes","attachTransformScopes","useChatThread","ChatThreadOptions","AISDKChatOptions","UI_MESSAGE","useAISDKChat","options","$","t0","id","t1","initialize","remoteId","externalId","undefined","threadListItem","t2","t3","isMainThread","getThreadListItem","stopOnClientDestroy","runtime","t4","AISDKChat"],"sources":["../../src/runtime/AISDKChat.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource } from \"@assistant-ui/tap\";\nimport { useState } from \"react\";\nimport { generateId } from \"ai\";\nimport type { UIMessage } from \"@ai-sdk/react\";\nimport {\n RuntimeAdapter,\n runtimeAdapterTransformScopes,\n} from \"@assistant-ui/core/store\";\nimport { attachTransformScopes } from \"@assistant-ui/store/client\";\nimport { useChatThread, type ChatThreadOptions } from \"./useChatThread\";\n\nexport type AISDKChatOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatThreadOptions<UI_MESSAGE>;\n\nconst useAISDKChat = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: AISDKChatOptions<UI_MESSAGE>,\n) => {\n const [id] = useState(() => options?.id ?? generateId());\n // The transport resolves the request id from the thread list item, falling\n // back to the runtime's main item, whose id here is the external store's\n // placeholder constant. The single thread of this entry is the chat itself,\n // so the handed-over item initializes to the chat id.\n const [threadListItem] = useState(() => ({\n initialize: async () => ({ remoteId: id, externalId: undefined }),\n }));\n const runtime = useChatThread(options, {\n id,\n isMainThread: true,\n getThreadListItem: () => threadListItem,\n stopOnClientDestroy: true,\n });\n return useResource(RuntimeAdapter(runtime));\n};\n\n/**\n * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the\n * same orchestration as `useChatRuntime` inside the client's own resource tree,\n * so it works with any `AssistantClient` host, React or not. Single thread; the\n * multi-thread and assistant-cloud surface is {@link AISDKThreads}. The chat\n * id is captured when the entry mounts, so a later `id` change in the options\n * has no effect.\n */\nexport const AISDKChat = resource(useAISDKChat);\n\nattachTransformScopes(useAISDKChat, runtimeAdapterTransformScopes);\n"],"mappings":";;;;;;;;;AAgBA,MAAMc,gBAAeC,YAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAgB;CAAA,IAAAD,EAAA,OAAAD,SAAAG,IAAA;EAGGD,WAAMF,SAAOG,MAAQb,WAAW;EAACW,EAAA,KAAAD,SAAAG;EAAAF,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAAvD,MAAA,CAAAE,MAAad,SAASa,EAAiC;CAAE,IAAAE;CAAA,IAAAH,EAAA,OAAAE,IAAA;EAKvBC,YAAO,EAAAC,YAC3B,aAAa;GAAAC,UAAYH;GAAEI,YAAcC,KAAAA;EAAU,GACjE;EAAEP,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAFF,MAAA,CAAAQ,kBAAyBpB,SAASe,EAEhC;CAAE,IAAAM;CAAA,IAAAT,EAAA,OAAAQ,gBAAA;EAIiBC,WAAMD;EAAcR,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAU;CAAA,IAAAV,EAAA,OAAAE,MAAAF,EAAA,OAAAS,IAAA;EAHFC,KAAA;GAAAR;GAAAS,cAEvB;GAAIC,mBACCH;GAAoBI,qBAClB;EACvB;EAACb,EAAA,KAAAE;EAAAF,EAAA,KAAAS;EAAAT,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CALD,MAAAc,UAAgBpB,cAAcK,SAASW,EAKtC;CAAE,IAAAK;CAAA,IAAAf,EAAA,OAAAc,SAAA;EACgBC,KAAAxB,eAAeuB,OAAO;EAACd,EAAA,KAAAc;EAAAd,EAAA,MAAAe;CAAA,OAAAA,KAAAf,EAAA;CAAA,OAAnCb,YAAY4B,EAAuB;AAAC;;;;;;;;;AAW7C,MAAaC,YAAY9B,SAASY,YAAY;AAE9CL,sBAAsBK,cAAcN,6BAA6B"}
1
+ {"version":3,"file":"AISDKChat.js","names":["c","_c","resource","useResource","useState","generateId","UIMessage","RuntimeAdapter","runtimeAdapterTransformScopes","attachTransformScopes","useChatThread","ChatThreadOptions","AISDKChatOptions","UI_MESSAGE","useAISDKChat","options","$","t0","id","t1","initialize","remoteId","externalId","undefined","threadListItem","t2","t3","isMainThread","getThreadListItem","stopOnClientDestroy","runtime","t4","AISDKChat","_c"],"sources":["../../src/runtime/AISDKChat.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource } from \"@assistant-ui/tap\";\nimport { useState } from \"react\";\nimport { generateId } from \"ai\";\nimport type { UIMessage } from \"@ai-sdk/react\";\nimport {\n RuntimeAdapter,\n runtimeAdapterTransformScopes,\n} from \"@assistant-ui/core/store\";\nimport { attachTransformScopes } from \"@assistant-ui/store/client\";\nimport { useChatThread, type ChatThreadOptions } from \"./useChatThread\";\n\nexport type AISDKChatOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatThreadOptions<UI_MESSAGE>;\n\nconst useAISDKChat = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: AISDKChatOptions<UI_MESSAGE>,\n) => {\n const [id] = useState(() => options?.id ?? generateId());\n const [threadListItem] = useState(() => ({\n initialize: async () => ({ remoteId: id, externalId: undefined }),\n }));\n const runtime = useChatThread(options, {\n id,\n isMainThread: true,\n getThreadListItem: () => threadListItem,\n stopOnClientDestroy: true,\n });\n return useResource(RuntimeAdapter(runtime));\n};\n\n/**\n * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the\n * same orchestration as `useChatRuntime` inside the client's own resource tree,\n * so it works with any `AssistantClient` host, React or not. Single thread; the\n * multi-thread and assistant-cloud surface is {@link AISDKThreads}. The chat\n * id is captured when the entry mounts, so a later `id` change in the options\n * has no effect.\n */\nexport const AISDKChat = resource(useAISDKChat);\n\nattachTransformScopes(useAISDKChat, runtimeAdapterTransformScopes);\n"],"mappings":";;;;;;;;;AAgBA,MAAMc,gBAAeC,YAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAgB;CAAA,IAAAD,EAAA,OAAAD,SAAAG,IAAA;EAGGD,WAAMF,SAAOG,MAAQb,WAAW;EAACW,EAAA,KAAAD,SAAAG;EAAAF,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAAvD,MAAA,CAAAE,MAAad,SAASa,EAAiC;CAAE,IAAAE;CAAA,IAAAH,EAAA,OAAAE,IAAA;EACvBC,YAAO,EAAAC,YAC3B,aAAa;GAAAC,UAAYH;GAAEI,YAAcC,KAAAA;EAAU,GACjE;EAAEP,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAFF,MAAA,CAAAQ,kBAAyBpB,SAASe,EAEhC;CAAE,IAAAM;CAAA,IAAAT,EAAA,OAAAQ,gBAAA;EAIiBC,WAAMD;EAAcR,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAU;CAAA,IAAAV,EAAA,OAAAE,MAAAF,EAAA,OAAAS,IAAA;EAHFC,KAAA;GAAAR;GAAAS,cAEvB;GAAIC,mBACCH;GAAoBI,qBAClB;EACvB;EAACb,EAAA,KAAAE;EAAAF,EAAA,KAAAS;EAAAT,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CALD,MAAAc,UAAgBpB,cAAcK,SAASW,EAKtC;CAAE,IAAAK;CAAA,IAAAf,EAAA,OAAAc,SAAA;EACgBC,KAAAxB,eAAeuB,OAAO;EAACd,EAAA,KAAAc;EAAAd,EAAA,MAAAe;CAAA,OAAAA,KAAAf,EAAA;CAAA,OAAnCb,YAAY4B,EAAuB;AAAC;;;;;;;;;AAW7C,MAAaC,YAAY9B,SAASY,YAAY;AAE9CL,sBAAsBK,cAAcN,6BAA6B"}
@@ -1 +1 @@
1
- {"version":3,"file":"AISDKThreads.js","names":["c","_c","resource","useResource","withKey","useEffect","useMemo","useState","Chat","UIMessage","ChatTransport","AssistantCloud","InMemoryThreadList","RemoteThreadList","inMemoryThreadListTransformScopes","ThreadClient","useCloudThreadListAdapter","attachTransformScopes","useAssistantClientRef","useAssistantScopeEffect","useAui","AssistantChatTransport","createChat","splitChatThreadOptions","useChatThread","ChatThreadOptions","MessageRepository","useResourceCleanup","AI_SDK_SDK","AISDKThreadsOptions","Omit","UI_MESSAGE","transport","cloud","threadId","onThreadIdChange","AISDKThreadChatOptions","ChatOptionsRef","current","ChatEntry","chat","repository","optionsRef","createChatEntry","options","chatInit","undefined","__internal_clone","id","getOrCreateChatEntry","chats","Map","existing","get","created","set","useAISDKChatThread","t0","$","t1","owned","t2","t3","t4","t5","stop","catch","_temp","aui","t6","initialize","remoteId","externalId","fallbackItem","t7","t8","threadListItem","source","t9","isMainThread","getThreadListItem","messageRepositoryInstance","stopOnClientDestroy","runtime","clientRef","t10","registerModelContextProvider","modelContext","t11","t12","thread","AISDKChatThread","useAISDKThreads","threadOptions","_temp2","bindCloud","values","_temp3","cloudAdapter","sdk","element","adapter","backgroundThreads","onDelete","id_0","_temp4","delete","AISDKThreads"],"sources":["../../src/runtime/AISDKThreads.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource, withKey } from \"@assistant-ui/tap\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { Chat, UIMessage } from \"@ai-sdk/react\";\nimport type { ChatTransport } from \"ai\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport {\n InMemoryThreadList,\n RemoteThreadList,\n inMemoryThreadListTransformScopes,\n} from \"@assistant-ui/core/store\";\nimport { ThreadClient } from \"@assistant-ui/core/store/internal\";\nimport { useCloudThreadListAdapter } from \"@assistant-ui/core/react\";\nimport {\n attachTransformScopes,\n useAssistantClientRef,\n useAssistantScopeEffect,\n} from \"@assistant-ui/store/client\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { AssistantChatTransport } from \"../transport/AssistantChatTransport\";\nimport {\n createChat,\n splitChatThreadOptions,\n useChatThread,\n type ChatThreadOptions,\n} from \"./useChatThread\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport { useResourceCleanup } from \"./useResourceCleanup\";\nimport { AI_SDK_SDK } from \"./sdkIdentity\";\n\nexport type AISDKThreadsOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n Omit<ChatThreadOptions<UI_MESSAGE>, \"id\" | \"transport\" | \"messages\"> & {\n /**\n * The transport threads send through. A factory is invoked once per\n * thread so each thread owns its instance. A plain\n * `AssistantChatTransport` instance is cloned per thread (its\n * assistant-ui wiring is per thread); any other transport instance is\n * shared as-is. Defaults to one `AssistantChatTransport` per thread.\n */\n transport?:\n | ChatTransport<UI_MESSAGE>\n | (() => ChatTransport<UI_MESSAGE>)\n | undefined;\n /**\n * When set, the thread list is a `RemoteThreadList` backed by this\n * assistant-cloud. Omit it to keep the in-memory list. Every visited\n * cloud thread stays mounted, so an in-flight run continues after a\n * switch and stops on delete; per-thread history loads once per thread.\n */\n cloud?: AssistantCloud | undefined;\n /**\n * Controlled thread id for the cloud list. Ignored without `cloud`.\n */\n threadId?: string | undefined;\n /**\n * Called with the settled remote id when the cloud list changes thread.\n */\n onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;\n };\n\ntype AISDKThreadChatOptions<UI_MESSAGE extends UIMessage = UIMessage> = Omit<\n AISDKThreadsOptions<UI_MESSAGE>,\n \"cloud\" | \"threadId\" | \"onThreadIdChange\"\n>;\n\ntype ChatOptionsRef<UI_MESSAGE extends UIMessage> = {\n current: AISDKThreadChatOptions<UI_MESSAGE> | undefined;\n};\n\ntype ChatEntry<UI_MESSAGE extends UIMessage> = {\n chat: Chat<UI_MESSAGE>;\n transport: ChatTransport<UI_MESSAGE>;\n repository: MessageRepository;\n optionsRef: ChatOptionsRef<UI_MESSAGE>;\n};\n\nconst createChatEntry = <UI_MESSAGE extends UIMessage>(\n threadId: string,\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined,\n): ChatEntry<UI_MESSAGE> => {\n const optionsRef: ChatOptionsRef<UI_MESSAGE> = { current: options };\n const { chatInit } = splitChatThreadOptions(\n options as ChatThreadOptions<UI_MESSAGE> | undefined,\n );\n const transport =\n typeof options?.transport === \"function\"\n ? options.transport()\n : options?.transport === undefined\n ? new AssistantChatTransport()\n : options.transport instanceof AssistantChatTransport\n ? options.transport.__internal_clone()\n : options.transport;\n return {\n chat: createChat({ ...chatInit, id: threadId, transport }, optionsRef),\n transport,\n repository: new MessageRepository(),\n optionsRef,\n };\n};\n\nconst getOrCreateChatEntry = <UI_MESSAGE extends UIMessage>(\n threadId: string,\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined,\n chats: Map<string, ChatEntry<UI_MESSAGE>>,\n): ChatEntry<UI_MESSAGE> => {\n const existing = chats.get(threadId);\n if (existing) return existing;\n const created = createChatEntry(threadId, options);\n chats.set(threadId, created);\n return created;\n};\n\nconst useAISDKChatThread = <UI_MESSAGE extends UIMessage = UIMessage>({\n threadId,\n options,\n chats,\n cloud,\n}: {\n threadId: string;\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined;\n chats: Map<string, ChatEntry<UI_MESSAGE>>;\n cloud: boolean;\n}) => {\n const [owned] = useState(() =>\n cloud ? createChatEntry(threadId, options) : undefined,\n );\n const { chat, transport, repository, optionsRef } =\n owned ?? getOrCreateChatEntry(threadId, options, chats);\n\n useEffect(() => {\n if (cloud) optionsRef.current = options;\n });\n\n useEffect(() => {\n if (!cloud) return undefined;\n return () => {\n void chat.stop().catch(() => {});\n };\n }, [chat, cloud]);\n\n const aui = useAui();\n const fallbackItem = useMemo(\n () => ({\n initialize: async () => ({\n remoteId: threadId,\n externalId: undefined,\n }),\n }),\n [threadId],\n );\n const runtime = useChatThread(\n { ...options, transport } as ChatThreadOptions<UI_MESSAGE>,\n {\n id: threadId,\n isMainThread: true,\n getThreadListItem: () =>\n cloud\n ? aui.threadListItem.source\n ? aui.threadListItem\n : undefined\n : fallbackItem,\n chat,\n messageRepositoryInstance: repository,\n stopOnClientDestroy: false,\n },\n );\n\n const clientRef = useAssistantClientRef();\n useAssistantScopeEffect(\n \"modelContext\",\n () =>\n runtime.registerModelContextProvider(clientRef.current!.modelContext()),\n [runtime],\n );\n\n return useResource(ThreadClient({ runtime: runtime.thread }));\n};\n\nconst AISDKChatThread = resource(useAISDKChatThread);\n\nconst useAISDKThreads = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: AISDKThreadsOptions<UI_MESSAGE>,\n) => {\n const { cloud, threadId, onThreadIdChange, ...threadOptions } = options ?? {};\n const [chats] = useState(() => new Map<string, ChatEntry<UI_MESSAGE>>());\n const bindCloud = cloud !== undefined;\n\n useEffect(() => {\n for (const { optionsRef } of chats.values()) {\n optionsRef.current = threadOptions;\n }\n });\n\n useResourceCleanup(true, () => {\n for (const { chat } of chats.values()) {\n void chat.stop().catch(() => {});\n }\n });\n\n const cloudAdapter = useCloudThreadListAdapter({ cloud, sdk: AI_SDK_SDK });\n const thread = (id: string) => {\n const element = AISDKChatThread({\n threadId: id,\n options: threadOptions,\n chats,\n cloud: bindCloud,\n });\n return bindCloud ? withKey(id, element) : element;\n };\n\n return useResource(\n bindCloud\n ? RemoteThreadList({\n adapter: cloudAdapter,\n backgroundThreads: true,\n thread,\n threadId,\n onThreadIdChange,\n })\n : InMemoryThreadList({\n thread,\n onDelete: (id) => {\n void chats\n .get(id)\n ?.chat.stop()\n .catch(() => {});\n chats.delete(id);\n },\n }),\n );\n};\n\n/**\n * `AuiConfig` entry that runs one AI SDK chat per thread. Hosts the same\n * per-thread orchestration as {@link AISDKChat} inside the client's own\n * resource tree, so it works with any `AssistantClient` host, React or not.\n * Without `cloud`, threads live in memory for the client's lifetime and keep\n * their history across switches; only the visible thread is mounted, and a\n * switched-away chat keeps streaming into its stored state until it settles\n * or the thread is deleted. With `cloud`, the list is a\n * `RemoteThreadList` with `backgroundThreads`: every visited thread stays\n * mounted with its own history, a run continues after a switch and stops on\n * delete, and a freshly created thread titles itself. Model context is\n * registered on every mounted thread.\n */\nexport const AISDKThreads = resource(useAISDKThreads);\n\nattachTransformScopes(useAISDKThreads, inMemoryThreadListTransformScopes);\n"],"mappings":"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"}
1
+ {"version":3,"file":"AISDKThreads.js","names":["c","_c","resource","useResource","withKey","useEffect","useMemo","useState","Chat","UIMessage","ChatTransport","AssistantCloud","InMemoryThreadList","RemoteThreadList","inMemoryThreadListTransformScopes","ThreadClient","useCloudThreadListAdapter","attachTransformScopes","useAssistantClientRef","useAssistantScopeEffect","useAui","AssistantChatTransport","createChat","splitChatThreadOptions","useChatThread","ChatThreadOptions","MessageRepository","useResourceCleanup","AI_SDK_SDK","AISDKThreadsOptions","Omit","UI_MESSAGE","transport","cloud","threadId","onThreadIdChange","AISDKThreadChatOptions","ChatOptionsRef","current","ChatEntry","chat","repository","optionsRef","createChatEntry","options","chatInit","undefined","__internal_clone","id","getOrCreateChatEntry","chats","Map","existing","get","created","set","useAISDKChatThread","t0","$","t1","owned","t2","t3","t4","t5","stop","catch","_temp","aui","t6","initialize","remoteId","externalId","fallbackItem","t7","t8","threadListItem","source","t9","isMainThread","getThreadListItem","messageRepositoryInstance","stopOnClientDestroy","runtime","clientRef","t10","registerModelContextProvider","modelContext","t11","t12","thread","AISDKChatThread","useAISDKThreads","threadOptions","_temp2","bindCloud","values","_temp3","cloudAdapter","sdk","element","adapter","backgroundThreads","onDelete","id_0","_temp4","delete","AISDKThreads","_c"],"sources":["../../src/runtime/AISDKThreads.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource, withKey } from \"@assistant-ui/tap\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport type { Chat, UIMessage } from \"@ai-sdk/react\";\nimport type { ChatTransport } from \"ai\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport {\n InMemoryThreadList,\n RemoteThreadList,\n inMemoryThreadListTransformScopes,\n} from \"@assistant-ui/core/store\";\nimport { ThreadClient } from \"@assistant-ui/core/store/internal\";\nimport { useCloudThreadListAdapter } from \"@assistant-ui/core/react\";\nimport {\n attachTransformScopes,\n useAssistantClientRef,\n useAssistantScopeEffect,\n} from \"@assistant-ui/store/client\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { AssistantChatTransport } from \"../transport/AssistantChatTransport\";\nimport {\n createChat,\n splitChatThreadOptions,\n useChatThread,\n type ChatThreadOptions,\n} from \"./useChatThread\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport { useResourceCleanup } from \"./useResourceCleanup\";\nimport { AI_SDK_SDK } from \"./sdkIdentity\";\n\nexport type AISDKThreadsOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n Omit<ChatThreadOptions<UI_MESSAGE>, \"id\" | \"transport\" | \"messages\"> & {\n /**\n * The transport threads send through. A factory is invoked once per\n * thread so each thread owns its instance. A plain\n * `AssistantChatTransport` instance is cloned per thread (its\n * assistant-ui wiring is per thread); any other transport instance is\n * shared as-is. Defaults to one `AssistantChatTransport` per thread.\n */\n transport?:\n | ChatTransport<UI_MESSAGE>\n | (() => ChatTransport<UI_MESSAGE>)\n | undefined;\n /**\n * When set, the thread list is a `RemoteThreadList` backed by this\n * assistant-cloud. Omit it to keep the in-memory list. Every visited\n * cloud thread stays mounted, so an in-flight run continues after a\n * switch and stops on delete; per-thread history loads once per thread.\n */\n cloud?: AssistantCloud | undefined;\n /**\n * Controlled thread id for the cloud list. Ignored without `cloud`.\n */\n threadId?: string | undefined;\n /**\n * Called with the settled remote id when the cloud list changes thread.\n */\n onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;\n };\n\ntype AISDKThreadChatOptions<UI_MESSAGE extends UIMessage = UIMessage> = Omit<\n AISDKThreadsOptions<UI_MESSAGE>,\n \"cloud\" | \"threadId\" | \"onThreadIdChange\"\n>;\n\ntype ChatOptionsRef<UI_MESSAGE extends UIMessage> = {\n current: AISDKThreadChatOptions<UI_MESSAGE> | undefined;\n};\n\ntype ChatEntry<UI_MESSAGE extends UIMessage> = {\n chat: Chat<UI_MESSAGE>;\n transport: ChatTransport<UI_MESSAGE>;\n repository: MessageRepository;\n optionsRef: ChatOptionsRef<UI_MESSAGE>;\n};\n\nconst createChatEntry = <UI_MESSAGE extends UIMessage>(\n threadId: string,\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined,\n): ChatEntry<UI_MESSAGE> => {\n const optionsRef: ChatOptionsRef<UI_MESSAGE> = { current: options };\n const { chatInit } = splitChatThreadOptions(\n options as ChatThreadOptions<UI_MESSAGE> | undefined,\n );\n const transport =\n typeof options?.transport === \"function\"\n ? options.transport()\n : options?.transport === undefined\n ? new AssistantChatTransport()\n : options.transport instanceof AssistantChatTransport\n ? options.transport.__internal_clone()\n : options.transport;\n return {\n chat: createChat({ ...chatInit, id: threadId, transport }, optionsRef),\n transport,\n repository: new MessageRepository(),\n optionsRef,\n };\n};\n\nconst getOrCreateChatEntry = <UI_MESSAGE extends UIMessage>(\n threadId: string,\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined,\n chats: Map<string, ChatEntry<UI_MESSAGE>>,\n): ChatEntry<UI_MESSAGE> => {\n const existing = chats.get(threadId);\n if (existing) return existing;\n const created = createChatEntry(threadId, options);\n chats.set(threadId, created);\n return created;\n};\n\nconst useAISDKChatThread = <UI_MESSAGE extends UIMessage = UIMessage>({\n threadId,\n options,\n chats,\n cloud,\n}: {\n threadId: string;\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined;\n chats: Map<string, ChatEntry<UI_MESSAGE>>;\n cloud: boolean;\n}) => {\n const [owned] = useState(() =>\n cloud ? createChatEntry(threadId, options) : undefined,\n );\n const { chat, transport, repository, optionsRef } =\n owned ?? getOrCreateChatEntry(threadId, options, chats);\n\n useEffect(() => {\n if (cloud) optionsRef.current = options;\n });\n\n useEffect(() => {\n if (!cloud) return undefined;\n return () => {\n void chat.stop().catch(() => {});\n };\n }, [chat, cloud]);\n\n const aui = useAui();\n const fallbackItem = useMemo(\n () => ({\n initialize: async () => ({\n remoteId: threadId,\n externalId: undefined,\n }),\n }),\n [threadId],\n );\n const runtime = useChatThread(\n { ...options, transport } as ChatThreadOptions<UI_MESSAGE>,\n {\n id: threadId,\n isMainThread: true,\n getThreadListItem: () =>\n cloud\n ? aui.threadListItem.source\n ? aui.threadListItem\n : undefined\n : fallbackItem,\n chat,\n messageRepositoryInstance: repository,\n stopOnClientDestroy: false,\n },\n );\n\n const clientRef = useAssistantClientRef();\n useAssistantScopeEffect(\n \"modelContext\",\n () =>\n runtime.registerModelContextProvider(clientRef.current!.modelContext()),\n [runtime],\n );\n\n return useResource(ThreadClient({ runtime: runtime.thread }));\n};\n\nconst AISDKChatThread = resource(useAISDKChatThread);\n\nconst useAISDKThreads = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: AISDKThreadsOptions<UI_MESSAGE>,\n) => {\n const { cloud, threadId, onThreadIdChange, ...threadOptions } = options ?? {};\n const [chats] = useState(() => new Map<string, ChatEntry<UI_MESSAGE>>());\n const bindCloud = cloud !== undefined;\n\n useEffect(() => {\n for (const { optionsRef } of chats.values()) {\n optionsRef.current = threadOptions;\n }\n });\n\n useResourceCleanup(true, () => {\n for (const { chat } of chats.values()) {\n void chat.stop().catch(() => {});\n }\n });\n\n const cloudAdapter = useCloudThreadListAdapter({ cloud, sdk: AI_SDK_SDK });\n const thread = (id: string) => {\n const element = AISDKChatThread({\n threadId: id,\n options: threadOptions,\n chats,\n cloud: bindCloud,\n });\n return bindCloud ? withKey(id, element) : element;\n };\n\n return useResource(\n bindCloud\n ? RemoteThreadList({\n adapter: cloudAdapter,\n backgroundThreads: true,\n thread,\n threadId,\n onThreadIdChange,\n })\n : InMemoryThreadList({\n thread,\n onDelete: (id) => {\n void chats\n .get(id)\n ?.chat.stop()\n .catch(() => {});\n chats.delete(id);\n },\n }),\n );\n};\n\n/**\n * `AuiConfig` entry that runs one AI SDK chat per thread. Hosts the same\n * per-thread orchestration as {@link AISDKChat} inside the client's own\n * resource tree, so it works with any `AssistantClient` host, React or not.\n * Without `cloud`, threads live in memory for the client's lifetime and keep\n * their history across switches; only the visible thread is mounted, and a\n * switched-away chat keeps streaming into its stored state until it settles\n * or the thread is deleted. With `cloud`, the list is a\n * `RemoteThreadList` with `backgroundThreads`: every visited thread stays\n * mounted with its own history, a run continues after a switch and stops on\n * delete, and a freshly created thread titles itself. Model context is\n * registered on every mounted thread.\n */\nexport const AISDKThreads = resource(useAISDKThreads);\n\nattachTransformScopes(useAISDKThreads, inMemoryThreadListTransformScopes);\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  //#region src/runtime/sdkIdentity.ts
2
2
  const AI_SDK_SDK = {
3
3
  name: "@assistant-ui/ai-sdk",
4
- version: "0.0.8"
4
+ version: "0.0.10"
5
5
  };
6
6
  //#endregion
7
7
  export { AI_SDK_SDK };
@@ -11,6 +11,13 @@ export type AISDKRuntimeAdapter<UI_MESSAGE extends UIMessage = UIMessage> = Exte
11
11
  }) | undefined;
12
12
  toCreateMessage?: CustomToCreateMessageFunction;
13
13
  unstable_messageRepositoryInstance?: MessageRepository | undefined;
14
+ /**
15
+ * The object a host answer belongs to, normally the `Chat` the runtime
16
+ * renders. A host answer never reaches the `useChat` messages, so without
17
+ * an owner it lives only as long as this runtime. With an owner, it
18
+ * survives runtime remounts over the same chat.
19
+ */
20
+ unstable_hostApprovalOwner?: object | undefined;
14
21
  /**
15
22
  * Whether to automatically cancel pending interactive tool calls when the user sends a new message.
16
23
  *
@@ -38,7 +45,7 @@ export type AISDKRuntimeAdapter<UI_MESSAGE extends UIMessage = UIMessage> = Exte
38
45
  /**
39
46
  * Answers tool approval requests through a host-owned channel instead of the AI SDK's `addToolApprovalResponse`.
40
47
  *
41
- * Called for every approval request in the thread with the complete response, including option and free-form answers. Hand requests the host does not own to `respondViaAISDK`, which is what runs when this option is omitted. The answer applies to the approval when the handler starts and is removed if it throws. It is never written into the `useChat` messages, so `sendAutomaticallyWhen` cannot forward it. With a history adapter, the answer is stored with its message once the handler resolves and returns on reload, and a second response to the same request rejects; without one it lasts as long as this runtime, and a runtime mounted again over the same chat shows the request open until the resumed run records its resolution in the chat.
48
+ * Called for every approval request in the thread with the complete response, including option and free-form answers. Hand requests the host does not own to `respondViaAISDK`, which is what runs when this option is omitted. The answer applies to the approval when the handler starts and is removed if it throws. It is never written into the `useChat` messages, so `sendAutomaticallyWhen` cannot forward it. With a history adapter, the answer is stored with its message once the handler resolves and returns on reload. With `unstable_hostApprovalOwner`, in-memory answers survive runtime remounts over the same chat; without an owner or history adapter, they last only as long as the runtime. Bring the resumed run back into the chat, for example with `resumeStream`, and have the endpoint refuse a second resume.
42
49
  *
43
50
  * While a handler is set, an approval's `display`, `allowFreeform`, `dismissible` and `options` reach the renderer, because the handler can receive answers the AI SDK cannot carry. A stream declares them through the `approvalDescriptor` of its `tool-approval-request` chunk, the one approval field the AI SDK keeps opaque; the converter reads the request and answer fields from that descriptor when the approval itself lacks them.
44
51
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useAISDKRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/useAISDKRuntime.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,SAAS,EACT,OAAO,EACP,eAAe,EAEhB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAIhB,uBAAuB,EACvB,aAAa,EAGb,4BAA4B,EAE7B,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EAGL,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAuBrC,MAAM,MAAM,6BAA6B,GAAG,CAC1C,UAAU,SAAS,SAAS,GAAG,SAAS,EAExC,OAAO,EAAE,aAAa,KACnB,eAAe,CAAC,UAAU,CAAC,CAAC;AA6BjC,MAAM,MAAM,mBAAmB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACtE,0BAA0B,GAAG;IAC3B,QAAQ,CAAC,EACL,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,GAAG;QAC/C,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;QAC3C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;KAC5C,CAAC,GACF,SAAS,CAAC;IACd,eAAe,CAAC,EAAE,6BAA6B,CAAC;IAChD,kCAAkC,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACnE;;;;;;;OAOG;IACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;IAC5D;;;;;;OAMG;IACH,uBAAuB,CAAC,EACpB,CAAC,CACC,QAAQ,EAAE,4BAA4B,EACtC,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,sHAAsH;QACtH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KACtC,KACE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAC1B,SAAS,CAAC;IACd;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC;IACxD;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,oBAAoB,CAAC,yBAAyB,CAAC,CAAC;CAC3E,CAAC;AAqGJ,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,aAAa,UAAU,CAAC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,EACnD,UAAS,mBAAmB,CAAC,UAAU,CAAM,qBAonB9C,CAAC"}
1
+ {"version":3,"file":"useAISDKRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/useAISDKRuntime.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,SAAS,EACT,OAAO,EACP,eAAe,EAEhB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAIhB,uBAAuB,EACvB,aAAa,EAGb,4BAA4B,EAE7B,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EAGL,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAuBrC,MAAM,MAAM,6BAA6B,GAAG,CAC1C,UAAU,SAAS,SAAS,GAAG,SAAS,EAExC,OAAO,EAAE,aAAa,KACnB,eAAe,CAAC,UAAU,CAAC,CAAC;AA6BjC,MAAM,MAAM,mBAAmB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACtE,0BAA0B,GAAG;IAC3B,QAAQ,CAAC,EACL,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,GAAG;QAC/C,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;QAC3C,UAAU,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;KAC5C,CAAC,GACF,SAAS,CAAC;IACd,eAAe,CAAC,EAAE,6BAA6B,CAAC;IAChD,kCAAkC,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACnE;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD;;;;;;;OAOG;IACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;IAC5D;;;;;;OAMG;IACH,uBAAuB,CAAC,EACpB,CAAC,CACC,QAAQ,EAAE,4BAA4B,EACtC,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,sHAAsH;QACtH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;KACtC,KACE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAC1B,SAAS,CAAC;IACd;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC;IACxD;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,oBAAoB,CAAC,yBAAyB,CAAC,CAAC;CAC3E,CAAC;AAsRJ,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,aAAa,UAAU,CAAC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,EACnD,UAAS,mBAAmB,CAAC,UAAU,CAAM,qBA4yB9C,CAAC"}