@ulearning/ai-sdk-adapter 0.0.0-stage → 1.0.0-next.0

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 (210) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -2
  3. package/dist/adapters/aiSDKFormatAdapter.d.ts +6 -0
  4. package/dist/adapters/aiSDKFormatAdapter.d.ts.map +1 -0
  5. package/dist/adapters/aiSDKFormatAdapter.js +17 -0
  6. package/dist/adapters/aiSDKFormatAdapter.js.map +1 -0
  7. package/dist/adapters/vercelAttachmentAdapter.d.ts +3 -0
  8. package/dist/adapters/vercelAttachmentAdapter.d.ts.map +1 -0
  9. package/dist/adapters/vercelAttachmentAdapter.js +36 -0
  10. package/dist/adapters/vercelAttachmentAdapter.js.map +1 -0
  11. package/dist/aiSDKExtras.d.ts +13 -0
  12. package/dist/aiSDKExtras.d.ts.map +1 -0
  13. package/dist/aiSDKExtras.js +6 -0
  14. package/dist/aiSDKExtras.js.map +1 -0
  15. package/dist/converters/convertMessage.d.ts +44 -0
  16. package/dist/converters/convertMessage.d.ts.map +1 -0
  17. package/dist/converters/convertMessage.js +465 -0
  18. package/dist/converters/convertMessage.js.map +1 -0
  19. package/dist/converters/toCreateMessage.d.ts +4 -0
  20. package/dist/converters/toCreateMessage.d.ts.map +1 -0
  21. package/dist/converters/toCreateMessage.js +65 -0
  22. package/dist/converters/toCreateMessage.js.map +1 -0
  23. package/dist/converters/toolApprovalAnswers.d.ts +3 -0
  24. package/dist/converters/toolApprovalAnswers.d.ts.map +1 -0
  25. package/dist/converters/toolApprovalAnswers.js +16 -0
  26. package/dist/converters/toolApprovalAnswers.js.map +1 -0
  27. package/dist/hooks.d.ts +17 -0
  28. package/dist/hooks.d.ts.map +1 -0
  29. package/dist/hooks.js +19 -0
  30. package/dist/hooks.js.map +1 -0
  31. package/dist/index.d.ts +17 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +13 -0
  34. package/dist/model-context/injectInteractableContext.d.ts +37 -0
  35. package/dist/model-context/injectInteractableContext.d.ts.map +1 -0
  36. package/dist/model-context/injectInteractableContext.js +54 -0
  37. package/dist/model-context/injectInteractableContext.js.map +1 -0
  38. package/dist/model-context/injectQuoteContext.d.ts +25 -0
  39. package/dist/model-context/injectQuoteContext.d.ts.map +1 -0
  40. package/dist/model-context/injectQuoteContext.js +51 -0
  41. package/dist/model-context/injectQuoteContext.js.map +1 -0
  42. package/dist/runtime/AISDKChat.d.ts +13 -0
  43. package/dist/runtime/AISDKChat.d.ts.map +1 -0
  44. package/dist/runtime/AISDKChat.js +34 -0
  45. package/dist/runtime/AISDKChat.js.map +1 -0
  46. package/dist/runtime/AISDKThreads.d.ts +24 -0
  47. package/dist/runtime/AISDKThreads.d.ts.map +1 -0
  48. package/dist/runtime/AISDKThreads.js +92 -0
  49. package/dist/runtime/AISDKThreads.js.map +1 -0
  50. package/dist/runtime/DynamicChatTransport.d.ts +50 -0
  51. package/dist/runtime/DynamicChatTransport.d.ts.map +1 -0
  52. package/dist/runtime/DynamicChatTransport.js +153 -0
  53. package/dist/runtime/DynamicChatTransport.js.map +1 -0
  54. package/dist/runtime/getResumableAdapter.d.ts +5 -0
  55. package/dist/runtime/getResumableAdapter.d.ts.map +1 -0
  56. package/dist/runtime/getResumableAdapter.js +11 -0
  57. package/dist/runtime/getResumableAdapter.js.map +1 -0
  58. package/dist/runtime/toolHistoryCodec.d.ts +20 -0
  59. package/dist/runtime/toolHistoryCodec.d.ts.map +1 -0
  60. package/dist/runtime/toolHistoryCodec.js +122 -0
  61. package/dist/runtime/toolHistoryCodec.js.map +1 -0
  62. package/dist/runtime/useAISDKRuntime.d.ts +95 -0
  63. package/dist/runtime/useAISDKRuntime.d.ts.map +1 -0
  64. package/dist/runtime/useAISDKRuntime.js +754 -0
  65. package/dist/runtime/useAISDKRuntime.js.map +1 -0
  66. package/dist/runtime/useChatRuntime.d.ts +17 -0
  67. package/dist/runtime/useChatRuntime.d.ts.map +1 -0
  68. package/dist/runtime/useChatRuntime.js +50 -0
  69. package/dist/runtime/useChatRuntime.js.map +1 -0
  70. package/dist/runtime/useChatSnapshot.d.ts +6 -0
  71. package/dist/runtime/useChatSnapshot.d.ts.map +1 -0
  72. package/dist/runtime/useChatSnapshot.js +62 -0
  73. package/dist/runtime/useChatSnapshot.js.map +1 -0
  74. package/dist/runtime/useChatThread.d.ts +121 -0
  75. package/dist/runtime/useChatThread.d.ts.map +1 -0
  76. package/dist/runtime/useChatThread.js +255 -0
  77. package/dist/runtime/useChatThread.js.map +1 -0
  78. package/dist/runtime/useDynamicChatTransport.d.ts +4 -0
  79. package/dist/runtime/useDynamicChatTransport.d.ts.map +1 -0
  80. package/dist/runtime/useDynamicChatTransport.js +26 -0
  81. package/dist/runtime/useDynamicChatTransport.js.map +1 -0
  82. package/dist/runtime/useExternalHistory.d.ts +12 -0
  83. package/dist/runtime/useExternalHistory.d.ts.map +1 -0
  84. package/dist/runtime/useExternalHistory.js +556 -0
  85. package/dist/runtime/useExternalHistory.js.map +1 -0
  86. package/dist/runtime/useMessageQueue.d.ts +14 -0
  87. package/dist/runtime/useMessageQueue.d.ts.map +1 -0
  88. package/dist/runtime/useMessageQueue.js +142 -0
  89. package/dist/runtime/useMessageQueue.js.map +1 -0
  90. package/dist/runtime/useResourceCleanup.d.ts +2 -0
  91. package/dist/runtime/useResourceCleanup.d.ts.map +1 -0
  92. package/dist/runtime/useResourceCleanup.js +47 -0
  93. package/dist/runtime/useResourceCleanup.js.map +1 -0
  94. package/dist/runtime/useStreamingTiming.d.ts +12 -0
  95. package/dist/runtime/useStreamingTiming.d.ts.map +1 -0
  96. package/dist/runtime/useStreamingTiming.js +36 -0
  97. package/dist/runtime/useStreamingTiming.js.map +1 -0
  98. package/dist/tools/generativeTools.d.ts +71 -0
  99. package/dist/tools/generativeTools.d.ts.map +1 -0
  100. package/dist/tools/generativeTools.js +258 -0
  101. package/dist/tools/generativeTools.js.map +1 -0
  102. package/dist/tools/mcp-stdio.node.d.ts +2 -0
  103. package/dist/tools/mcp-stdio.node.d.ts.map +1 -0
  104. package/dist/tools/mcp-stdio.node.js +1 -0
  105. package/dist/tools/mcp-stdio.unsupported.d.ts +3 -0
  106. package/dist/tools/mcp-stdio.unsupported.d.ts.map +1 -0
  107. package/dist/tools/mcp-stdio.unsupported.js +10 -0
  108. package/dist/tools/mcp-stdio.unsupported.js.map +1 -0
  109. package/dist/transport/AssistantChatTransport.d.ts +20 -0
  110. package/dist/transport/AssistantChatTransport.d.ts.map +1 -0
  111. package/dist/transport/AssistantChatTransport.js +151 -0
  112. package/dist/transport/AssistantChatTransport.js.map +1 -0
  113. package/dist/transport/resumable.d.ts +36 -0
  114. package/dist/transport/resumable.d.ts.map +1 -0
  115. package/dist/transport/resumable.js +112 -0
  116. package/dist/transport/resumable.js.map +1 -0
  117. package/dist/usage.d.ts +24 -0
  118. package/dist/usage.d.ts.map +1 -0
  119. package/dist/usage.js +121 -0
  120. package/dist/usage.js.map +1 -0
  121. package/dist/utils/getVercelAIMessages.d.ts +4 -0
  122. package/dist/utils/getVercelAIMessages.d.ts.map +1 -0
  123. package/dist/utils/getVercelAIMessages.js +8 -0
  124. package/dist/utils/getVercelAIMessages.js.map +1 -0
  125. package/dist/utils/sliceMessagesUntil.d.ts +3 -0
  126. package/dist/utils/sliceMessagesUntil.d.ts.map +1 -0
  127. package/dist/utils/sliceMessagesUntil.js +10 -0
  128. package/dist/utils/sliceMessagesUntil.js.map +1 -0
  129. package/package.json +96 -3
  130. package/src/__tests__/standalone.e2e.ts +118 -0
  131. package/src/adapters/aiSDKFormatAdapter.test.ts +36 -0
  132. package/src/adapters/aiSDKFormatAdapter.ts +18 -0
  133. package/src/adapters/vercelAttachmentAdapter.test.ts +52 -0
  134. package/src/adapters/vercelAttachmentAdapter.ts +36 -0
  135. package/src/aiSDKExtras.ts +31 -0
  136. package/src/converters/convertMessage.metadata-key.test.tsx +182 -0
  137. package/src/converters/convertMessage.test.ts +2428 -0
  138. package/src/converters/convertMessage.tool-args-status.test.tsx +185 -0
  139. package/src/converters/convertMessage.ts +919 -0
  140. package/src/converters/toCreateMessage.test.ts +716 -0
  141. package/src/converters/toCreateMessage.ts +110 -0
  142. package/src/converters/toolApprovalAnswers.ts +27 -0
  143. package/src/hooks.test.ts +168 -0
  144. package/src/hooks.ts +26 -0
  145. package/src/index.ts +29 -0
  146. package/src/model-context/injectInteractableContext.test.ts +167 -0
  147. package/src/model-context/injectInteractableContext.ts +64 -0
  148. package/src/model-context/injectQuoteContext.test.ts +33 -0
  149. package/src/model-context/injectQuoteContext.ts +63 -0
  150. package/src/runtime/AISDKChat.artifacts.test.ts +48 -0
  151. package/src/runtime/AISDKChat.integration.test.tsx +148 -0
  152. package/src/runtime/AISDKChat.test.ts +241 -0
  153. package/src/runtime/AISDKChat.ts +43 -0
  154. package/src/runtime/AISDKThreads.test.ts +811 -0
  155. package/src/runtime/AISDKThreads.ts +194 -0
  156. package/src/runtime/DynamicChatTransport.test.ts +228 -0
  157. package/src/runtime/DynamicChatTransport.ts +281 -0
  158. package/src/runtime/__tests__/controlled-transport.ts +70 -0
  159. package/src/runtime/__tests__/tap.ts +80 -0
  160. package/src/runtime/__tests__/vue.ts +46 -0
  161. package/src/runtime/getResumableAdapter.ts +16 -0
  162. package/src/runtime/toolHistoryCodec.test.ts +187 -0
  163. package/src/runtime/toolHistoryCodec.ts +245 -0
  164. package/src/runtime/useAISDKRuntime.approval.integration.test.tsx +1956 -0
  165. package/src/runtime/useAISDKRuntime.approval.test.tsx +580 -0
  166. package/src/runtime/useAISDKRuntime.denied-tool.test.tsx +122 -0
  167. package/src/runtime/useAISDKRuntime.fast-refresh.test.tsx +302 -0
  168. package/src/runtime/useAISDKRuntime.metadata-cache.test.tsx +157 -0
  169. package/src/runtime/useAISDKRuntime.queue.test.tsx +707 -0
  170. package/src/runtime/useAISDKRuntime.reload.test.tsx +217 -0
  171. package/src/runtime/useAISDKRuntime.test.ts +2345 -0
  172. package/src/runtime/useAISDKRuntime.tool-output.test.tsx +113 -0
  173. package/src/runtime/useAISDKRuntime.ts +1503 -0
  174. package/src/runtime/useAISDKRuntime.voice.test.tsx +319 -0
  175. package/src/runtime/useChatOnTap.test.ts +60 -0
  176. package/src/runtime/useChatRuntime.fast-refresh.test.tsx +83 -0
  177. package/src/runtime/useChatRuntime.integration.test.tsx +661 -0
  178. package/src/runtime/useChatRuntime.local-storage.test.tsx +114 -0
  179. package/src/runtime/useChatRuntime.native.test.ts +147 -0
  180. package/src/runtime/useChatRuntime.run-telemetry.test.tsx +226 -0
  181. package/src/runtime/useChatRuntime.test.ts +619 -0
  182. package/src/runtime/useChatRuntime.ts +80 -0
  183. package/src/runtime/useChatSnapshot.test.ts +60 -0
  184. package/src/runtime/useChatSnapshot.ts +86 -0
  185. package/src/runtime/useChatThread.binding.test.tsx +140 -0
  186. package/src/runtime/useChatThread.test.ts +993 -0
  187. package/src/runtime/useChatThread.transport.test.tsx +149 -0
  188. package/src/runtime/useChatThread.ts +533 -0
  189. package/src/runtime/useDynamicChatTransport.ts +26 -0
  190. package/src/runtime/useExternalHistory.test.ts +4187 -0
  191. package/src/runtime/useExternalHistory.ts +902 -0
  192. package/src/runtime/useMessageQueue.effects.test.tsx +88 -0
  193. package/src/runtime/useMessageQueue.test.tsx +256 -0
  194. package/src/runtime/useMessageQueue.ts +189 -0
  195. package/src/runtime/useResourceCleanup.ts +58 -0
  196. package/src/runtime/useStreamingTiming.test.tsx +96 -0
  197. package/src/runtime/useStreamingTiming.ts +69 -0
  198. package/src/tools/generativeTools.test.ts +1058 -0
  199. package/src/tools/generativeTools.ts +491 -0
  200. package/src/tools/mcp-stdio.node.ts +1 -0
  201. package/src/tools/mcp-stdio.unsupported.ts +12 -0
  202. package/src/transport/AssistantChatTransport.test.ts +631 -0
  203. package/src/transport/AssistantChatTransport.ts +236 -0
  204. package/src/transport/resumable.test.ts +262 -0
  205. package/src/transport/resumable.ts +162 -0
  206. package/src/usage.test.ts +204 -0
  207. package/src/usage.ts +179 -0
  208. package/src/utils/getVercelAIMessages.ts +11 -0
  209. package/src/utils/sliceMessagesUntil.test.ts +51 -0
  210. package/src/utils/sliceMessagesUntil.ts +16 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toCreateMessage.js","names":[],"sources":["../../src/converters/toCreateMessage.ts"],"sourcesContent":["import type { AppendMessage } from \"@ulearning/ai-core\";\nimport {\n resolveFileMediaType,\n resolveFilePartSource,\n resolveImageMediaType,\n toMediaWireUrl,\n} from \"@ulearning/ai-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 ...(part.providerMetadata != null && {\n providerMetadata: part.providerMetadata,\n }),\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 ...(part.providerMetadata != null && {\n providerMetadata: part.providerMetadata,\n }),\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 ...(part.providerMetadata != null && {\n providerMetadata: part.providerMetadata,\n }),\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,MAAa,mBACX,YACgC;CAYhC,MAAM,QAAQ,CAVZ,GAAG,QAAQ,SACX,GAAI,QAAQ,aAAa,SAAS,MAChC,EAAE,QAAQ,KAAK,OAAO;EACpB,GAAG;EACH,UAAU,EAAE;EACZ,aAAa,EAAE;CACjB,EAAE,CACJ,KAAK,CAAC,CAGe,CAAC,CAAC,KAAK,SAA8C;EAC1E,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM,KAAK;IACX,GAAI,KAAK,oBAAoB,QAAQ,EACnC,kBAAkB,KAAK,iBACzB;GACF;GACF,KAAK,SAAS;IACZ,MAAM,YAAY,sBAAsB,KAAK,OAAO,KAAK,WAAW;IACpE,OAAO;KACL,MAAM;KACN,KAAK,eAAe,KAAK,OAAO,SAAS;KACzC,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;KAC/C;KACA,GAAI,KAAK,oBAAoB,QAAQ,EACnC,kBAAkB,KAAK,iBACzB;IACF;GACF;GACA,KAAK,QAAQ;IAIX,MAAM,YAAY,qBAAqB,KAAK,MAAM,KAAK,QAAQ;IAC/D,OAAO;KACL,MAAM;KAIN,KACE,KAAK,eAAe,OAChB,KAAK,OACL,eAAe,KAAK,MAAM,SAAS;KACzC;KACA,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;KAC/C,GAAI,KAAK,oBAAoB,QAAQ,EACnC,kBAAkB,KAAK,iBACzB;IACF;GACF;GACA,KAAK,SAAS;IAGZ,MAAM,YAAY,SAAS,KAAK,MAAM;IACtC,MAAM,OAAO,KAAK,MAAM;IACxB,MAAM,SAAS,sBAAsB;KAAE;KAAM,UAAU;IAAU,CAAC;IAClE,OAAO;KACL,MAAM;KACN,KACE,OAAO,SAAS,QACZ,OAAO,MACP,QAAQ,UAAU,UAAU,OAAO;KACzC;KACA,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;IACjD;GACF;GACA,KAAK,QACH,OAAO;IACL,MAAM,QAAQ,KAAK;IACnB,MAAM,KAAK;IACX,GAAI,KAAK,OAAO,KAAA,KAAa,EAAE,IAAI,KAAK,GAAG;GAC7C;GACF,SACE,MAAM,IAAI,MAAM,0BAA0B,KAAK,MAAM;EACzD;CACF,CAAC;CAED,OAAO;EACL,MAAM,QAAQ;EACd;EACA,UAAU,QAAQ;CACpB;AACF"}
@@ -0,0 +1,3 @@
1
+ import type { ToolApprovalAnswer } from "@ulearning/ai-core";
2
+ export declare const normalizeToolApprovalAnswers: (answers: unknown) => Readonly<Record<string, ToolApprovalAnswer>> | undefined;
3
+ //# sourceMappingURL=toolApprovalAnswers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolApprovalAnswers.d.ts","mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB;AAE5D,eAAO,MAAM,4BAA4B,GACvC,SAAS,OAAO,KACf,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,GAAG,SAsBjD","names":[],"ignoreList":[],"sources":["../../src/converters/toolApprovalAnswers.ts"],"sourcesContent":[null]}
@@ -0,0 +1,16 @@
1
+ // src/converters/toolApprovalAnswers.ts
2
+ const normalizeToolApprovalAnswers = (answers) => {
3
+ if (!answers || typeof answers !== "object" || Array.isArray(answers)) return void 0;
4
+ return Object.fromEntries(Object.entries(answers).flatMap(([id, value]) => {
5
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
6
+ const { optionIds, text } = value;
7
+ const answer = {
8
+ ...Array.isArray(optionIds) && { optionIds: optionIds.filter((optionId) => typeof optionId === "string") },
9
+ ...typeof text === "string" && { text }
10
+ };
11
+ return answer.optionIds?.length || answer.text !== void 0 ? [[id, answer]] : [];
12
+ }));
13
+ };
14
+ export { normalizeToolApprovalAnswers };
15
+
16
+ //# sourceMappingURL=toolApprovalAnswers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolApprovalAnswers.js","names":[],"sources":["../../src/converters/toolApprovalAnswers.ts"],"sourcesContent":["import type { ToolApprovalAnswer } from \"@ulearning/ai-core\";\n\nexport const normalizeToolApprovalAnswers = (\n answers: unknown,\n): Readonly<Record<string, ToolApprovalAnswer>> | undefined => {\n if (!answers || typeof answers !== \"object\" || Array.isArray(answers))\n return undefined;\n\n return Object.fromEntries(\n Object.entries(answers).flatMap(([id, value]) => {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return [];\n const { optionIds, text } = value as Record<string, unknown>;\n const answer: ToolApprovalAnswer = {\n ...(Array.isArray(optionIds) && {\n optionIds: optionIds.filter(\n (optionId): optionId is string => typeof optionId === \"string\",\n ),\n }),\n ...(typeof text === \"string\" && { text }),\n };\n return answer.optionIds?.length || answer.text !== undefined\n ? [[id, answer]]\n : [];\n }),\n );\n};\n"],"mappings":";AAEA,MAAa,gCACX,YAC6D;CAC7D,IAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAClE,OAAO,KAAA;CAET,OAAO,OAAO,YACZ,OAAO,QAAQ,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,WAAW;EAC/C,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D,OAAO,CAAC;EACV,MAAM,EAAE,WAAW,SAAS;EAC5B,MAAM,SAA6B;GACjC,GAAI,MAAM,QAAQ,SAAS,KAAK,EAC9B,WAAW,UAAU,QAClB,aAAiC,OAAO,aAAa,QACxD,EACF;GACA,GAAI,OAAO,SAAS,YAAY,EAAE,KAAK;EACzC;EACA,OAAO,OAAO,WAAW,UAAU,OAAO,SAAS,KAAA,IAC/C,CAAC,CAAC,IAAI,MAAM,CAAC,IACb,CAAC;CACP,CAAC,CACH;AACF"}
@@ -0,0 +1,17 @@
1
+ import type { ShallowRef } from "vue";
2
+ import type { UIMessage } from "ai";
3
+ import { type AISDKChatHelpers } from "./aiSDKExtras.js";
4
+ /**
5
+ * Read the last AI SDK chat error object from the runtime extras.
6
+ * The readonly Ref contains `undefined` when there is no error or the current thread is not backed by
7
+ * the AI SDK runtime.
8
+ */
9
+ export declare const useAISDKError: () => Readonly<ShallowRef<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. Read `.value`; it is `undefined` when the thread is not backed by the AI
14
+ * SDK runtime.
15
+ */
16
+ export declare const useAISDKChat: <UI_MESSAGE extends UIMessage = UIMessage>() => Readonly<ShallowRef<AISDKChatHelpers<UI_MESSAGE> | undefined>>;
17
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AACnC,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,kBAAe;AAElE;;;;;AAKA,eAAO,MAAM,aAAa,+CAAmD;AAE7E;;;;;;AAMA,eAAO,MAAM,YAAY,GACvB,UAAU,SAAS,SAAS,GAAG,SAAS,OACrC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,CAI/D","names":[],"ignoreList":[],"sources":["../src/hooks.ts"],"sourcesContent":[null]}
package/dist/hooks.js ADDED
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { aiSDKExtras } from "./aiSDKExtras.js";
3
+ // src/hooks.ts
4
+ /**
5
+ * Read the last AI SDK chat error object from the runtime extras.
6
+ * The readonly Ref contains `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. Read `.value`; it is `undefined` when the thread is not backed by the AI
14
+ * SDK runtime.
15
+ */
16
+ const useAISDKChat = () => aiSDKExtras.use((e) => e.chat, void 0);
17
+ export { useAISDKChat, useAISDKError };
18
+
19
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport type { ShallowRef } from \"vue\";\nimport type { UIMessage } from \"ai\";\nimport { aiSDKExtras, type AISDKChatHelpers } from \"./aiSDKExtras\";\n\n/**\n * Read the last AI SDK chat error object from the runtime extras.\n * The readonly Ref contains `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. Read `.value`; it is `undefined` when the thread is not backed by the AI\n * SDK runtime.\n */\nexport const useAISDKChat = <\n UI_MESSAGE extends UIMessage = UIMessage,\n>(): Readonly<ShallowRef<AISDKChatHelpers<UI_MESSAGE> | undefined>> =>\n aiSDKExtras.use(\n (e) => e.chat as unknown as AISDKChatHelpers<UI_MESSAGE>,\n undefined,\n );\n"],"mappings":";;;;;;;;AAWA,MAAa,sBAAsB,YAAY,KAAK,MAAM,EAAE,OAAO,KAAA,CAAS;;;;;;;AAQ5E,MAAa,qBAGX,YAAY,KACT,MAAM,EAAE,MACT,KAAA,CACF"}
@@ -0,0 +1,17 @@
1
+ /// <reference types="@ulearning/ai-core/vue" preserve="true" />
2
+ export { useAISDKRuntime } from "./runtime/useAISDKRuntime.js";
3
+ export { useChatRuntime } from "./runtime/useChatRuntime.js";
4
+ export type { UseChatRuntimeOptions } from "./runtime/useChatRuntime.js";
5
+ export { AssistantChatTransport } from "./transport/AssistantChatTransport.js";
6
+ export { RESUMABLE_STREAM_ID_HEADER, createResumableSessionStorage, } from "./transport/resumable.js";
7
+ export type { AssistantChatResumableOptions, ResumableClientStorage, } from "./transport/resumable.js";
8
+ export { frontendTools, type FrontendTools } from "@ulearning/ai-stream/ai-sdk";
9
+ export { injectQuoteContext } from "./model-context/injectQuoteContext.js";
10
+ export { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
11
+ export type { ThreadTokenUsage, TokenUsageExtractableMessage } from "./usage.js";
12
+ export { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
13
+ export { useAISDKChat, useAISDKError } from "./hooks.js";
14
+ export { AISDKToolkit, generativeTools, type AISDKToolkitOptions, type AISDKToolkitToolsOptions, type GenerativeToolsOptions, } from "./tools/generativeTools.js";
15
+ export { AISDKChat, type AISDKChatOptions } from "./runtime/AISDKChat.js";
16
+ export { AISDKThreads, type AISDKThreadsOptions } from "./runtime/AISDKThreads.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA2B;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA0B;AACzD,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA0B;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAoC;AAC3E,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,0BAAuB;AAC9B,YAAY,EACV,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,0BAAuB;AAC9B,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAoC;AACvE,OAAO,EAAE,kCAAkC,EAAE,MAAM,8CAA2C;AAC9F,YAAY,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,YAAS;AAC7E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,YAAS;AACzE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAS;AACrD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,GAC5B,MAAM,4BAAyB;AAChC,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAqB;AACtE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAAwB","names":[],"ignoreList":[],"sources":["../src/index.ts"],"sourcesContent":[null]}
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 { injectQuoteContext } from "./model-context/injectQuoteContext.js";
7
+ import { unstable_injectInteractableContext } from "./model-context/injectInteractableContext.js";
8
+ import { getThreadMessageTokenUsage, useThreadTokenUsage } from "./usage.js";
9
+ import { AISDKToolkit, generativeTools } from "./tools/generativeTools.js";
10
+ import { AISDKChat } from "./runtime/AISDKChat.js";
11
+ import { AISDKThreads } from "./runtime/AISDKThreads.js";
12
+ import { frontendTools } from "@ulearning/ai-stream/ai-sdk";
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,37 @@
1
+ import type { UIMessage } from "ai";
2
+ import { type Unstable_InteractableSnapshotEntry } from "@ulearning/ai-core";
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
+ * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { convertToModelMessages, streamText } from "ai";
23
+ * import { unstable_injectInteractableContext } from "@ulearning/ai-sdk-adapter";
24
+ *
25
+ * export async function POST(req: Request) {
26
+ * const { messages } = await req.json();
27
+ * const result = streamText({
28
+ * abortSignal: req.signal,
29
+ * model: myModel,
30
+ * messages: await convertToModelMessages(unstable_injectInteractableContext(messages)),
31
+ * });
32
+ * return result.toUIMessageStreamResponse();
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function unstable_injectInteractableContext(messages: UIMessage[], format?: (item: Unstable_InteractableSnapshotEntry) => string): UIMessage[];
37
+ //# sourceMappingURL=injectInteractableContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectInteractableContext.d.ts","mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AACnC,OAAO,EAGL,KAAK,kCAAkC,EACxC,MAAM,oBAAoB;AAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,SAAS,EAAE,EACrB,MAAM,GAAE,CACN,IAAI,EAAE,kCAAkC,KACrC,MAA4C,GAChD,SAAS,EAAE","names":[],"ignoreList":[],"sources":["../../src/model-context/injectInteractableContext.ts"],"sourcesContent":[null]}
@@ -0,0 +1,54 @@
1
+ import { unstable_formatInteractableSnapshot, unstable_getInteractableSnapshots } from "@ulearning/ai-core";
2
+ // 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
+ * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { convertToModelMessages, streamText } from "ai";
23
+ * import { unstable_injectInteractableContext } from "@ulearning/ai-sdk-adapter";
24
+ *
25
+ * export async function POST(req: Request) {
26
+ * const { messages } = await req.json();
27
+ * const result = streamText({
28
+ * abortSignal: req.signal,
29
+ * model: myModel,
30
+ * messages: await convertToModelMessages(unstable_injectInteractableContext(messages)),
31
+ * });
32
+ * return result.toUIMessageStreamResponse();
33
+ * }
34
+ * ```
35
+ */
36
+ function unstable_injectInteractableContext(messages, format = unstable_formatInteractableSnapshot) {
37
+ return messages.map((msg) => {
38
+ if (msg.role !== "user") return msg;
39
+ const items = unstable_getInteractableSnapshots(msg);
40
+ if (!items?.length) return msg;
41
+ const text = `${items.map(format).join("\n")}\n\n`;
42
+ if (msg.parts?.[0]?.type === "text" && msg.parts[0].text === text) return msg;
43
+ return {
44
+ ...msg,
45
+ parts: [{
46
+ type: "text",
47
+ text
48
+ }, ...msg.parts ?? []]
49
+ };
50
+ });
51
+ }
52
+ export { unstable_injectInteractableContext };
53
+
54
+ //# sourceMappingURL=injectInteractableContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectInteractableContext.js","names":[],"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 \"@ulearning/ai-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 * @deprecated Experimental since 2026-06-23. Not scheduled for removal; the API may change in any release.\n *\n * @example\n * ```ts\n * import { convertToModelMessages, streamText } from \"ai\";\n * import { unstable_injectInteractableContext } from \"@ulearning/ai-sdk-adapter\";\n *\n * export async function POST(req: Request) {\n * const { messages } = await req.json();\n * const result = streamText({\n * abortSignal: req.signal,\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,mCACd,UACA,SAEc,qCACD;CACb,OAAO,SAAS,KAAK,QAAQ;EAC3B,IAAI,IAAI,SAAS,QAAQ,OAAO;EAEhC,MAAM,QAAQ,kCAAkC,GAAG;EACnD,IAAI,CAAC,OAAO,QAAQ,OAAO;EAE3B,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE;EAI7C,IADE,IAAI,QAAQ,EAAE,EAAE,SAAS,UAAU,IAAI,MAAM,EAAE,CAAC,SAAS,MACtC,OAAO;EAE5B,OAAO;GACL,GAAG;GACH,OAAO,CAAC;IAAE,MAAM;IAAiB;GAAK,GAAG,GAAI,IAAI,SAAS,CAAC,CAAE;EAC/D;CACF,CAAC;AACH"}
@@ -0,0 +1,25 @@
1
+ import type { UIMessage } from "ai";
2
+ /**
3
+ * Injects quote context into messages as markdown blockquotes.
4
+ *
5
+ * Use this in your route handler before `convertToModelMessages` so the LLM
6
+ * sees the quoted text that the user is referring to.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { convertToModelMessages, streamText } from "ai";
11
+ * import { injectQuoteContext } from "@ulearning/ai-sdk-adapter";
12
+ *
13
+ * export async function POST(req: Request) {
14
+ * const { messages } = await req.json();
15
+ * const result = streamText({
16
+ * abortSignal: req.signal,
17
+ * model: myModel,
18
+ * messages: await convertToModelMessages(injectQuoteContext(messages)),
19
+ * });
20
+ * return result.toUIMessageStreamResponse();
21
+ * }
22
+ * ```
23
+ */
24
+ export declare function injectQuoteContext(messages: UIMessage[]): UIMessage[];
25
+ //# sourceMappingURL=injectQuoteContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectQuoteContext.d.ts","mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AAenC;;;;;;;;;;;;;;;;;;;;;;AAsBA,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE","names":[],"ignoreList":[],"sources":["../../src/model-context/injectQuoteContext.ts"],"sourcesContent":[null]}
@@ -0,0 +1,51 @@
1
+ // 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 "@ulearning/ai-sdk-adapter";
21
+ *
22
+ * export async function POST(req: Request) {
23
+ * const { messages } = await req.json();
24
+ * const result = streamText({
25
+ * abortSignal: req.signal,
26
+ * model: myModel,
27
+ * messages: await convertToModelMessages(injectQuoteContext(messages)),
28
+ * });
29
+ * return result.toUIMessageStreamResponse();
30
+ * }
31
+ * ```
32
+ */
33
+ function injectQuoteContext(messages) {
34
+ return messages.map((msg) => {
35
+ if (msg.role !== "user") return msg;
36
+ const text = getQuoteText(msg.metadata);
37
+ if (!text) return msg;
38
+ const blockquote = text.split(/\r?\n/).map((line) => `> ${line}`).join("\n");
39
+ if (msg.parts?.[0]?.type === "text" && msg.parts[0].text === `${blockquote}\n\n`) return msg;
40
+ return {
41
+ ...msg,
42
+ parts: [{
43
+ type: "text",
44
+ text: `${blockquote}\n\n`
45
+ }, ...msg.parts ?? []]
46
+ };
47
+ });
48
+ }
49
+ export { injectQuoteContext };
50
+
51
+ //# sourceMappingURL=injectQuoteContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectQuoteContext.js","names":[],"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 \"@ulearning/ai-sdk-adapter\";\n *\n * export async function POST(req: Request) {\n * const { messages } = await req.json();\n * const result = streamText({\n * abortSignal: req.signal,\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,MAAM,gBAAgB,aAA0C;CAC9D,IAAI,CAAC,YAAY,OAAO,aAAa,UAAU,OAAO,KAAA;CAEtD,MAAM,SAAU,SAAqC;CACrD,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU,OAAO,KAAA;CAElD,MAAM,QAAS,OAAmC;CAClD,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO,KAAA;CAEhD,MAAM,OAAQ,MAAkC;CAChD,OAAO,OAAO,SAAS,WAAW,OAAO,KAAA;AAC3C;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,mBAAmB,UAAoC;CACrE,OAAO,SAAS,KAAK,QAAQ;EAC3B,IAAI,IAAI,SAAS,QAAQ,OAAO;EAEhC,MAAM,OAAO,aAAa,IAAI,QAAQ;EACtC,IAAI,CAAC,MAAM,OAAO;EAElB,MAAM,aAAa,KAChB,MAAM,OAAO,CAAC,CACd,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,KAAK,IAAI;EAKZ,IAFE,IAAI,QAAQ,EAAE,EAAE,SAAS,UACzB,IAAI,MAAM,EAAE,CAAC,SAAS,GAAG,WAAW,OACjB,OAAO;EAE5B,OAAO;GACL,GAAG;GACH,OAAO,CACL;IAAE,MAAM;IAAiB,MAAM,GAAG,WAAW;GAAM,GACnD,GAAI,IAAI,SAAS,CAAC,CACpB;EACF;CACF,CAAC;AACH"}
@@ -0,0 +1,13 @@
1
+ import type { UIMessage } from "ai";
2
+ import { type ChatThreadOptions } from "./useChatThread.js";
3
+ export type AISDKChatOptions<UI_MESSAGE extends UIMessage = UIMessage> = ChatThreadOptions<UI_MESSAGE>;
4
+ /**
5
+ * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the
6
+ * same orchestration as `useChatRuntime` inside the client's own resource tree,
7
+ * so it works with any `AssistantClient` host, React or not. Single thread; the
8
+ * multi-thread surface is {@link AISDKThreads}. The chat
9
+ * id is captured when the entry mounts, so a later `id` change in the options
10
+ * has no effect.
11
+ */
12
+ export declare const AISDKChat: <UI_MESSAGE extends UIMessage = UIMessage<unknown, import("ai").UIDataTypes, import("ai").UITools>>(options?: AISDKChatOptions<UI_MESSAGE> | undefined) => import("@ulearning/ai-tap").ResourceElement<import("@ulearning/ai-store").ClientOutput<"threads">>;
13
+ //# sourceMappingURL=AISDKChat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKChat.d.ts","mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AAMnC,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,oBAAiB;AAEvE,MAAM,MAAM,gBAAgB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACnE,iBAAiB,CAAC,UAAU,CAAC;AAkB/B;;;;;;;;AAQA,eAAO,MAAM,SAAS,GAxBA,UAAU,SAAS,SAAS,gOAwBH","names":[],"ignoreList":[],"sources":["../../src/runtime/AISDKChat.ts"],"sourcesContent":[null]}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { useChatThread } from "./useChatThread.js";
3
+ import { generateId } from "ai";
4
+ import { resource, useResource, useState } from "@ulearning/ai-tap";
5
+ import { RuntimeAdapter, runtimeAdapterTransformScopes } from "@ulearning/ai-core/store";
6
+ import { attachTransformScopes } from "@ulearning/ai-store/client";
7
+ // src/runtime/AISDKChat.ts
8
+ const useAISDKChat = (options) => {
9
+ const [id] = useState(() => options?.id ?? generateId());
10
+ const [threadListItem] = useState(() => ({ initialize: async () => ({
11
+ remoteId: id,
12
+ externalId: void 0
13
+ }) }));
14
+ const runtime = useChatThread(options, {
15
+ id,
16
+ isMainThread: true,
17
+ getThreadListItem: () => threadListItem,
18
+ stopOnClientDestroy: true
19
+ });
20
+ return useResource(RuntimeAdapter(runtime));
21
+ };
22
+ /**
23
+ * `AuiConfig` entry that runs the AI SDK chat as the `threads` scope. Hosts the
24
+ * same orchestration as `useChatRuntime` inside the client's own resource tree,
25
+ * so it works with any `AssistantClient` host, React or not. Single thread; the
26
+ * multi-thread surface is {@link AISDKThreads}. The chat
27
+ * id is captured when the entry mounts, so a later `id` change in the options
28
+ * has no effect.
29
+ */
30
+ const AISDKChat = resource(useAISDKChat);
31
+ attachTransformScopes(useAISDKChat, runtimeAdapterTransformScopes);
32
+ export { AISDKChat };
33
+
34
+ //# sourceMappingURL=AISDKChat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKChat.js","names":[],"sources":["../../src/runtime/AISDKChat.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource } from \"@ulearning/ai-tap\";\nimport { useState } from \"@ulearning/ai-tap\";\nimport { generateId } from \"ai\";\nimport type { UIMessage } from \"ai\";\nimport {\n RuntimeAdapter,\n runtimeAdapterTransformScopes,\n} from \"@ulearning/ai-core/store\";\nimport { attachTransformScopes } from \"@ulearning/ai-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 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,MAAM,gBACJ,YACG;CACH,MAAM,CAAC,MAAM,eAAe,SAAS,MAAM,WAAW,CAAC;CACvD,MAAM,CAAC,kBAAkB,gBAAgB,EACvC,YAAY,aAAa;EAAE,UAAU;EAAI,YAAY,KAAA;CAAU,GACjE,EAAE;CACF,MAAM,UAAU,cAAc,SAAS;EACrC;EACA,cAAc;EACd,yBAAyB;EACzB,qBAAqB;CACvB,CAAC;CACD,OAAO,YAAY,eAAe,OAAO,CAAC;AAC5C;;;;;;;;;AAUA,MAAa,YAAY,SAAS,YAAY;AAE9C,sBAAsB,cAAc,6BAA6B"}
@@ -0,0 +1,24 @@
1
+ import type { UIMessage } from "ai";
2
+ import type { ChatTransport } from "ai";
3
+ import { type ChatThreadOptions } from "./useChatThread.js";
4
+ export type AISDKThreadsOptions<UI_MESSAGE extends UIMessage = UIMessage> = Omit<ChatThreadOptions<UI_MESSAGE>, "id" | "transport" | "messages"> & {
5
+ /**
6
+ * The transport threads send through. A factory is invoked once per
7
+ * thread so each thread owns its instance. A plain
8
+ * `AssistantChatTransport` instance is cloned per thread (its
9
+ * assistant-ui wiring is per thread); any other transport instance is
10
+ * shared as-is. Defaults to one `AssistantChatTransport` per thread.
11
+ */
12
+ transport?: ChatTransport<UI_MESSAGE> | (() => ChatTransport<UI_MESSAGE>) | undefined;
13
+ };
14
+ /**
15
+ * `AuiConfig` entry that runs one AI SDK chat per thread. Hosts the same
16
+ * per-thread orchestration as {@link AISDKChat} inside the client's own
17
+ * resource tree, so it works with any `AssistantClient` host, React or not.
18
+ * Threads live in memory for the client's lifetime and keep
19
+ * their history across switches; only the visible thread is mounted, and a
20
+ * switched-away chat keeps streaming into its stored state until it settles
21
+ * or the thread is deleted. Model context is registered on each mounted thread.
22
+ */
23
+ export declare const AISDKThreads: <UI_MESSAGE extends UIMessage = UIMessage<unknown, import("ai").UIDataTypes, import("ai").UITools>>(options?: AISDKThreadsOptions<UI_MESSAGE> | undefined) => import("@ulearning/ai-tap").ResourceElement<import("@ulearning/ai-store").ClientOutput<"threads">>;
24
+ //# sourceMappingURL=AISDKThreads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKThreads.d.ts","mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI;AAYvC,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,oBAAiB;AAIxB,MAAM,MAAM,mBAAmB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACtE,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,UAAU,CAAC,GAAG;IACrE;;;;;;;IAOA,SAAS,CAAC,EACN,aAAa,CAAC,UAAU,CAAC,GACzB,CAAC,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC,GACjC,SAAS;CACd;AA8IH;;;;;;;;;AASA,eAAO,MAAM,YAAY,GAlDA,UAAU,SAAS,SAAS,mOAkDA","names":[],"ignoreList":[],"sources":["../../src/runtime/AISDKThreads.ts"],"sourcesContent":[null]}
@@ -0,0 +1,92 @@
1
+ "use client";
2
+ import { AssistantChatTransport } from "../transport/AssistantChatTransport.js";
3
+ import { useResourceCleanup } from "./useResourceCleanup.js";
4
+ import { createChat, splitChatThreadOptions, useChatThread } from "./useChatThread.js";
5
+ import { MessageRepository } from "@ulearning/ai-core/internal";
6
+ import { resource, useEffect, useMemo, useResource, useState } from "@ulearning/ai-tap";
7
+ import { InMemoryThreadList, inMemoryThreadListTransformScopes } from "@ulearning/ai-core/store";
8
+ import { attachTransformScopes, useAssistantClientRef, useAssistantScopeEffect } from "@ulearning/ai-store/client";
9
+ import { ThreadClient } from "@ulearning/ai-core/store/internal";
10
+ // src/runtime/AISDKThreads.ts
11
+ const createChatEntry = (threadId, options) => {
12
+ const optionsRef = { current: options };
13
+ const { chatInit } = splitChatThreadOptions(options);
14
+ const transport = typeof options?.transport === "function" ? options.transport() : options?.transport === void 0 ? new AssistantChatTransport() : options.transport instanceof AssistantChatTransport ? options.transport.__internal_clone() : options.transport;
15
+ return {
16
+ chat: createChat({
17
+ ...chatInit,
18
+ id: threadId,
19
+ transport
20
+ }, optionsRef),
21
+ transport,
22
+ repository: new MessageRepository(),
23
+ optionsRef
24
+ };
25
+ };
26
+ const getOrCreateChatEntry = (threadId, options, chats) => {
27
+ const existing = chats.get(threadId);
28
+ if (existing) return existing;
29
+ const created = createChatEntry(threadId, options);
30
+ chats.set(threadId, created);
31
+ return created;
32
+ };
33
+ const useAISDKChatThread = ({ threadId, options, chats }) => {
34
+ const { chat, transport, repository } = getOrCreateChatEntry(threadId, options, chats);
35
+ const fallbackItem = useMemo(() => ({ initialize: async () => ({
36
+ remoteId: threadId,
37
+ externalId: void 0
38
+ }) }), [threadId]);
39
+ const runtime = useChatThread({
40
+ ...options,
41
+ transport
42
+ }, {
43
+ id: threadId,
44
+ isMainThread: true,
45
+ getThreadListItem: () => fallbackItem,
46
+ chat,
47
+ messageRepositoryInstance: repository,
48
+ stopOnClientDestroy: false
49
+ });
50
+ const clientRef = useAssistantClientRef();
51
+ useAssistantScopeEffect("modelContext", () => runtime.registerModelContextProvider(clientRef.current.modelContext()), [runtime]);
52
+ return useResource(ThreadClient({ runtime: runtime.thread }));
53
+ };
54
+ const AISDKChatThread = resource(useAISDKChatThread);
55
+ const useAISDKThreads = (options) => {
56
+ const threadOptions = options;
57
+ const [chats] = useState(() => /* @__PURE__ */ new Map());
58
+ useEffect(() => {
59
+ for (const { optionsRef } of chats.values()) optionsRef.current = threadOptions;
60
+ });
61
+ useResourceCleanup(true, () => {
62
+ for (const { chat } of chats.values()) chat.stop().catch(() => {});
63
+ });
64
+ const thread = (id) => {
65
+ return AISDKChatThread({
66
+ threadId: id,
67
+ options: threadOptions,
68
+ chats
69
+ });
70
+ };
71
+ return useResource(InMemoryThreadList({
72
+ thread,
73
+ onDelete: (id) => {
74
+ chats.get(id)?.chat.stop().catch(() => {});
75
+ chats.delete(id);
76
+ }
77
+ }));
78
+ };
79
+ /**
80
+ * `AuiConfig` entry that runs one AI SDK chat per thread. Hosts the same
81
+ * per-thread orchestration as {@link AISDKChat} inside the client's own
82
+ * resource tree, so it works with any `AssistantClient` host, React or not.
83
+ * Threads live in memory for the client's lifetime and keep
84
+ * their history across switches; only the visible thread is mounted, and a
85
+ * switched-away chat keeps streaming into its stored state until it settles
86
+ * or the thread is deleted. Model context is registered on each mounted thread.
87
+ */
88
+ const AISDKThreads = resource(useAISDKThreads);
89
+ attachTransformScopes(useAISDKThreads, inMemoryThreadListTransformScopes);
90
+ export { AISDKThreads };
91
+
92
+ //# sourceMappingURL=AISDKThreads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AISDKThreads.js","names":[],"sources":["../../src/runtime/AISDKThreads.ts"],"sourcesContent":["\"use client\";\n\nimport { resource, useResource } from \"@ulearning/ai-tap\";\nimport { useEffect, useMemo, useState } from \"@ulearning/ai-tap\";\nimport type { Chat } from \"@ai-sdk/vue\";\nimport type { UIMessage } from \"ai\";\nimport type { ChatTransport } from \"ai\";\nimport {\n InMemoryThreadList,\n inMemoryThreadListTransformScopes,\n} from \"@ulearning/ai-core/store\";\nimport { ThreadClient } from \"@ulearning/ai-core/store/internal\";\nimport {\n attachTransformScopes,\n useAssistantClientRef,\n useAssistantScopeEffect,\n} from \"@ulearning/ai-store/client\";\nimport { AssistantChatTransport } from \"../transport/AssistantChatTransport\";\nimport {\n createChat,\n splitChatThreadOptions,\n useChatThread,\n type ChatThreadOptions,\n} from \"./useChatThread\";\nimport { MessageRepository } from \"@ulearning/ai-core/internal\";\nimport { useResourceCleanup } from \"./useResourceCleanup\";\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\ntype AISDKThreadChatOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n AISDKThreadsOptions<UI_MESSAGE>;\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}: {\n threadId: string;\n options: AISDKThreadChatOptions<UI_MESSAGE> | undefined;\n chats: Map<string, ChatEntry<UI_MESSAGE>>;\n}) => {\n const { chat, transport, repository } = getOrCreateChatEntry(\n threadId,\n options,\n chats,\n );\n\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: () => 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 threadOptions = options;\n const [chats] = useState(() => new Map<string, ChatEntry<UI_MESSAGE>>());\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 thread = (id: string) => {\n const element = AISDKChatThread({\n threadId: id,\n options: threadOptions,\n chats,\n });\n return element;\n };\n\n return useResource(\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 * 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. Model context is registered on each mounted thread.\n */\nexport const AISDKThreads = resource(useAISDKThreads);\n\nattachTransformScopes(useAISDKThreads, inMemoryThreadListTransformScopes);\n"],"mappings":";;;;;;;;;;AAwDA,MAAM,mBACJ,UACA,YAC0B;CAC1B,MAAM,aAAyC,EAAE,SAAS,QAAQ;CAClE,MAAM,EAAE,aAAa,uBACnB,OACF;CACA,MAAM,YACJ,OAAO,SAAS,cAAc,aAC1B,QAAQ,UAAU,IAClB,SAAS,cAAc,KAAA,IACrB,IAAI,uBAAuB,IAC3B,QAAQ,qBAAqB,yBAC3B,QAAQ,UAAU,iBAAiB,IACnC,QAAQ;CAClB,OAAO;EACL,MAAM,WAAW;GAAE,GAAG;GAAU,IAAI;GAAU;EAAU,GAAG,UAAU;EACrE;EACA,YAAY,IAAI,kBAAkB;EAClC;CACF;AACF;AAEA,MAAM,wBACJ,UACA,SACA,UAC0B;CAC1B,MAAM,WAAW,MAAM,IAAI,QAAQ;CACnC,IAAI,UAAU,OAAO;CACrB,MAAM,UAAU,gBAAgB,UAAU,OAAO;CACjD,MAAM,IAAI,UAAU,OAAO;CAC3B,OAAO;AACT;AAEA,MAAM,sBAAgE,EACpE,UACA,SACA,YAKI;CACJ,MAAM,EAAE,MAAM,WAAW,eAAe,qBACtC,UACA,SACA,KACF;CAEA,MAAM,eAAe,eACZ,EACL,YAAY,aAAa;EACvB,UAAU;EACV,YAAY,KAAA;CACd,GACF,IACA,CAAC,QAAQ,CACX;CACA,MAAM,UAAU,cACd;EAAE,GAAG;EAAS;CAAU,GACxB;EACE,IAAI;EACJ,cAAc;EACd,yBAAyB;EACzB;EACA,2BAA2B;EAC3B,qBAAqB;CACvB,CACF;CAEA,MAAM,YAAY,sBAAsB;CACxC,wBACE,sBAEE,QAAQ,6BAA6B,UAAU,QAAS,aAAa,CAAC,GACxE,CAAC,OAAO,CACV;CAEA,OAAO,YAAY,aAAa,EAAE,SAAS,QAAQ,OAAO,CAAC,CAAC;AAC9D;AAEA,MAAM,kBAAkB,SAAS,kBAAkB;AAEnD,MAAM,mBACJ,YACG;CACH,MAAM,gBAAgB;CACtB,MAAM,CAAC,SAAS,+BAAe,IAAI,IAAmC,CAAC;CAEvE,gBAAgB;EACd,KAAK,MAAM,EAAE,gBAAgB,MAAM,OAAO,GACxC,WAAW,UAAU;CAEzB,CAAC;CAED,mBAAmB,YAAY;EAC7B,KAAK,MAAM,EAAE,UAAU,MAAM,OAAO,GAClC,KAAU,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC;CAEnC,CAAC;CAED,MAAM,UAAU,OAAe;EAM7B,OALgB,gBAAgB;GAC9B,UAAU;GACV,SAAS;GACT;EACF,CACa;CACf;CAEA,OAAO,YACL,mBAAmB;EACjB;EACA,WAAW,OAAO;GAChB,MACG,IAAI,EAAE,CAAC,EACN,KAAK,KAAK,CAAC,CACZ,YAAY,CAAC,CAAC;GACjB,MAAM,OAAO,EAAE;EACjB;CACF,CAAC,CACH;AACF;;;;;;;;;;AAWA,MAAa,eAAe,SAAS,eAAe;AAEpD,sBAAsB,iBAAiB,iCAAiC"}
@@ -0,0 +1,50 @@
1
+ import type { AssistantRuntime } from "@ulearning/ai-core";
2
+ import type { UIMessage } from "ai";
3
+ import type { ChatTransport } from "ai";
4
+ import { type InitializableThreadListItem } from "../transport/AssistantChatTransport.js";
5
+ import type { ResumableClientStorage } from "../transport/resumable.js";
6
+ export declare const getResumedStreamIds: (storage: ResumableClientStorage | undefined) => Set<string>;
7
+ declare class DynamicResumableStorage implements ResumableClientStorage {
8
+ private readonly subscriptions;
9
+ private storage;
10
+ private resumedStreamIds;
11
+ private hasPendingNotification;
12
+ constructor(storage: ResumableClientStorage | undefined);
13
+ setStorage(storage: ResumableClientStorage | undefined): void;
14
+ flushChange(): void;
15
+ getResumedStreamIds(): Set<string>;
16
+ getStreamId(threadId?: string): string | null;
17
+ setStreamId(id: string, threadId?: string): void;
18
+ clear(threadId?: string): void;
19
+ subscribe(listener: () => void, threadId?: string): () => void;
20
+ }
21
+ type ThreadTransportBinding = {
22
+ runtime: AssistantRuntime;
23
+ getThreadListItem: () => InitializableThreadListItem | undefined;
24
+ };
25
+ export declare class DynamicChatTransport<UI_MESSAGE extends UIMessage> implements ChatTransport<UI_MESSAGE> {
26
+ private readonly threadContexts;
27
+ private transport;
28
+ private readonly resumableStorage;
29
+ constructor(transport: ChatTransport<UI_MESSAGE>);
30
+ readonly sendMessages: ChatTransport<UI_MESSAGE>["sendMessages"];
31
+ readonly reconnectToStream: ChatTransport<UI_MESSAGE>["reconnectToStream"];
32
+ get resumeStreamIsReplay(): boolean;
33
+ readonly getCurrentTransport: (chatId: string) => ChatTransport<UI_MESSAGE>;
34
+ readonly getCurrentResumableStorage: () => DynamicResumableStorage;
35
+ readonly getResumedStreamIds: () => Set<string>;
36
+ createThreadProxy(owner: object, getBinding: () => ThreadTransportBinding): ChatTransport<UI_MESSAGE>;
37
+ setTransport(transport: ChatTransport<UI_MESSAGE>): void;
38
+ flushTransportChange(): void;
39
+ registerThread(chatId: string, owner: object): void;
40
+ setThreadContext(chatId: string, owner: object, runtime: AssistantRuntime, getThreadListItem: () => InitializableThreadListItem | undefined): void;
41
+ unregisterThread(chatId: string, owner: object): void;
42
+ private getTransport;
43
+ private getBoundTransport;
44
+ private getOrCreateBoundTransport;
45
+ private getThreadTransport;
46
+ private createThreadTransport;
47
+ private wireTransport;
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=DynamicChatTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DynamicChatTransport.d.ts","mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI;AACvC,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,wCAAqC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAAwB;AAQpE,eAAO,MAAM,mBAAmB,GAC9B,SAAS,sBAAsB,GAAG,SAAS,gBAS5C;AAQD,cAAM,uBAAwB,YAAW,sBAAsB;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,sBAAsB;gBAElB,OAAO,EAAE,sBAAsB,GAAG,SAAS;IAKhD,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS;IAWtD,WAAW;IAaX,mBAAmB;IAInB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM;IAI7B,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAIzC,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM;IAIvB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM;;AAwB1D,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,gBAAgB;IACzB,iBAAiB,EAAE,MAAM,2BAA2B,GAAG,SAAS;CACjE;AAED,qBAAa,oBAAoB,CAC/B,UAAU,SAAS,SAAS,CAC5B,YAAW,aAAa,CAAC,UAAU,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAI/B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAErB,SAAS,EAAE,aAAa,CAAC,UAAU,CAAC;IAOhD,SAAgB,YAAY,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC;IAIvE,SAAgB,iBAAiB,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,mBAAmB,CAAC;IAGjF,IAAW,oBAAoB;IAI/B,SAAgB,mBAAmB,GAAI,QAAQ,MAAM;IAGrD,SAAgB,0BAA0B;IAE1C,SAAgB,mBAAmB;IAG5B,iBAAiB,CACtB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,sBAAsB,GACvC,aAAa,CAAC,UAAU,CAAC;IAqBrB,YAAY,CAAC,SAAS,EAAE,aAAa,CAAC,UAAU,CAAC;IAMjD,oBAAoB;IAIpB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAQ5C,gBAAgB,CACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,EACzB,iBAAiB,EAAE,MAAM,2BAA2B,GAAG,SAAS;IAkB3D,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAMrD,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,aAAa","names":[],"ignoreList":[],"sources":["../../src/runtime/DynamicChatTransport.ts"],"sourcesContent":[null]}