@assistant-ui/ai-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +32 -0
  3. package/dist/adapters/aiSDKFormatAdapter.d.ts +8 -0
  4. package/dist/adapters/aiSDKFormatAdapter.d.ts.map +1 -0
  5. package/dist/adapters/aiSDKFormatAdapter.js +26 -0
  6. package/dist/adapters/aiSDKFormatAdapter.js.map +1 -0
  7. package/dist/adapters/vercelAttachmentAdapter.d.ts +6 -0
  8. package/dist/adapters/vercelAttachmentAdapter.d.ts.map +1 -0
  9. package/dist/adapters/vercelAttachmentAdapter.js +37 -0
  10. package/dist/adapters/vercelAttachmentAdapter.js.map +1 -0
  11. package/dist/aiSDKExtras.d.ts +11 -0
  12. package/dist/aiSDKExtras.d.ts.map +1 -0
  13. package/dist/aiSDKExtras.js +7 -0
  14. package/dist/aiSDKExtras.js.map +1 -0
  15. package/dist/converters/convertMessage.d.ts +28 -0
  16. package/dist/converters/convertMessage.d.ts.map +1 -0
  17. package/dist/converters/convertMessage.js +249 -0
  18. package/dist/converters/convertMessage.js.map +1 -0
  19. package/dist/converters/modelContentEnvelope.d.ts +16 -0
  20. package/dist/converters/modelContentEnvelope.d.ts.map +1 -0
  21. package/dist/converters/modelContentEnvelope.js +22 -0
  22. package/dist/converters/modelContentEnvelope.js.map +1 -0
  23. package/dist/converters/toCreateMessage.d.ts +7 -0
  24. package/dist/converters/toCreateMessage.d.ts.map +1 -0
  25. package/dist/converters/toCreateMessage.js +58 -0
  26. package/dist/converters/toCreateMessage.js.map +1 -0
  27. package/dist/converters/toolOutputConversion.d.ts +29 -0
  28. package/dist/converters/toolOutputConversion.d.ts.map +1 -0
  29. package/dist/converters/toolOutputConversion.js +31 -0
  30. package/dist/converters/toolOutputConversion.js.map +1 -0
  31. package/dist/hooks.d.ts +19 -0
  32. package/dist/hooks.d.ts.map +1 -0
  33. package/dist/hooks.js +20 -0
  34. package/dist/hooks.js.map +1 -0
  35. package/dist/index.d.ts +14 -0
  36. package/dist/index.js +13 -0
  37. package/dist/index.native.d.ts +12 -0
  38. package/dist/index.native.js +11 -0
  39. package/dist/model-context/injectInteractableContext.d.ts +37 -0
  40. package/dist/model-context/injectInteractableContext.d.ts.map +1 -0
  41. package/dist/model-context/injectInteractableContext.js +52 -0
  42. package/dist/model-context/injectInteractableContext.js.map +1 -0
  43. package/dist/model-context/injectQuoteContext.d.ts +27 -0
  44. package/dist/model-context/injectQuoteContext.d.ts.map +1 -0
  45. package/dist/model-context/injectQuoteContext.js +51 -0
  46. package/dist/model-context/injectQuoteContext.js.map +1 -0
  47. package/dist/runtime/AISDKChat.d.ts +16 -0
  48. package/dist/runtime/AISDKChat.d.ts.map +1 -0
  49. package/dist/runtime/AISDKChat.js +69 -0
  50. package/dist/runtime/AISDKChat.js.map +1 -0
  51. package/dist/runtime/AISDKThreads.d.ts +45 -0
  52. package/dist/runtime/AISDKThreads.d.ts.map +1 -0
  53. package/dist/runtime/AISDKThreads.js +203 -0
  54. package/dist/runtime/AISDKThreads.js.map +1 -0
  55. package/dist/runtime/useAISDKRuntime.d.ts +49 -0
  56. package/dist/runtime/useAISDKRuntime.d.ts.map +1 -0
  57. package/dist/runtime/useAISDKRuntime.js +266 -0
  58. package/dist/runtime/useAISDKRuntime.js.map +1 -0
  59. package/dist/runtime/useChatRuntime.d.ts +13 -0
  60. package/dist/runtime/useChatRuntime.d.ts.map +1 -0
  61. package/dist/runtime/useChatRuntime.js +52 -0
  62. package/dist/runtime/useChatRuntime.js.map +1 -0
  63. package/dist/runtime/useChatThread.d.ts +77 -0
  64. package/dist/runtime/useChatThread.d.ts.map +1 -0
  65. package/dist/runtime/useChatThread.js +134 -0
  66. package/dist/runtime/useChatThread.js.map +1 -0
  67. package/dist/runtime/useExternalHistory.d.ts +11 -0
  68. package/dist/runtime/useExternalHistory.d.ts.map +1 -0
  69. package/dist/runtime/useExternalHistory.js +278 -0
  70. package/dist/runtime/useExternalHistory.js.map +1 -0
  71. package/dist/runtime/useResourceCleanup.d.ts +5 -0
  72. package/dist/runtime/useResourceCleanup.d.ts.map +1 -0
  73. package/dist/runtime/useResourceCleanup.js +47 -0
  74. package/dist/runtime/useResourceCleanup.js.map +1 -0
  75. package/dist/runtime/useStreamingTiming.d.ts +15 -0
  76. package/dist/runtime/useStreamingTiming.d.ts.map +1 -0
  77. package/dist/runtime/useStreamingTiming.js +38 -0
  78. package/dist/runtime/useStreamingTiming.js.map +1 -0
  79. package/dist/tools/frontendTools.d.ts +33 -0
  80. package/dist/tools/frontendTools.d.ts.map +1 -0
  81. package/dist/tools/frontendTools.js +33 -0
  82. package/dist/tools/frontendTools.js.map +1 -0
  83. package/dist/tools/generativeTools.d.ts +73 -0
  84. package/dist/tools/generativeTools.d.ts.map +1 -0
  85. package/dist/tools/generativeTools.js +245 -0
  86. package/dist/tools/generativeTools.js.map +1 -0
  87. package/dist/tools/mcp-stdio.node.d.ts +2 -0
  88. package/dist/tools/mcp-stdio.node.js +2 -0
  89. package/dist/tools/mcp-stdio.unsupported.d.ts +6 -0
  90. package/dist/tools/mcp-stdio.unsupported.d.ts.map +1 -0
  91. package/dist/tools/mcp-stdio.unsupported.js +11 -0
  92. package/dist/tools/mcp-stdio.unsupported.js.map +1 -0
  93. package/dist/transport/AssistantChatTransport.d.ts +23 -0
  94. package/dist/transport/AssistantChatTransport.d.ts.map +1 -0
  95. package/dist/transport/AssistantChatTransport.js +134 -0
  96. package/dist/transport/AssistantChatTransport.js.map +1 -0
  97. package/dist/transport/resumable.d.ts +38 -0
  98. package/dist/transport/resumable.d.ts.map +1 -0
  99. package/dist/transport/resumable.js +113 -0
  100. package/dist/transport/resumable.js.map +1 -0
  101. package/dist/usage.d.ts +19 -0
  102. package/dist/usage.d.ts.map +1 -0
  103. package/dist/usage.js +127 -0
  104. package/dist/usage.js.map +1 -0
  105. package/dist/utils/getVercelAIMessages.d.ts +7 -0
  106. package/dist/utils/getVercelAIMessages.d.ts.map +1 -0
  107. package/dist/utils/getVercelAIMessages.js +9 -0
  108. package/dist/utils/getVercelAIMessages.js.map +1 -0
  109. package/dist/utils/sliceMessagesUntil.d.ts +6 -0
  110. package/dist/utils/sliceMessagesUntil.d.ts.map +1 -0
  111. package/dist/utils/sliceMessagesUntil.js +12 -0
  112. package/dist/utils/sliceMessagesUntil.js.map +1 -0
  113. package/package.json +100 -0
  114. package/src/__tests__/standalone.e2e.ts +59 -0
  115. package/src/adapters/aiSDKFormatAdapter.ts +41 -0
  116. package/src/adapters/vercelAttachmentAdapter.test.ts +29 -0
  117. package/src/adapters/vercelAttachmentAdapter.ts +36 -0
  118. package/src/aiSDKExtras.ts +11 -0
  119. package/src/converters/convertMessage.test.ts +1130 -0
  120. package/src/converters/convertMessage.ts +457 -0
  121. package/src/converters/modelContentEnvelope.ts +41 -0
  122. package/src/converters/toCreateMessage.test.ts +596 -0
  123. package/src/converters/toCreateMessage.ts +99 -0
  124. package/src/converters/toolOutputConversion.ts +26 -0
  125. package/src/hooks.ts +23 -0
  126. package/src/index.native.ts +21 -0
  127. package/src/index.ts +29 -0
  128. package/src/model-context/injectInteractableContext.test.ts +167 -0
  129. package/src/model-context/injectInteractableContext.ts +61 -0
  130. package/src/model-context/injectQuoteContext.test.ts +33 -0
  131. package/src/model-context/injectQuoteContext.ts +62 -0
  132. package/src/runtime/AISDKChat.integration.test.tsx +47 -0
  133. package/src/runtime/AISDKChat.react-compiler.test.ts +49 -0
  134. package/src/runtime/AISDKChat.test.ts +193 -0
  135. package/src/runtime/AISDKChat.ts +47 -0
  136. package/src/runtime/AISDKThreads.cloud.test.ts +136 -0
  137. package/src/runtime/AISDKThreads.test.ts +548 -0
  138. package/src/runtime/AISDKThreads.ts +223 -0
  139. package/src/runtime/__tests__/controlled-transport.ts +43 -0
  140. package/src/runtime/useAISDKRuntime.approval.test.tsx +69 -0
  141. package/src/runtime/useAISDKRuntime.test.ts +1021 -0
  142. package/src/runtime/useAISDKRuntime.tool-output.test.tsx +113 -0
  143. package/src/runtime/useAISDKRuntime.ts +524 -0
  144. package/src/runtime/useChatOnTap.test.ts +58 -0
  145. package/src/runtime/useChatRuntime.integration.test.tsx +67 -0
  146. package/src/runtime/useChatRuntime.test.ts +522 -0
  147. package/src/runtime/useChatRuntime.ts +49 -0
  148. package/src/runtime/useChatThread.ts +286 -0
  149. package/src/runtime/useExternalHistory.test.ts +1289 -0
  150. package/src/runtime/useExternalHistory.ts +435 -0
  151. package/src/runtime/useResourceCleanup.ts +32 -0
  152. package/src/runtime/useStreamingTiming.ts +68 -0
  153. package/src/tools/frontendTools.test.ts +205 -0
  154. package/src/tools/frontendTools.ts +83 -0
  155. package/src/tools/generativeTools.test.ts +785 -0
  156. package/src/tools/generativeTools.ts +470 -0
  157. package/src/tools/mcp-stdio.node.ts +1 -0
  158. package/src/tools/mcp-stdio.unsupported.ts +12 -0
  159. package/src/transport/AssistantChatTransport.test.ts +300 -0
  160. package/src/transport/AssistantChatTransport.ts +204 -0
  161. package/src/transport/resumable.test.ts +262 -0
  162. package/src/transport/resumable.ts +161 -0
  163. package/src/usage.test.ts +186 -0
  164. package/src/usage.ts +174 -0
  165. package/src/utils/getVercelAIMessages.ts +11 -0
  166. package/src/utils/sliceMessagesUntil.test.ts +55 -0
  167. package/src/utils/sliceMessagesUntil.ts +20 -0
@@ -0,0 +1,58 @@
1
+ import { httpUrlPattern, parseDataUrl, resolveFileMediaType, resolveImageMediaType, toMediaWireUrl } from "@assistant-ui/core/internal";
2
+ //#region src/converters/toCreateMessage.ts
3
+ const toCreateMessage = (message) => {
4
+ const parts = [...message.content, ...message.attachments?.flatMap((a) => a.content.map((c) => ({
5
+ ...c,
6
+ filename: a.name,
7
+ contentType: a.contentType
8
+ }))) ?? []].map((part) => {
9
+ switch (part.type) {
10
+ case "text": return {
11
+ type: "text",
12
+ text: part.text
13
+ };
14
+ case "image": {
15
+ const mediaType = resolveImageMediaType(part.image, part.contentType);
16
+ return {
17
+ type: "file",
18
+ url: toMediaWireUrl(part.image, mediaType),
19
+ ...part.filename && { filename: part.filename },
20
+ mediaType
21
+ };
22
+ }
23
+ case "file": {
24
+ const mediaType = resolveFileMediaType(part.data, part.mimeType);
25
+ return {
26
+ type: "file",
27
+ url: part.sourceType === "id" ? part.data : toMediaWireUrl(part.data, mediaType),
28
+ mediaType,
29
+ ...part.filename && { filename: part.filename }
30
+ };
31
+ }
32
+ case "audio": {
33
+ const mediaType = `audio/${part.audio.format}`;
34
+ const data = part.audio.data;
35
+ return {
36
+ type: "file",
37
+ url: httpUrlPattern.test(data) ? data : `data:${mediaType};base64,${parseDataUrl(data)?.data ?? data}`,
38
+ mediaType,
39
+ ...part.filename && { filename: part.filename }
40
+ };
41
+ }
42
+ case "data": return {
43
+ type: `data-${part.name}`,
44
+ data: part.data
45
+ };
46
+ default: throw new Error(`Unsupported part type: ${part.type}`);
47
+ }
48
+ });
49
+ return {
50
+ role: message.role,
51
+ parts,
52
+ metadata: message.metadata
53
+ };
54
+ };
55
+ //#endregion
56
+ export { toCreateMessage };
57
+
58
+ //# sourceMappingURL=toCreateMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toCreateMessage.js","names":["AppendMessage","httpUrlPattern","parseDataUrl","resolveFileMediaType","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","test","Error","role","metadata"],"sources":["../../src/converters/toCreateMessage.ts"],"sourcesContent":["import type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n httpUrlPattern,\n parseDataUrl,\n resolveFileMediaType,\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 return {\n type: \"file\",\n url: httpUrlPattern.test(data)\n ? data\n : `data:${mediaType};base64,${parseDataUrl(data)?.data ?? 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":";;AAqBA,MAAac,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,YAAY1B,qBAAqBuB,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,OAAO;KACLL,MAAM;KACNI,KAAK9B,eAAeoC,KAAKL,IAAI,IACzBA,OACA,QAAQH,UAAS,UAAW3B,aAAa8B,IAAI,CAAC,EAAEA,QAAQA;KAC5DH;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,IAAIM,MAAM,0BAA0BZ,KAAKC,MAAM;EACzD;CACF,CAAC;CAED,OAAO;EACLY,MAAMxB,QAAQwB;EACdd;EACAe,UAAUzB,QAAQyB;CACpB;AACF"}
@@ -0,0 +1,29 @@
1
+ import { JSONValue } from "ai";
2
+ import { ToolModelContentPart } from "assistant-stream";
3
+ //#region src/converters/toolOutputConversion.d.ts
4
+ declare const toAISDKContent: (parts: readonly ToolModelContentPart[]) => {
5
+ type: "content";
6
+ value: ({
7
+ type: "text";
8
+ text: string;
9
+ } | {
10
+ filename?: string;
11
+ type: "file";
12
+ data: {
13
+ type: "data";
14
+ data: string;
15
+ };
16
+ mediaType: string;
17
+ text?: never;
18
+ })[];
19
+ };
20
+ declare const toAISDKDefaultOutput: (output: unknown) => {
21
+ type: "text";
22
+ value: string;
23
+ } | {
24
+ type: "json";
25
+ value: JSONValue;
26
+ };
27
+ //#endregion
28
+ export { toAISDKContent, toAISDKDefaultOutput };
29
+ //# sourceMappingURL=toolOutputConversion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolOutputConversion.d.ts","names":[],"sources":["../../src/converters/toolOutputConversion.ts"],"mappings":";;;cAGa,iBAAkB,gBAAgB;;;;;;;;;;;;;;;;cAmBlC,uBAAwB;;;;;EAGqB,OAAA"}
@@ -0,0 +1,31 @@
1
+ //#region src/converters/toolOutputConversion.ts
2
+ const toAISDKContent = (parts) => ({
3
+ type: "content",
4
+ value: parts.map((part) => {
5
+ if (part.type === "text") return {
6
+ type: "text",
7
+ text: part.text
8
+ };
9
+ const mediaType = typeof part.mediaType === "string" ? part.mediaType : "application/octet-stream";
10
+ return {
11
+ type: "file",
12
+ data: {
13
+ type: "data",
14
+ data: part.data
15
+ },
16
+ mediaType,
17
+ ...part.filename !== void 0 && { filename: part.filename }
18
+ };
19
+ })
20
+ });
21
+ const toAISDKDefaultOutput = (output) => typeof output === "string" ? {
22
+ type: "text",
23
+ value: output
24
+ } : {
25
+ type: "json",
26
+ value: output ?? null
27
+ };
28
+ //#endregion
29
+ export { toAISDKContent, toAISDKDefaultOutput };
30
+
31
+ //# sourceMappingURL=toolOutputConversion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolOutputConversion.js","names":["JSONValue","ToolModelContentPart","toAISDKContent","parts","type","const","value","map","part","text","mediaType","data","filename","undefined","toAISDKDefaultOutput","output"],"sources":["../../src/converters/toolOutputConversion.ts"],"sourcesContent":["import type { JSONValue } from \"ai\";\nimport type { ToolModelContentPart } from \"assistant-stream\";\n\nexport const toAISDKContent = (parts: readonly ToolModelContentPart[]) => ({\n type: \"content\" as const,\n value: parts.map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\" as const, text: part.text };\n }\n const mediaType =\n typeof part.mediaType === \"string\"\n ? part.mediaType\n : \"application/octet-stream\";\n return {\n type: \"file\" as const,\n data: { type: \"data\" as const, data: part.data },\n mediaType,\n ...(part.filename !== undefined && { filename: part.filename }),\n };\n }),\n});\n\nexport const toAISDKDefaultOutput = (output: unknown) =>\n typeof output === \"string\"\n ? { type: \"text\" as const, value: output }\n : { type: \"json\" as const, value: (output ?? null) as JSONValue };\n"],"mappings":";AAGA,MAAaE,kBAAkBC,WAA4C;CACzEC,MAAM;CACNE,OAAOH,MAAMI,KAAKC,SAAS;EACzB,IAAIA,KAAKJ,SAAS,QAChB,OAAO;GAAEA,MAAM;GAAiBK,MAAMD,KAAKC;EAAK;EAElD,MAAMC,YACJ,OAAOF,KAAKE,cAAc,WACtBF,KAAKE,YACL;EACN,OAAO;GACLN,MAAM;GACNO,MAAM;IAAEP,MAAM;IAAiBO,MAAMH,KAAKG;GAAK;GAC/CD;GACA,GAAIF,KAAKI,aAAaC,KAAAA,KAAa,EAAED,UAAUJ,KAAKI,SAAS;EAC/D;CACF,CAAC;AACH;AAEA,MAAaE,wBAAwBC,WACnC,OAAOA,WAAW,WACd;CAAEX,MAAM;CAAiBE,OAAOS;AAAO,IACvC;CAAEX,MAAM;CAAiBE,OAAQS,UAAU;AAAmB"}
@@ -0,0 +1,19 @@
1
+ import { UIMessage } from "ai";
2
+ import { UseChatHelpers } from "@ai-sdk/react";
3
+ //#region src/hooks.d.ts
4
+ /**
5
+ * Read the last AI SDK chat error object from the runtime extras.
6
+ * `undefined` when there is no error or the current thread is not backed by
7
+ * the AI SDK runtime.
8
+ */
9
+ declare const useAISDKError: () => Error | undefined;
10
+ /**
11
+ * The underlying `useChat` helpers object, for advanced views — reach
12
+ * `resumeStream`, `clearError`, or the raw `sendMessage` without forking the
13
+ * runtime hook. `undefined` when the current thread is not backed by the AI
14
+ * SDK runtime.
15
+ */
16
+ declare const useAISDKChat: <UI_MESSAGE extends UIMessage = UIMessage>() => UseChatHelpers<UI_MESSAGE> | undefined;
17
+ //#endregion
18
+ export { useAISDKChat, useAISDKError };
19
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","names":[],"sources":["../src/hooks.ts"],"mappings":";;;;;;;;cAWa,qBAAa;;;;;;;cAQb,eAAgB,mBAAmB,YAAY,gBAEtD,eAAe"}
package/dist/hooks.js ADDED
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { aiSDKExtras } from "./aiSDKExtras.js";
3
+ //#region src/hooks.ts
4
+ /**
5
+ * Read the last AI SDK chat error object from the runtime extras.
6
+ * `undefined` when there is no error or the current thread is not backed by
7
+ * the AI SDK runtime.
8
+ */
9
+ const useAISDKError = () => aiSDKExtras.use((e) => e.error, void 0);
10
+ /**
11
+ * The underlying `useChat` helpers object, for advanced views — reach
12
+ * `resumeStream`, `clearError`, or the raw `sendMessage` without forking the
13
+ * runtime hook. `undefined` when the current thread is not backed by the AI
14
+ * SDK runtime.
15
+ */
16
+ const useAISDKChat = () => aiSDKExtras.use((e) => e.chat, void 0);
17
+ //#endregion
18
+ export { useAISDKChat, useAISDKError };
19
+
20
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":["UseChatHelpers","UIMessage","aiSDKExtras","useAISDKError","use","e","error","undefined","useAISDKChat","chat","UI_MESSAGE"],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport type { UseChatHelpers } from \"@ai-sdk/react\";\nimport type { UIMessage } from \"ai\";\nimport { aiSDKExtras } from \"./aiSDKExtras\";\n\n/**\n * Read the last AI SDK chat error object from the runtime extras.\n * `undefined` when there is no error or the current thread is not backed by\n * the AI SDK runtime.\n */\nexport const useAISDKError = () => aiSDKExtras.use((e) => e.error, undefined);\n\n/**\n * The underlying `useChat` helpers object, for advanced views — reach\n * `resumeStream`, `clearError`, or the raw `sendMessage` without forking the\n * runtime hook. `undefined` when the current thread is not backed by the AI\n * SDK runtime.\n */\nexport const useAISDKChat = <UI_MESSAGE extends UIMessage = UIMessage>() =>\n aiSDKExtras.use((e) => e.chat, undefined) as\n | UseChatHelpers<UI_MESSAGE>\n | undefined;\n"],"mappings":";;;;;;;;AAWA,MAAaG,sBAAsBD,YAAYE,KAAKC,MAAMA,EAAEC,OAAOC,KAAAA,CAAS;;;;;;;AAQ5E,MAAaC,qBACXN,YAAYE,KAAKC,MAAMA,EAAEI,MAAMF,KAAAA,CAAS"}
@@ -0,0 +1,14 @@
1
+ /// <reference types="@assistant-ui/core/react" />
2
+ import { useAISDKChat, useAISDKError } from "./hooks.js";
3
+ import { useAISDKRuntime } from "./runtime/useAISDKRuntime.js";
4
+ import { AssistantChatResumableOptions, RESUMABLE_STREAM_ID_HEADER, ResumableClientStorage, createResumableSessionStorage } from "./transport/resumable.js";
5
+ import { AssistantChatTransport } from "./transport/AssistantChatTransport.js";
6
+ import { UseChatRuntimeOptions, useChatRuntime } from "./runtime/useChatRuntime.js";
7
+ import { FrontendTools, frontendTools } from "./tools/frontendTools.js";
8
+ import { injectQuoteContext } from "./model-context/injectQuoteContext.js";
9
+ import { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
10
+ import { ThreadTokenUsage, TokenUsageExtractableMessage, getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
11
+ import { AISDKToolkit, AISDKToolkitOptions, AISDKToolkitToolsOptions, GenerativeToolsOptions, generativeTools } from "./tools/generativeTools.js";
12
+ import { AISDKChat, AISDKChatOptions } from "./runtime/AISDKChat.js";
13
+ import { AISDKThreads, AISDKThreadsOptions } from "./runtime/AISDKThreads.js";
14
+ export { AISDKChat, type AISDKChatOptions, AISDKThreads, type AISDKThreadsOptions, AISDKToolkit, type AISDKToolkitOptions, type AISDKToolkitToolsOptions, type AssistantChatResumableOptions, AssistantChatTransport, type FrontendTools, type GenerativeToolsOptions, RESUMABLE_STREAM_ID_HEADER, type ResumableClientStorage, type ThreadTokenUsage, type TokenUsageExtractableMessage, type UseChatRuntimeOptions, createResumableSessionStorage, frontendTools, generativeTools, getThreadMessageTokenUsage, injectQuoteContext, unstable_injectInteractableContext, useAISDKChat, useAISDKError, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import { useAISDKChat, useAISDKError } from "./hooks.js";
2
+ import { useAISDKRuntime } from "./runtime/useAISDKRuntime.js";
3
+ import { RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage } from "./transport/resumable.js";
4
+ import { AssistantChatTransport } from "./transport/AssistantChatTransport.js";
5
+ import { useChatRuntime } from "./runtime/useChatRuntime.js";
6
+ import { frontendTools } from "./tools/frontendTools.js";
7
+ import { injectQuoteContext } from "./model-context/injectQuoteContext.js";
8
+ import { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
9
+ import { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
10
+ import { AISDKChat } from "./runtime/AISDKChat.js";
11
+ import { AISDKToolkit, generativeTools } from "./tools/generativeTools.js";
12
+ import { AISDKThreads } from "./runtime/AISDKThreads.js";
13
+ export { AISDKChat, AISDKThreads, AISDKToolkit, AssistantChatTransport, RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage, frontendTools, generativeTools, getThreadMessageTokenUsage, injectQuoteContext, unstable_injectInteractableContext, useAISDKChat, useAISDKError, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
@@ -0,0 +1,12 @@
1
+ /// <reference types="@assistant-ui/core/react" />
2
+ import { useAISDKChat, useAISDKError } from "./hooks.js";
3
+ import { useAISDKRuntime } from "./runtime/useAISDKRuntime.js";
4
+ import { AssistantChatResumableOptions, RESUMABLE_STREAM_ID_HEADER, ResumableClientStorage, createResumableSessionStorage } from "./transport/resumable.js";
5
+ import { AssistantChatTransport } from "./transport/AssistantChatTransport.js";
6
+ import { UseChatRuntimeOptions, useChatRuntime } from "./runtime/useChatRuntime.js";
7
+ import { FrontendTools, frontendTools } from "./tools/frontendTools.js";
8
+ import { injectQuoteContext } from "./model-context/injectQuoteContext.js";
9
+ import { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
10
+ import { ThreadTokenUsage, TokenUsageExtractableMessage, getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
11
+ import { AISDKChat, AISDKChatOptions } from "./runtime/AISDKChat.js";
12
+ export { AISDKChat, type AISDKChatOptions, type AssistantChatResumableOptions, AssistantChatTransport, type FrontendTools, RESUMABLE_STREAM_ID_HEADER, type ResumableClientStorage, type ThreadTokenUsage, type TokenUsageExtractableMessage, type UseChatRuntimeOptions, createResumableSessionStorage, frontendTools, getThreadMessageTokenUsage, injectQuoteContext, unstable_injectInteractableContext, useAISDKChat, useAISDKError, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
@@ -0,0 +1,11 @@
1
+ import { useAISDKChat, useAISDKError } from "./hooks.js";
2
+ import { useAISDKRuntime } from "./runtime/useAISDKRuntime.js";
3
+ import { RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage } from "./transport/resumable.js";
4
+ import { AssistantChatTransport } from "./transport/AssistantChatTransport.js";
5
+ import { useChatRuntime } from "./runtime/useChatRuntime.js";
6
+ import { frontendTools } from "./tools/frontendTools.js";
7
+ import { injectQuoteContext } from "./model-context/injectQuoteContext.js";
8
+ import { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
9
+ import { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
10
+ import { AISDKChat } from "./runtime/AISDKChat.js";
11
+ export { AISDKChat, AssistantChatTransport, RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage, frontendTools, getThreadMessageTokenUsage, injectQuoteContext, unstable_injectInteractableContext, useAISDKChat, useAISDKError, useAISDKRuntime, useChatRuntime, useThreadTokenUsage };
@@ -0,0 +1,37 @@
1
+ import { UIMessage } from "ai";
2
+ import { Unstable_InteractableSnapshotEntry } from "@assistant-ui/core";
3
+ //#region src/model-context/injectInteractableContext.d.ts
4
+ /**
5
+ * Injects interactable state snapshots into messages as model-visible text.
6
+ *
7
+ * Mirrors {@link injectQuoteContext}: reads the frozen snapshot stamped on a user
8
+ * message's `metadata.custom.interactables` (by the interactables scope at send
9
+ * time) and prepends a text part. Run this in your route handler before
10
+ * `convertToModelMessages`, which otherwise ignores `metadata.custom`.
11
+ *
12
+ * Wording is consumer-owned — pass `format` to control how each snapshot reads.
13
+ * A snapshot may originate from a user edit or an agent `update_*` call, so the
14
+ * default phrasing is neutral. Keep the instance id visible in custom wording:
15
+ * the model needs it to address the `update_*` tool's `id` parameter. A custom
16
+ * `format` must also handle entries with `partial: true`, whose `state` carries
17
+ * only the fields that changed since the model's last known state.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { convertToModelMessages, streamText } from "ai";
22
+ * import { unstable_injectInteractableContext } from "@assistant-ui/react-ai-sdk";
23
+ *
24
+ * export async function POST(req: Request) {
25
+ * const { messages } = await req.json();
26
+ * const result = streamText({
27
+ * model: myModel,
28
+ * messages: await convertToModelMessages(unstable_injectInteractableContext(messages)),
29
+ * });
30
+ * return result.toUIMessageStreamResponse();
31
+ * }
32
+ * ```
33
+ */
34
+ declare function unstable_injectInteractableContext(messages: UIMessage[], format?: (item: Unstable_InteractableSnapshotEntry) => string): UIMessage[];
35
+ //#endregion
36
+ export { unstable_injectInteractableContext };
37
+ //# sourceMappingURL=injectInteractableContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectInteractableContext.d.ts","names":[],"sources":["../../src/model-context/injectInteractableContext.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqCgB,mCACd,UAAU,aACV,UACE,MAAM,gDAEP"}
@@ -0,0 +1,52 @@
1
+ import { unstable_formatInteractableSnapshot, unstable_getInteractableSnapshots } from "@assistant-ui/core";
2
+ //#region src/model-context/injectInteractableContext.ts
3
+ /**
4
+ * Injects interactable state snapshots into messages as model-visible text.
5
+ *
6
+ * Mirrors {@link injectQuoteContext}: reads the frozen snapshot stamped on a user
7
+ * message's `metadata.custom.interactables` (by the interactables scope at send
8
+ * time) and prepends a text part. Run this in your route handler before
9
+ * `convertToModelMessages`, which otherwise ignores `metadata.custom`.
10
+ *
11
+ * Wording is consumer-owned — pass `format` to control how each snapshot reads.
12
+ * A snapshot may originate from a user edit or an agent `update_*` call, so the
13
+ * default phrasing is neutral. Keep the instance id visible in custom wording:
14
+ * the model needs it to address the `update_*` tool's `id` parameter. A custom
15
+ * `format` must also handle entries with `partial: true`, whose `state` carries
16
+ * only the fields that changed since the model's last known state.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { convertToModelMessages, streamText } from "ai";
21
+ * import { unstable_injectInteractableContext } from "@assistant-ui/react-ai-sdk";
22
+ *
23
+ * export async function POST(req: Request) {
24
+ * const { messages } = await req.json();
25
+ * const result = streamText({
26
+ * model: myModel,
27
+ * messages: await convertToModelMessages(unstable_injectInteractableContext(messages)),
28
+ * });
29
+ * return result.toUIMessageStreamResponse();
30
+ * }
31
+ * ```
32
+ */
33
+ function unstable_injectInteractableContext(messages, format = unstable_formatInteractableSnapshot) {
34
+ return messages.map((msg) => {
35
+ if (msg.role !== "user") return msg;
36
+ const items = unstable_getInteractableSnapshots(msg);
37
+ if (!items?.length) return msg;
38
+ const text = `${items.map(format).join("\n")}\n\n`;
39
+ if (msg.parts?.[0]?.type === "text" && msg.parts[0].text === text) return msg;
40
+ return {
41
+ ...msg,
42
+ parts: [{
43
+ type: "text",
44
+ text
45
+ }, ...msg.parts ?? []]
46
+ };
47
+ });
48
+ }
49
+ //#endregion
50
+ export { unstable_injectInteractableContext };
51
+
52
+ //# sourceMappingURL=injectInteractableContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectInteractableContext.js","names":["UIMessage","unstable_formatInteractableSnapshot","unstable_getInteractableSnapshots","Unstable_InteractableSnapshotEntry","unstable_injectInteractableContext","messages","format","item","map","msg","role","items","length","text","join","alreadyInjected","parts","type","const"],"sources":["../../src/model-context/injectInteractableContext.ts"],"sourcesContent":["import type { UIMessage } from \"ai\";\nimport {\n unstable_formatInteractableSnapshot,\n unstable_getInteractableSnapshots,\n type Unstable_InteractableSnapshotEntry,\n} from \"@assistant-ui/core\";\n\n/**\n * Injects interactable state snapshots into messages as model-visible text.\n *\n * Mirrors {@link injectQuoteContext}: reads the frozen snapshot stamped on a user\n * message's `metadata.custom.interactables` (by the interactables scope at send\n * time) and prepends a text part. Run this in your route handler before\n * `convertToModelMessages`, which otherwise ignores `metadata.custom`.\n *\n * Wording is consumer-owned — pass `format` to control how each snapshot reads.\n * A snapshot may originate from a user edit or an agent `update_*` call, so the\n * default phrasing is neutral. Keep the instance id visible in custom wording:\n * the model needs it to address the `update_*` tool's `id` parameter. A custom\n * `format` must also handle entries with `partial: true`, whose `state` carries\n * only the fields that changed since the model's last known state.\n *\n * @example\n * ```ts\n * import { convertToModelMessages, streamText } from \"ai\";\n * import { unstable_injectInteractableContext } from \"@assistant-ui/react-ai-sdk\";\n *\n * export async function POST(req: Request) {\n * const { messages } = await req.json();\n * const result = streamText({\n * model: myModel,\n * messages: await convertToModelMessages(unstable_injectInteractableContext(messages)),\n * });\n * return result.toUIMessageStreamResponse();\n * }\n * ```\n */\nexport function unstable_injectInteractableContext(\n messages: UIMessage[],\n format: (\n item: Unstable_InteractableSnapshotEntry,\n ) => string = unstable_formatInteractableSnapshot,\n): UIMessage[] {\n return messages.map((msg) => {\n if (msg.role !== \"user\") return msg;\n\n const items = unstable_getInteractableSnapshots(msg);\n if (!items?.length) return msg;\n\n const text = `${items.map(format).join(\"\\n\")}\\n\\n`;\n\n const alreadyInjected =\n msg.parts?.[0]?.type === \"text\" && msg.parts[0].text === text;\n if (alreadyInjected) return msg;\n\n return {\n ...msg,\n parts: [{ type: \"text\" as const, text }, ...(msg.parts ?? [])],\n };\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgBI,mCACdC,UACAC,SAEcL,qCACD;CACb,OAAOI,SAASG,KAAKC,QAAQ;EAC3B,IAAIA,IAAIC,SAAS,QAAQ,OAAOD;EAEhC,MAAME,QAAQT,kCAAkCO,GAAG;EACnD,IAAI,CAACE,OAAOC,QAAQ,OAAOH;EAE3B,MAAMI,OAAO,GAAGF,MAAMH,IAAIF,MAAM,CAAC,CAACQ,KAAK,IAAI,EAAC;EAI5C,IADEL,IAAIO,QAAQ,EAAE,EAAEC,SAAS,UAAUR,IAAIO,MAAM,EAAE,CAACH,SAASA,MACtC,OAAOJ;EAE5B,OAAO;GACL,GAAGA;GACHO,OAAO,CAAC;IAAEC,MAAM;IAAiBJ;GAAK,GAAG,GAAIJ,IAAIO,SAAS,CAAA,CAAG;EAC/D;CACF,CAAC;AACH"}
@@ -0,0 +1,27 @@
1
+ import { UIMessage } from "ai";
2
+ //#region src/model-context/injectQuoteContext.d.ts
3
+ /**
4
+ * Injects quote context into messages as markdown blockquotes.
5
+ *
6
+ * Use this in your route handler before `convertToModelMessages` so the LLM
7
+ * sees the quoted text that the user is referring to.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { convertToModelMessages, streamText } from "ai";
12
+ * import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";
13
+ *
14
+ * export async function POST(req: Request) {
15
+ * const { messages } = await req.json();
16
+ * const result = streamText({
17
+ * model: myModel,
18
+ * messages: await convertToModelMessages(injectQuoteContext(messages)),
19
+ * });
20
+ * return result.toUIMessageStreamResponse();
21
+ * }
22
+ * ```
23
+ */
24
+ declare function injectQuoteContext(messages: UIMessage[]): UIMessage[];
25
+ //#endregion
26
+ export { injectQuoteContext };
27
+ //# sourceMappingURL=injectQuoteContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectQuoteContext.d.ts","names":[],"sources":["../../src/model-context/injectQuoteContext.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;iBAoCgB,mBAAmB,UAAU,cAAc"}
@@ -0,0 +1,51 @@
1
+ //#region src/model-context/injectQuoteContext.ts
2
+ const getQuoteText = (metadata) => {
3
+ if (!metadata || typeof metadata !== "object") return void 0;
4
+ const custom = metadata.custom;
5
+ if (!custom || typeof custom !== "object") return void 0;
6
+ const quote = custom.quote;
7
+ if (!quote || typeof quote !== "object") return void 0;
8
+ const text = quote.text;
9
+ return typeof text === "string" ? text : void 0;
10
+ };
11
+ /**
12
+ * Injects quote context into messages as markdown blockquotes.
13
+ *
14
+ * Use this in your route handler before `convertToModelMessages` so the LLM
15
+ * sees the quoted text that the user is referring to.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { convertToModelMessages, streamText } from "ai";
20
+ * import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";
21
+ *
22
+ * export async function POST(req: Request) {
23
+ * const { messages } = await req.json();
24
+ * const result = streamText({
25
+ * model: myModel,
26
+ * messages: await convertToModelMessages(injectQuoteContext(messages)),
27
+ * });
28
+ * return result.toUIMessageStreamResponse();
29
+ * }
30
+ * ```
31
+ */
32
+ function injectQuoteContext(messages) {
33
+ return messages.map((msg) => {
34
+ if (msg.role !== "user") return msg;
35
+ const text = getQuoteText(msg.metadata);
36
+ if (!text) return msg;
37
+ const blockquote = text.split(/\r?\n/).map((line) => `> ${line}`).join("\n");
38
+ if (msg.parts?.[0]?.type === "text" && msg.parts[0].text === `${blockquote}\n\n`) return msg;
39
+ return {
40
+ ...msg,
41
+ parts: [{
42
+ type: "text",
43
+ text: `${blockquote}\n\n`
44
+ }, ...msg.parts ?? []]
45
+ };
46
+ });
47
+ }
48
+ //#endregion
49
+ export { injectQuoteContext };
50
+
51
+ //# sourceMappingURL=injectQuoteContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectQuoteContext.js","names":["UIMessage","getQuoteText","metadata","undefined","custom","Record","quote","text","injectQuoteContext","messages","map","msg","role","blockquote","split","line","join","alreadyInjected","parts","type","const"],"sources":["../../src/model-context/injectQuoteContext.ts"],"sourcesContent":["import type { UIMessage } from \"ai\";\n\nconst getQuoteText = (metadata: unknown): string | undefined => {\n if (!metadata || typeof metadata !== \"object\") return undefined;\n\n const custom = (metadata as Record<string, unknown>).custom;\n if (!custom || typeof custom !== \"object\") return undefined;\n\n const quote = (custom as Record<string, unknown>).quote;\n if (!quote || typeof quote !== \"object\") return undefined;\n\n const text = (quote as Record<string, unknown>).text;\n return typeof text === \"string\" ? text : undefined;\n};\n\n/**\n * Injects quote context into messages as markdown blockquotes.\n *\n * Use this in your route handler before `convertToModelMessages` so the LLM\n * sees the quoted text that the user is referring to.\n *\n * @example\n * ```ts\n * import { convertToModelMessages, streamText } from \"ai\";\n * import { injectQuoteContext } from \"@assistant-ui/react-ai-sdk\";\n *\n * export async function POST(req: Request) {\n * const { messages } = await req.json();\n * const result = streamText({\n * model: myModel,\n * messages: await convertToModelMessages(injectQuoteContext(messages)),\n * });\n * return result.toUIMessageStreamResponse();\n * }\n * ```\n */\nexport function injectQuoteContext(messages: UIMessage[]): UIMessage[] {\n return messages.map((msg) => {\n if (msg.role !== \"user\") return msg;\n\n const text = getQuoteText(msg.metadata);\n if (!text) return msg;\n\n const blockquote = text\n .split(/\\r?\\n/)\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n\n const alreadyInjected =\n msg.parts?.[0]?.type === \"text\" &&\n msg.parts[0].text === `${blockquote}\\n\\n`;\n if (alreadyInjected) return msg;\n\n return {\n ...msg,\n parts: [\n { type: \"text\" as const, text: `${blockquote}\\n\\n` },\n ...(msg.parts ?? []),\n ],\n };\n });\n}\n"],"mappings":";AAEA,MAAMC,gBAAgBC,aAA0C;CAC9D,IAAI,CAACA,YAAY,OAAOA,aAAa,UAAU,OAAOC,KAAAA;CAEtD,MAAMC,SAAUF,SAAqCE;CACrD,IAAI,CAACA,UAAU,OAAOA,WAAW,UAAU,OAAOD,KAAAA;CAElD,MAAMG,QAASF,OAAmCE;CAClD,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU,OAAOH,KAAAA;CAEhD,MAAMI,OAAQD,MAAkCC;CAChD,OAAO,OAAOA,SAAS,WAAWA,OAAOJ,KAAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgBK,mBAAmBC,UAAoC;CACrE,OAAOA,SAASC,KAAKC,QAAQ;EAC3B,IAAIA,IAAIC,SAAS,QAAQ,OAAOD;EAEhC,MAAMJ,OAAON,aAAaU,IAAIT,QAAQ;EACtC,IAAI,CAACK,MAAM,OAAOI;EAElB,MAAME,aAAaN,KAChBO,MAAM,OAAO,CAAC,CACdJ,KAAKK,SAAS,KAAKA,MAAM,CAAC,CAC1BC,KAAK,IAAI;EAKZ,IAFEL,IAAIO,QAAQ,EAAE,EAAEC,SAAS,UACzBR,IAAIO,MAAM,EAAE,CAACX,SAAS,GAAGM,WAAU,OAChB,OAAOF;EAE5B,OAAO;GACL,GAAGA;GACHO,OAAO,CACL;IAAEC,MAAM;IAAiBZ,MAAM,GAAGM,WAAU;GAAO,GACnD,GAAIF,IAAIO,SAAS,CAAA,CAAG;EAExB;CACF,CAAC;AACH"}
@@ -0,0 +1,16 @@
1
+ import { ChatThreadOptions } from "./useChatThread.js";
2
+ import { UIMessage } from "@ai-sdk/react";
3
+ //#region src/runtime/AISDKChat.d.ts
4
+ type AISDKChatOptions<UI_MESSAGE extends UIMessage = UIMessage> = ChatThreadOptions<UI_MESSAGE>;
5
+ /**
6
+ * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the
7
+ * same orchestration as `useChatRuntime` inside the client's own resource tree,
8
+ * so it works with any `AssistantClient` host, React or not. Single thread; the
9
+ * multi-thread and assistant-cloud surface is {@link AISDKThreads}. The chat
10
+ * id is captured when the entry mounts, so a later `id` change in the options
11
+ * has no effect.
12
+ */
13
+ declare const AISDKChat: <UI_MESSAGE extends UIMessage = UIMessage<unknown, import("ai").UIDataTypes, import("ai").UITools>>(options?: AISDKChatOptions<UI_MESSAGE> | undefined) => import("@assistant-ui/tap").ResourceElement<import("@assistant-ui/store").ClientOutput<"threads">>;
14
+ //#endregion
15
+ export { AISDKChat, AISDKChatOptions };
16
+ //# sourceMappingURL=AISDKChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKChat.d.ts","names":[],"sources":["../../src/runtime/AISDKChat.ts"],"mappings":";;;KAaY,iBAAiB,mBAAmB,YAAY,aAC1D,kBAAkB;;;;;;;;;cA8BP,YA5BS,mBAAmB,YAAS,gCAAA,0BAAA,UAAA,UAAA,iBAAA,wDAAA,8CAAA"}
@@ -0,0 +1,69 @@
1
+ "use client";
2
+ import { useChatThread } from "./useChatThread.js";
3
+ import { useState } from "@assistant-ui/tap/react-shim";
4
+ import { generateId } from "ai";
5
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
6
+ import { resource, useResource } from "@assistant-ui/tap";
7
+ import { RuntimeAdapter, runtimeAdapterTransformScopes } from "@assistant-ui/core/store";
8
+ import { attachTransformScopes } from "@assistant-ui/store/client";
9
+ //#region src/runtime/AISDKChat.ts
10
+ const useAISDKChat = (options) => {
11
+ const $ = c(11);
12
+ let t0;
13
+ if ($[0] !== options?.id) {
14
+ t0 = () => options?.id ?? generateId();
15
+ $[0] = options?.id;
16
+ $[1] = t0;
17
+ } else t0 = $[1];
18
+ const [id] = useState(t0);
19
+ let t1;
20
+ if ($[2] !== id) {
21
+ t1 = () => ({ initialize: async () => ({
22
+ remoteId: id,
23
+ externalId: void 0
24
+ }) });
25
+ $[2] = id;
26
+ $[3] = t1;
27
+ } else t1 = $[3];
28
+ const [threadListItem] = useState(t1);
29
+ let t2;
30
+ if ($[4] !== threadListItem) {
31
+ t2 = () => threadListItem;
32
+ $[4] = threadListItem;
33
+ $[5] = t2;
34
+ } else t2 = $[5];
35
+ let t3;
36
+ if ($[6] !== id || $[7] !== t2) {
37
+ t3 = {
38
+ id,
39
+ isMainThread: true,
40
+ getThreadListItem: t2,
41
+ stopOnClientDestroy: true
42
+ };
43
+ $[6] = id;
44
+ $[7] = t2;
45
+ $[8] = t3;
46
+ } else t3 = $[8];
47
+ const runtime = useChatThread(options, t3);
48
+ let t4;
49
+ if ($[9] !== runtime) {
50
+ t4 = RuntimeAdapter(runtime);
51
+ $[9] = runtime;
52
+ $[10] = t4;
53
+ } else t4 = $[10];
54
+ return useResource(t4);
55
+ };
56
+ /**
57
+ * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the
58
+ * same orchestration as `useChatRuntime` inside the client's own resource tree,
59
+ * so it works with any `AssistantClient` host, React or not. Single thread; the
60
+ * multi-thread and assistant-cloud surface is {@link AISDKThreads}. The chat
61
+ * id is captured when the entry mounts, so a later `id` change in the options
62
+ * has no effect.
63
+ */
64
+ const AISDKChat = resource(useAISDKChat);
65
+ attachTransformScopes(useAISDKChat, runtimeAdapterTransformScopes);
66
+ //#endregion
67
+ export { AISDKChat };
68
+
69
+ //# sourceMappingURL=AISDKChat.js.map
@@ -0,0 +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"}
@@ -0,0 +1,45 @@
1
+ import { ChatThreadOptions } from "./useChatThread.js";
2
+ import { ChatTransport } from "ai";
3
+ import { UIMessage as UIMessage$1 } from "@ai-sdk/react";
4
+ import { AssistantCloud } from "assistant-cloud";
5
+ //#region src/runtime/AISDKThreads.d.ts
6
+ type AISDKThreadsOptions<UI_MESSAGE extends UIMessage$1 = UIMessage$1> = Omit<ChatThreadOptions<UI_MESSAGE>, "id" | "transport" | "messages"> & {
7
+ /**
8
+ * The transport threads send through. A factory is invoked once per
9
+ * thread so each thread owns its instance. A plain
10
+ * `AssistantChatTransport` instance is cloned per thread (its
11
+ * assistant-ui wiring is per thread); any other transport instance is
12
+ * shared as-is. Defaults to one `AssistantChatTransport` per thread.
13
+ */
14
+ transport?: ChatTransport<UI_MESSAGE> | (() => ChatTransport<UI_MESSAGE>) | undefined;
15
+ /**
16
+ * When set, the thread list is a `RemoteThreadList` backed by this
17
+ * assistant-cloud. Omit it to keep the in-memory list. The thread
18
+ * factory is keyed so cloud history reloads on a switch, and an
19
+ * in-flight run does not continue in the background.
20
+ */
21
+ cloud?: AssistantCloud | undefined;
22
+ /**
23
+ * Controlled thread id for the cloud list. Ignored without `cloud`.
24
+ */
25
+ threadId?: string | undefined;
26
+ /**
27
+ * Called with the settled remote id when the cloud list changes thread.
28
+ */
29
+ onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;
30
+ };
31
+ /**
32
+ * `AuiConfig` entry that runs one AI SDK chat per thread. Hosts the same
33
+ * per-thread orchestration as {@link AISDKChat} inside the client's own
34
+ * resource tree, so it works with any `AssistantClient` host, React or not.
35
+ * Without `cloud`, threads live in memory for the client's lifetime and keep
36
+ * their history across switches; each thread's chat id is its thread id.
37
+ * With `cloud`, the list is a `RemoteThreadList` and the factory is keyed so
38
+ * cloud history reloads on a switch. The store entry mounts only the visible
39
+ * thread, so a switch cancels an in-flight run. Model context is
40
+ * registered on the visible thread only.
41
+ */
42
+ declare const AISDKThreads: <UI_MESSAGE extends UIMessage$1 = UIMessage$1<unknown, import("ai").UIDataTypes, import("ai").UITools>>(options?: AISDKThreadsOptions<UI_MESSAGE> | undefined) => import("@assistant-ui/tap").ResourceElement<import("@assistant-ui/store").ClientOutput<"threads">>;
43
+ //#endregion
44
+ export { AISDKThreads, AISDKThreadsOptions };
45
+ //# sourceMappingURL=AISDKThreads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKThreads.d.ts","names":[],"sources":["../../src/runtime/AISDKThreads.ts"],"mappings":";;;;;KA4BY,oBAAoB,mBAAmB,cAAY,eAC7D,KAAK,kBAAkB;;;;;;;;EAQrB,YACI,cAAc,qBACP,cAAc;;;;;;;EAQzB,QAAQ;;;;EAIR;;;;EAIA,qBAAqB;;;;;;;;;;;;;cAqKZ,eAxDY,mBAAmB,cAAS,kCAAA,0BAAA,UAAA,UAAA,oBAAA,wDAAA,8CAAA"}