@fondation-io/ai 7.0.0-beta.45

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 (536) hide show
  1. package/CHANGELOG.md +7687 -0
  2. package/README.md +238 -0
  3. package/dist/index.d.mts +7056 -0
  4. package/dist/index.d.ts +7056 -0
  5. package/dist/index.js +14607 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/index.mjs +14578 -0
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/internal/index.d.mts +303 -0
  10. package/dist/internal/index.d.ts +303 -0
  11. package/dist/internal/index.js +1352 -0
  12. package/dist/internal/index.js.map +1 -0
  13. package/dist/internal/index.mjs +1336 -0
  14. package/dist/internal/index.mjs.map +1 -0
  15. package/dist/test/index.d.mts +265 -0
  16. package/dist/test/index.d.ts +265 -0
  17. package/dist/test/index.js +509 -0
  18. package/dist/test/index.js.map +1 -0
  19. package/dist/test/index.mjs +472 -0
  20. package/dist/test/index.mjs.map +1 -0
  21. package/docs/00-introduction/index.mdx +76 -0
  22. package/docs/02-foundations/01-overview.mdx +43 -0
  23. package/docs/02-foundations/02-providers-and-models.mdx +160 -0
  24. package/docs/02-foundations/03-prompts.mdx +616 -0
  25. package/docs/02-foundations/04-tools.mdx +251 -0
  26. package/docs/02-foundations/05-streaming.mdx +62 -0
  27. package/docs/02-foundations/06-provider-options.mdx +345 -0
  28. package/docs/02-foundations/index.mdx +49 -0
  29. package/docs/02-getting-started/00-choosing-a-provider.mdx +110 -0
  30. package/docs/02-getting-started/01-navigating-the-library.mdx +85 -0
  31. package/docs/02-getting-started/02-nextjs-app-router.mdx +559 -0
  32. package/docs/02-getting-started/03-nextjs-pages-router.mdx +542 -0
  33. package/docs/02-getting-started/04-svelte.mdx +627 -0
  34. package/docs/02-getting-started/05-nuxt.mdx +566 -0
  35. package/docs/02-getting-started/06-nodejs.mdx +512 -0
  36. package/docs/02-getting-started/07-expo.mdx +766 -0
  37. package/docs/02-getting-started/08-tanstack-start.mdx +583 -0
  38. package/docs/02-getting-started/09-coding-agents.mdx +179 -0
  39. package/docs/02-getting-started/index.mdx +44 -0
  40. package/docs/03-agents/01-overview.mdx +96 -0
  41. package/docs/03-agents/02-building-agents.mdx +449 -0
  42. package/docs/03-agents/03-workflows.mdx +386 -0
  43. package/docs/03-agents/04-loop-control.mdx +394 -0
  44. package/docs/03-agents/05-configuring-call-options.mdx +286 -0
  45. package/docs/03-agents/06-memory.mdx +222 -0
  46. package/docs/03-agents/06-subagents.mdx +362 -0
  47. package/docs/03-agents/index.mdx +46 -0
  48. package/docs/03-ai-sdk-core/01-overview.mdx +31 -0
  49. package/docs/03-ai-sdk-core/05-generating-text.mdx +707 -0
  50. package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +498 -0
  51. package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +1148 -0
  52. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +383 -0
  53. package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +146 -0
  54. package/docs/03-ai-sdk-core/25-settings.mdx +216 -0
  55. package/docs/03-ai-sdk-core/26-reasoning.mdx +190 -0
  56. package/docs/03-ai-sdk-core/30-embeddings.mdx +236 -0
  57. package/docs/03-ai-sdk-core/31-reranking.mdx +218 -0
  58. package/docs/03-ai-sdk-core/35-image-generation.mdx +341 -0
  59. package/docs/03-ai-sdk-core/36-transcription.mdx +227 -0
  60. package/docs/03-ai-sdk-core/37-speech.mdx +169 -0
  61. package/docs/03-ai-sdk-core/38-video-generation.mdx +366 -0
  62. package/docs/03-ai-sdk-core/40-middleware.mdx +485 -0
  63. package/docs/03-ai-sdk-core/45-provider-management.mdx +349 -0
  64. package/docs/03-ai-sdk-core/50-error-handling.mdx +149 -0
  65. package/docs/03-ai-sdk-core/55-testing.mdx +219 -0
  66. package/docs/03-ai-sdk-core/60-telemetry.mdx +391 -0
  67. package/docs/03-ai-sdk-core/65-devtools.mdx +107 -0
  68. package/docs/03-ai-sdk-core/65-event-listeners.mdx +1303 -0
  69. package/docs/03-ai-sdk-core/index.mdx +99 -0
  70. package/docs/04-ai-sdk-ui/01-overview.mdx +44 -0
  71. package/docs/04-ai-sdk-ui/02-chatbot.mdx +1320 -0
  72. package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +534 -0
  73. package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +263 -0
  74. package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +682 -0
  75. package/docs/04-ai-sdk-ui/04-generative-user-interfaces.mdx +389 -0
  76. package/docs/04-ai-sdk-ui/05-completion.mdx +181 -0
  77. package/docs/04-ai-sdk-ui/08-object-generation.mdx +344 -0
  78. package/docs/04-ai-sdk-ui/20-streaming-data.mdx +397 -0
  79. package/docs/04-ai-sdk-ui/21-error-handling.mdx +190 -0
  80. package/docs/04-ai-sdk-ui/21-transport.mdx +174 -0
  81. package/docs/04-ai-sdk-ui/24-reading-ui-message-streams.mdx +104 -0
  82. package/docs/04-ai-sdk-ui/25-message-metadata.mdx +152 -0
  83. package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +503 -0
  84. package/docs/04-ai-sdk-ui/index.mdx +64 -0
  85. package/docs/05-ai-sdk-rsc/01-overview.mdx +45 -0
  86. package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +209 -0
  87. package/docs/05-ai-sdk-rsc/03-generative-ui-state.mdx +279 -0
  88. package/docs/05-ai-sdk-rsc/03-saving-and-restoring-states.mdx +105 -0
  89. package/docs/05-ai-sdk-rsc/04-multistep-interfaces.mdx +282 -0
  90. package/docs/05-ai-sdk-rsc/05-streaming-values.mdx +157 -0
  91. package/docs/05-ai-sdk-rsc/06-loading-state.mdx +273 -0
  92. package/docs/05-ai-sdk-rsc/08-error-handling.mdx +94 -0
  93. package/docs/05-ai-sdk-rsc/09-authentication.mdx +42 -0
  94. package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +722 -0
  95. package/docs/05-ai-sdk-rsc/index.mdx +63 -0
  96. package/docs/06-advanced/01-prompt-engineering.mdx +96 -0
  97. package/docs/06-advanced/02-stopping-streams.mdx +184 -0
  98. package/docs/06-advanced/03-backpressure.mdx +173 -0
  99. package/docs/06-advanced/04-caching.mdx +169 -0
  100. package/docs/06-advanced/05-multiple-streamables.mdx +68 -0
  101. package/docs/06-advanced/06-rate-limiting.mdx +60 -0
  102. package/docs/06-advanced/07-rendering-ui-with-language-models.mdx +225 -0
  103. package/docs/06-advanced/08-model-as-router.mdx +120 -0
  104. package/docs/06-advanced/09-multistep-interfaces.mdx +115 -0
  105. package/docs/06-advanced/09-sequential-generations.mdx +55 -0
  106. package/docs/06-advanced/10-vercel-deployment-guide.mdx +117 -0
  107. package/docs/06-advanced/index.mdx +11 -0
  108. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2785 -0
  109. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +3752 -0
  110. package/docs/07-reference/01-ai-sdk-core/05-embed.mdx +332 -0
  111. package/docs/07-reference/01-ai-sdk-core/06-embed-many.mdx +330 -0
  112. package/docs/07-reference/01-ai-sdk-core/06-rerank.mdx +323 -0
  113. package/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx +251 -0
  114. package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +152 -0
  115. package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +221 -0
  116. package/docs/07-reference/01-ai-sdk-core/13-generate-video.mdx +264 -0
  117. package/docs/07-reference/01-ai-sdk-core/15-agent.mdx +235 -0
  118. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +973 -0
  119. package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +154 -0
  120. package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +173 -0
  121. package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +150 -0
  122. package/docs/07-reference/01-ai-sdk-core/20-tool.mdx +209 -0
  123. package/docs/07-reference/01-ai-sdk-core/22-dynamic-tool.mdx +223 -0
  124. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +423 -0
  125. package/docs/07-reference/01-ai-sdk-core/24-mcp-stdio-transport.mdx +68 -0
  126. package/docs/07-reference/01-ai-sdk-core/25-json-schema.mdx +94 -0
  127. package/docs/07-reference/01-ai-sdk-core/26-zod-schema.mdx +109 -0
  128. package/docs/07-reference/01-ai-sdk-core/27-valibot-schema.mdx +58 -0
  129. package/docs/07-reference/01-ai-sdk-core/28-output.mdx +342 -0
  130. package/docs/07-reference/01-ai-sdk-core/30-model-message.mdx +435 -0
  131. package/docs/07-reference/01-ai-sdk-core/31-ui-message.mdx +264 -0
  132. package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +101 -0
  133. package/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx +113 -0
  134. package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +198 -0
  135. package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +157 -0
  136. package/docs/07-reference/01-ai-sdk-core/50-cosine-similarity.mdx +52 -0
  137. package/docs/07-reference/01-ai-sdk-core/60-wrap-language-model.mdx +59 -0
  138. package/docs/07-reference/01-ai-sdk-core/61-wrap-image-model.mdx +64 -0
  139. package/docs/07-reference/01-ai-sdk-core/65-language-model-v2-middleware.mdx +74 -0
  140. package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +68 -0
  141. package/docs/07-reference/01-ai-sdk-core/67-simulate-streaming-middleware.mdx +71 -0
  142. package/docs/07-reference/01-ai-sdk-core/68-default-settings-middleware.mdx +80 -0
  143. package/docs/07-reference/01-ai-sdk-core/69-add-tool-input-examples-middleware.mdx +155 -0
  144. package/docs/07-reference/01-ai-sdk-core/70-extract-json-middleware.mdx +147 -0
  145. package/docs/07-reference/01-ai-sdk-core/70-step-count-is.mdx +84 -0
  146. package/docs/07-reference/01-ai-sdk-core/71-has-tool-call.mdx +120 -0
  147. package/docs/07-reference/01-ai-sdk-core/75-simulate-readable-stream.mdx +94 -0
  148. package/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx +145 -0
  149. package/docs/07-reference/01-ai-sdk-core/90-generate-id.mdx +30 -0
  150. package/docs/07-reference/01-ai-sdk-core/91-create-id-generator.mdx +89 -0
  151. package/docs/07-reference/01-ai-sdk-core/92-default-generated-file.mdx +68 -0
  152. package/docs/07-reference/01-ai-sdk-core/index.mdx +160 -0
  153. package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +493 -0
  154. package/docs/07-reference/02-ai-sdk-ui/02-use-completion.mdx +185 -0
  155. package/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx +196 -0
  156. package/docs/07-reference/02-ai-sdk-ui/31-convert-to-model-messages.mdx +231 -0
  157. package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +108 -0
  158. package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +162 -0
  159. package/docs/07-reference/02-ai-sdk-ui/41-create-ui-message-stream-response.mdx +119 -0
  160. package/docs/07-reference/02-ai-sdk-ui/42-pipe-ui-message-stream-to-response.mdx +77 -0
  161. package/docs/07-reference/02-ai-sdk-ui/43-read-ui-message-stream.mdx +57 -0
  162. package/docs/07-reference/02-ai-sdk-ui/46-infer-ui-tools.mdx +99 -0
  163. package/docs/07-reference/02-ai-sdk-ui/47-infer-ui-tool.mdx +75 -0
  164. package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +333 -0
  165. package/docs/07-reference/02-ai-sdk-ui/index.mdx +89 -0
  166. package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +767 -0
  167. package/docs/07-reference/03-ai-sdk-rsc/02-create-ai.mdx +90 -0
  168. package/docs/07-reference/03-ai-sdk-rsc/03-create-streamable-ui.mdx +91 -0
  169. package/docs/07-reference/03-ai-sdk-rsc/04-create-streamable-value.mdx +78 -0
  170. package/docs/07-reference/03-ai-sdk-rsc/05-read-streamable-value.mdx +79 -0
  171. package/docs/07-reference/03-ai-sdk-rsc/06-get-ai-state.mdx +50 -0
  172. package/docs/07-reference/03-ai-sdk-rsc/07-get-mutable-ai-state.mdx +70 -0
  173. package/docs/07-reference/03-ai-sdk-rsc/08-use-ai-state.mdx +26 -0
  174. package/docs/07-reference/03-ai-sdk-rsc/09-use-actions.mdx +42 -0
  175. package/docs/07-reference/03-ai-sdk-rsc/10-use-ui-state.mdx +35 -0
  176. package/docs/07-reference/03-ai-sdk-rsc/11-use-streamable-value.mdx +46 -0
  177. package/docs/07-reference/03-ai-sdk-rsc/20-render.mdx +266 -0
  178. package/docs/07-reference/03-ai-sdk-rsc/index.mdx +67 -0
  179. package/docs/07-reference/05-ai-sdk-errors/ai-api-call-error.mdx +31 -0
  180. package/docs/07-reference/05-ai-sdk-errors/ai-download-error.mdx +28 -0
  181. package/docs/07-reference/05-ai-sdk-errors/ai-empty-response-body-error.mdx +24 -0
  182. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-argument-error.mdx +26 -0
  183. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-data-content-error.mdx +26 -0
  184. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-message-role-error.mdx +25 -0
  185. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +47 -0
  186. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-response-data-error.mdx +25 -0
  187. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-approval-error.mdx +24 -0
  188. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-input-error.mdx +27 -0
  189. package/docs/07-reference/05-ai-sdk-errors/ai-json-parse-error.mdx +25 -0
  190. package/docs/07-reference/05-ai-sdk-errors/ai-load-api-key-error.mdx +24 -0
  191. package/docs/07-reference/05-ai-sdk-errors/ai-load-setting-error.mdx +24 -0
  192. package/docs/07-reference/05-ai-sdk-errors/ai-message-conversion-error.mdx +25 -0
  193. package/docs/07-reference/05-ai-sdk-errors/ai-no-content-generated-error.mdx +24 -0
  194. package/docs/07-reference/05-ai-sdk-errors/ai-no-image-generated-error.mdx +36 -0
  195. package/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx +43 -0
  196. package/docs/07-reference/05-ai-sdk-errors/ai-no-output-generated-error.mdx +25 -0
  197. package/docs/07-reference/05-ai-sdk-errors/ai-no-speech-generated-error.mdx +24 -0
  198. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +26 -0
  199. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +28 -0
  200. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-tool-error.mdx +26 -0
  201. package/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx +24 -0
  202. package/docs/07-reference/05-ai-sdk-errors/ai-no-video-generated-error.mdx +39 -0
  203. package/docs/07-reference/05-ai-sdk-errors/ai-retry-error.mdx +27 -0
  204. package/docs/07-reference/05-ai-sdk-errors/ai-too-many-embedding-values-for-call-error.mdx +27 -0
  205. package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-not-found-for-approval-error.mdx +25 -0
  206. package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-repair-error.mdx +28 -0
  207. package/docs/07-reference/05-ai-sdk-errors/ai-type-validation-error.mdx +25 -0
  208. package/docs/07-reference/05-ai-sdk-errors/ai-ui-message-stream-error.mdx +67 -0
  209. package/docs/07-reference/05-ai-sdk-errors/ai-unsupported-functionality-error.mdx +25 -0
  210. package/docs/07-reference/05-ai-sdk-errors/index.mdx +39 -0
  211. package/docs/07-reference/index.mdx +28 -0
  212. package/docs/08-migration-guides/00-versioning.mdx +46 -0
  213. package/docs/08-migration-guides/23-migration-guide-7-0.mdx +95 -0
  214. package/docs/08-migration-guides/24-migration-guide-6-0.mdx +823 -0
  215. package/docs/08-migration-guides/25-migration-guide-5-0-data.mdx +882 -0
  216. package/docs/08-migration-guides/26-migration-guide-5-0.mdx +3427 -0
  217. package/docs/08-migration-guides/27-migration-guide-4-2.mdx +99 -0
  218. package/docs/08-migration-guides/28-migration-guide-4-1.mdx +14 -0
  219. package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1157 -0
  220. package/docs/08-migration-guides/36-migration-guide-3-4.mdx +14 -0
  221. package/docs/08-migration-guides/37-migration-guide-3-3.mdx +64 -0
  222. package/docs/08-migration-guides/38-migration-guide-3-2.mdx +46 -0
  223. package/docs/08-migration-guides/39-migration-guide-3-1.mdx +168 -0
  224. package/docs/08-migration-guides/index.mdx +22 -0
  225. package/docs/09-troubleshooting/01-azure-stream-slow.mdx +33 -0
  226. package/docs/09-troubleshooting/03-server-actions-in-client-components.mdx +40 -0
  227. package/docs/09-troubleshooting/04-strange-stream-output.mdx +36 -0
  228. package/docs/09-troubleshooting/05-streamable-ui-errors.mdx +16 -0
  229. package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +106 -0
  230. package/docs/09-troubleshooting/06-streaming-not-working-when-deployed.mdx +31 -0
  231. package/docs/09-troubleshooting/06-streaming-not-working-when-proxied.mdx +31 -0
  232. package/docs/09-troubleshooting/06-timeout-on-vercel.mdx +60 -0
  233. package/docs/09-troubleshooting/07-unclosed-streams.mdx +34 -0
  234. package/docs/09-troubleshooting/08-use-chat-failed-to-parse-stream.mdx +26 -0
  235. package/docs/09-troubleshooting/09-client-stream-error.mdx +25 -0
  236. package/docs/09-troubleshooting/10-use-chat-tools-no-response.mdx +32 -0
  237. package/docs/09-troubleshooting/11-use-chat-custom-request-options.mdx +149 -0
  238. package/docs/09-troubleshooting/12-typescript-performance-zod.mdx +46 -0
  239. package/docs/09-troubleshooting/12-use-chat-an-error-occurred.mdx +59 -0
  240. package/docs/09-troubleshooting/13-repeated-assistant-messages.mdx +73 -0
  241. package/docs/09-troubleshooting/14-stream-abort-handling.mdx +73 -0
  242. package/docs/09-troubleshooting/14-tool-calling-with-structured-outputs.mdx +48 -0
  243. package/docs/09-troubleshooting/15-abort-breaks-resumable-streams.mdx +55 -0
  244. package/docs/09-troubleshooting/15-stream-text-not-working.mdx +33 -0
  245. package/docs/09-troubleshooting/16-streaming-status-delay.mdx +63 -0
  246. package/docs/09-troubleshooting/17-use-chat-stale-body-data.mdx +141 -0
  247. package/docs/09-troubleshooting/18-ontoolcall-type-narrowing.mdx +66 -0
  248. package/docs/09-troubleshooting/19-unsupported-model-version.mdx +50 -0
  249. package/docs/09-troubleshooting/20-no-object-generated-content-filter.mdx +76 -0
  250. package/docs/09-troubleshooting/21-missing-tool-results-error.mdx +82 -0
  251. package/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx +21 -0
  252. package/docs/09-troubleshooting/40-typescript-cannot-find-namespace-jsx.mdx +24 -0
  253. package/docs/09-troubleshooting/50-react-maximum-update-depth-exceeded.mdx +39 -0
  254. package/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx +22 -0
  255. package/docs/09-troubleshooting/70-high-memory-usage-with-images.mdx +108 -0
  256. package/docs/09-troubleshooting/index.mdx +11 -0
  257. package/internal.d.ts +1 -0
  258. package/package.json +120 -0
  259. package/src/agent/agent.ts +156 -0
  260. package/src/agent/create-agent-ui-stream-response.ts +61 -0
  261. package/src/agent/create-agent-ui-stream.ts +84 -0
  262. package/src/agent/index.ts +37 -0
  263. package/src/agent/infer-agent-tools.ts +7 -0
  264. package/src/agent/infer-agent-ui-message.ts +11 -0
  265. package/src/agent/pipe-agent-ui-stream-to-response.ts +64 -0
  266. package/src/agent/tool-loop-agent-settings.ts +252 -0
  267. package/src/agent/tool-loop-agent.ts +205 -0
  268. package/src/embed/embed-events.ts +181 -0
  269. package/src/embed/embed-many-result.ts +53 -0
  270. package/src/embed/embed-many.ts +428 -0
  271. package/src/embed/embed-result.ts +50 -0
  272. package/src/embed/embed.ts +266 -0
  273. package/src/embed/index.ts +5 -0
  274. package/src/error/index.ts +37 -0
  275. package/src/error/invalid-argument-error.ts +34 -0
  276. package/src/error/invalid-stream-part-error.ts +28 -0
  277. package/src/error/invalid-tool-approval-error.ts +26 -0
  278. package/src/error/invalid-tool-input-error.ts +33 -0
  279. package/src/error/missing-tool-result-error.ts +28 -0
  280. package/src/error/no-image-generated-error.ts +39 -0
  281. package/src/error/no-object-generated-error.ts +70 -0
  282. package/src/error/no-output-generated-error.ts +26 -0
  283. package/src/error/no-speech-generated-error.ts +28 -0
  284. package/src/error/no-such-tool-error.ts +35 -0
  285. package/src/error/no-transcript-generated-error.ts +30 -0
  286. package/src/error/no-video-generated-error.ts +57 -0
  287. package/src/error/tool-call-not-found-for-approval-error.ts +32 -0
  288. package/src/error/tool-call-repair-error.ts +30 -0
  289. package/src/error/ui-message-stream-error.ts +48 -0
  290. package/src/error/unsupported-model-version-error.ts +23 -0
  291. package/src/error/verify-no-object-generated-error.ts +27 -0
  292. package/src/generate-image/generate-image-result.ts +42 -0
  293. package/src/generate-image/generate-image.ts +361 -0
  294. package/src/generate-image/index.ts +18 -0
  295. package/src/generate-object/generate-object-result.ts +67 -0
  296. package/src/generate-object/generate-object.ts +514 -0
  297. package/src/generate-object/index.ts +9 -0
  298. package/src/generate-object/inject-json-instruction.ts +30 -0
  299. package/src/generate-object/output-strategy.ts +415 -0
  300. package/src/generate-object/parse-and-validate-object-result.ts +111 -0
  301. package/src/generate-object/repair-text.ts +12 -0
  302. package/src/generate-object/stream-object-result.ts +120 -0
  303. package/src/generate-object/stream-object.ts +984 -0
  304. package/src/generate-object/validate-object-generation-input.ts +144 -0
  305. package/src/generate-speech/generate-speech-result.ts +30 -0
  306. package/src/generate-speech/generate-speech.ts +191 -0
  307. package/src/generate-speech/generated-audio-file.ts +65 -0
  308. package/src/generate-speech/index.ts +3 -0
  309. package/src/generate-text/collect-tool-approvals.ts +116 -0
  310. package/src/generate-text/content-part.ts +31 -0
  311. package/src/generate-text/core-events.ts +390 -0
  312. package/src/generate-text/create-execute-tools-transformation.ts +144 -0
  313. package/src/generate-text/execute-tool-call.ts +190 -0
  314. package/src/generate-text/extract-reasoning-content.ts +17 -0
  315. package/src/generate-text/extract-text-content.ts +15 -0
  316. package/src/generate-text/generate-text-result.ts +168 -0
  317. package/src/generate-text/generate-text.ts +1445 -0
  318. package/src/generate-text/generated-file.ts +70 -0
  319. package/src/generate-text/index.ts +78 -0
  320. package/src/generate-text/invoke-tool-callbacks-from-stream.ts +81 -0
  321. package/src/generate-text/is-approval-needed.ts +29 -0
  322. package/src/generate-text/output-utils.ts +23 -0
  323. package/src/generate-text/output.ts +590 -0
  324. package/src/generate-text/parse-tool-call.ts +188 -0
  325. package/src/generate-text/prepare-step.ts +103 -0
  326. package/src/generate-text/prune-messages.ts +167 -0
  327. package/src/generate-text/reasoning-output.ts +99 -0
  328. package/src/generate-text/reasoning.ts +10 -0
  329. package/src/generate-text/response-message.ts +10 -0
  330. package/src/generate-text/smooth-stream.ts +162 -0
  331. package/src/generate-text/step-result.ts +310 -0
  332. package/src/generate-text/stop-condition.ts +29 -0
  333. package/src/generate-text/stream-model-call.ts +418 -0
  334. package/src/generate-text/stream-text-result.ts +536 -0
  335. package/src/generate-text/stream-text.ts +2696 -0
  336. package/src/generate-text/to-response-messages.ts +195 -0
  337. package/src/generate-text/tool-approval-request-output.ts +21 -0
  338. package/src/generate-text/tool-call-repair-function.ts +27 -0
  339. package/src/generate-text/tool-call.ts +47 -0
  340. package/src/generate-text/tool-error.ts +34 -0
  341. package/src/generate-text/tool-output-denied.ts +21 -0
  342. package/src/generate-text/tool-output.ts +7 -0
  343. package/src/generate-text/tool-result.ts +36 -0
  344. package/src/generate-text/tool-set.ts +14 -0
  345. package/src/generate-video/generate-video-result.ts +36 -0
  346. package/src/generate-video/generate-video.ts +402 -0
  347. package/src/generate-video/index.ts +3 -0
  348. package/src/global.ts +36 -0
  349. package/src/index.ts +49 -0
  350. package/src/logger/index.ts +6 -0
  351. package/src/logger/log-warnings.ts +140 -0
  352. package/src/middleware/add-tool-input-examples-middleware.ts +90 -0
  353. package/src/middleware/default-embedding-settings-middleware.ts +22 -0
  354. package/src/middleware/default-settings-middleware.ts +33 -0
  355. package/src/middleware/extract-json-middleware.ts +197 -0
  356. package/src/middleware/extract-reasoning-middleware.ts +249 -0
  357. package/src/middleware/index.ts +10 -0
  358. package/src/middleware/simulate-streaming-middleware.ts +79 -0
  359. package/src/middleware/wrap-embedding-model.ts +89 -0
  360. package/src/middleware/wrap-image-model.ts +92 -0
  361. package/src/middleware/wrap-language-model.ts +108 -0
  362. package/src/middleware/wrap-provider.ts +51 -0
  363. package/src/model/as-embedding-model-v3.ts +24 -0
  364. package/src/model/as-embedding-model-v4.ts +25 -0
  365. package/src/model/as-image-model-v3.ts +24 -0
  366. package/src/model/as-image-model-v4.ts +21 -0
  367. package/src/model/as-language-model-v3.ts +103 -0
  368. package/src/model/as-language-model-v4.ts +25 -0
  369. package/src/model/as-provider-v3.ts +36 -0
  370. package/src/model/as-provider-v4.ts +47 -0
  371. package/src/model/as-reranking-model-v4.ts +16 -0
  372. package/src/model/as-speech-model-v3.ts +24 -0
  373. package/src/model/as-speech-model-v4.ts +21 -0
  374. package/src/model/as-transcription-model-v3.ts +24 -0
  375. package/src/model/as-transcription-model-v4.ts +25 -0
  376. package/src/model/as-video-model-v4.ts +19 -0
  377. package/src/model/resolve-model.ts +172 -0
  378. package/src/prompt/call-settings.ts +169 -0
  379. package/src/prompt/content-part.ts +236 -0
  380. package/src/prompt/convert-to-language-model-prompt.ts +548 -0
  381. package/src/prompt/create-tool-model-output.ts +34 -0
  382. package/src/prompt/data-content.ts +134 -0
  383. package/src/prompt/index.ts +27 -0
  384. package/src/prompt/invalid-data-content-error.ts +29 -0
  385. package/src/prompt/invalid-message-role-error.ts +27 -0
  386. package/src/prompt/message-conversion-error.ts +28 -0
  387. package/src/prompt/message.ts +72 -0
  388. package/src/prompt/prepare-call-settings.ts +110 -0
  389. package/src/prompt/prepare-tools-and-tool-choice.ts +86 -0
  390. package/src/prompt/prompt.ts +43 -0
  391. package/src/prompt/split-data-url.ts +17 -0
  392. package/src/prompt/standardize-prompt.ts +99 -0
  393. package/src/prompt/wrap-gateway-error.ts +29 -0
  394. package/src/registry/custom-provider.ts +210 -0
  395. package/src/registry/index.ts +7 -0
  396. package/src/registry/no-such-provider-error.ts +41 -0
  397. package/src/registry/provider-registry.ts +331 -0
  398. package/src/rerank/index.ts +8 -0
  399. package/src/rerank/rerank-events.ts +189 -0
  400. package/src/rerank/rerank-result.ts +70 -0
  401. package/src/rerank/rerank.ts +348 -0
  402. package/src/telemetry/assemble-operation-name.ts +21 -0
  403. package/src/telemetry/get-base-telemetry-attributes.ts +45 -0
  404. package/src/telemetry/get-global-telemetry-integration.ts +126 -0
  405. package/src/telemetry/get-tracer.ts +20 -0
  406. package/src/telemetry/index.ts +4 -0
  407. package/src/telemetry/noop-tracer.ts +69 -0
  408. package/src/telemetry/open-telemetry-integration.ts +875 -0
  409. package/src/telemetry/record-span.ts +75 -0
  410. package/src/telemetry/select-telemetry-attributes.ts +78 -0
  411. package/src/telemetry/stringify-for-telemetry.ts +33 -0
  412. package/src/telemetry/telemetry-integration-registry.ts +22 -0
  413. package/src/telemetry/telemetry-integration.ts +139 -0
  414. package/src/telemetry/telemetry-settings.ts +55 -0
  415. package/src/test/mock-embedding-model-v2.ts +35 -0
  416. package/src/test/mock-embedding-model-v3.ts +48 -0
  417. package/src/test/mock-embedding-model-v4.ts +48 -0
  418. package/src/test/mock-image-model-v2.ts +28 -0
  419. package/src/test/mock-image-model-v3.ts +28 -0
  420. package/src/test/mock-image-model-v4.ts +28 -0
  421. package/src/test/mock-language-model-v2.ts +72 -0
  422. package/src/test/mock-language-model-v3.ts +77 -0
  423. package/src/test/mock-language-model-v4.ts +77 -0
  424. package/src/test/mock-provider-v2.ts +68 -0
  425. package/src/test/mock-provider-v3.ts +80 -0
  426. package/src/test/mock-provider-v4.ts +80 -0
  427. package/src/test/mock-reranking-model-v3.ts +25 -0
  428. package/src/test/mock-reranking-model-v4.ts +25 -0
  429. package/src/test/mock-server-response.ts +69 -0
  430. package/src/test/mock-speech-model-v2.ts +24 -0
  431. package/src/test/mock-speech-model-v3.ts +24 -0
  432. package/src/test/mock-speech-model-v4.ts +24 -0
  433. package/src/test/mock-tracer.ts +156 -0
  434. package/src/test/mock-transcription-model-v2.ts +24 -0
  435. package/src/test/mock-transcription-model-v3.ts +24 -0
  436. package/src/test/mock-transcription-model-v4.ts +24 -0
  437. package/src/test/mock-values.ts +4 -0
  438. package/src/test/mock-video-model-v3.ts +28 -0
  439. package/src/test/mock-video-model-v4.ts +28 -0
  440. package/src/test/not-implemented.ts +3 -0
  441. package/src/text-stream/create-text-stream-response.ts +30 -0
  442. package/src/text-stream/index.ts +2 -0
  443. package/src/text-stream/pipe-text-stream-to-response.ts +38 -0
  444. package/src/transcribe/index.ts +2 -0
  445. package/src/transcribe/transcribe-result.ts +60 -0
  446. package/src/transcribe/transcribe.ts +187 -0
  447. package/src/types/embedding-model-middleware.ts +15 -0
  448. package/src/types/embedding-model.ts +20 -0
  449. package/src/types/image-model-middleware.ts +15 -0
  450. package/src/types/image-model-response-metadata.ts +16 -0
  451. package/src/types/image-model.ts +19 -0
  452. package/src/types/index.ts +29 -0
  453. package/src/types/json-value.ts +15 -0
  454. package/src/types/language-model-middleware.ts +15 -0
  455. package/src/types/language-model-request-metadata.ts +6 -0
  456. package/src/types/language-model-response-metadata.ts +21 -0
  457. package/src/types/language-model.ts +106 -0
  458. package/src/types/provider-metadata.ts +16 -0
  459. package/src/types/provider.ts +55 -0
  460. package/src/types/reranking-model.ts +6 -0
  461. package/src/types/speech-model-response-metadata.ts +21 -0
  462. package/src/types/speech-model.ts +10 -0
  463. package/src/types/transcription-model-response-metadata.ts +16 -0
  464. package/src/types/transcription-model.ts +14 -0
  465. package/src/types/usage.ts +200 -0
  466. package/src/types/video-model-response-metadata.ts +28 -0
  467. package/src/types/video-model.ts +15 -0
  468. package/src/types/warning.ts +7 -0
  469. package/src/ui/call-completion-api.ts +157 -0
  470. package/src/ui/chat-transport.ts +83 -0
  471. package/src/ui/chat.ts +786 -0
  472. package/src/ui/convert-file-list-to-file-ui-parts.ts +36 -0
  473. package/src/ui/convert-to-model-messages.ts +403 -0
  474. package/src/ui/default-chat-transport.ts +36 -0
  475. package/src/ui/direct-chat-transport.ts +117 -0
  476. package/src/ui/http-chat-transport.ts +273 -0
  477. package/src/ui/index.ts +76 -0
  478. package/src/ui/last-assistant-message-is-complete-with-approval-responses.ts +44 -0
  479. package/src/ui/last-assistant-message-is-complete-with-tool-calls.ts +39 -0
  480. package/src/ui/process-text-stream.ts +16 -0
  481. package/src/ui/process-ui-message-stream.ts +858 -0
  482. package/src/ui/text-stream-chat-transport.ts +23 -0
  483. package/src/ui/transform-text-to-ui-message-stream.ts +27 -0
  484. package/src/ui/ui-messages.ts +602 -0
  485. package/src/ui/use-completion.ts +84 -0
  486. package/src/ui/validate-ui-messages.ts +521 -0
  487. package/src/ui-message-stream/create-ui-message-stream-response.ts +44 -0
  488. package/src/ui-message-stream/create-ui-message-stream.ts +145 -0
  489. package/src/ui-message-stream/get-response-ui-message-id.ts +35 -0
  490. package/src/ui-message-stream/handle-ui-message-stream-finish.ts +170 -0
  491. package/src/ui-message-stream/index.ts +14 -0
  492. package/src/ui-message-stream/json-to-sse-transform-stream.ts +17 -0
  493. package/src/ui-message-stream/pipe-ui-message-stream-to-response.ts +51 -0
  494. package/src/ui-message-stream/read-ui-message-stream.ts +87 -0
  495. package/src/ui-message-stream/ui-message-chunks.ts +372 -0
  496. package/src/ui-message-stream/ui-message-stream-headers.ts +7 -0
  497. package/src/ui-message-stream/ui-message-stream-on-finish-callback.ts +32 -0
  498. package/src/ui-message-stream/ui-message-stream-on-step-finish-callback.ts +25 -0
  499. package/src/ui-message-stream/ui-message-stream-response-init.ts +14 -0
  500. package/src/ui-message-stream/ui-message-stream-writer.ts +24 -0
  501. package/src/util/as-array.ts +3 -0
  502. package/src/util/async-iterable-stream.ts +94 -0
  503. package/src/util/consume-stream.ts +31 -0
  504. package/src/util/cosine-similarity.ts +46 -0
  505. package/src/util/create-resolvable-promise.ts +30 -0
  506. package/src/util/create-stitchable-stream.ts +112 -0
  507. package/src/util/data-url.ts +17 -0
  508. package/src/util/deep-partial.ts +84 -0
  509. package/src/util/detect-media-type.ts +226 -0
  510. package/src/util/download/create-download.ts +13 -0
  511. package/src/util/download/download-function.ts +45 -0
  512. package/src/util/download/download.ts +74 -0
  513. package/src/util/error-handler.ts +1 -0
  514. package/src/util/fix-json.ts +401 -0
  515. package/src/util/get-potential-start-index.ts +39 -0
  516. package/src/util/index.ts +12 -0
  517. package/src/util/is-deep-equal-data.ts +48 -0
  518. package/src/util/is-non-empty-object.ts +5 -0
  519. package/src/util/job.ts +1 -0
  520. package/src/util/log-v2-compatibility-warning.ts +21 -0
  521. package/src/util/merge-abort-signals.ts +43 -0
  522. package/src/util/merge-objects.ts +79 -0
  523. package/src/util/notify.ts +22 -0
  524. package/src/util/now.ts +4 -0
  525. package/src/util/parse-partial-json.ts +30 -0
  526. package/src/util/prepare-headers.ts +14 -0
  527. package/src/util/prepare-retries.ts +47 -0
  528. package/src/util/retry-error.ts +41 -0
  529. package/src/util/retry-with-exponential-backoff.ts +154 -0
  530. package/src/util/serial-job-executor.ts +36 -0
  531. package/src/util/simulate-readable-stream.ts +39 -0
  532. package/src/util/split-array.ts +20 -0
  533. package/src/util/value-of.ts +65 -0
  534. package/src/util/write-to-server-response.ts +49 -0
  535. package/src/version.ts +5 -0
  536. package/test.d.ts +1 -0
package/src/ui/chat.ts ADDED
@@ -0,0 +1,786 @@
1
+ import {
2
+ FlexibleSchema,
3
+ generateId as generateIdFunc,
4
+ IdGenerator,
5
+ InferSchema,
6
+ } from '@ai-sdk/provider-utils';
7
+ import { FinishReason } from '../types/language-model';
8
+ import { UIMessageChunk } from '../ui-message-stream/ui-message-chunks';
9
+ import { consumeStream } from '../util/consume-stream';
10
+ import { SerialJobExecutor } from '../util/serial-job-executor';
11
+ import { ChatTransport } from './chat-transport';
12
+ import { convertFileListToFileUIParts } from './convert-file-list-to-file-ui-parts';
13
+ import { DefaultChatTransport } from './default-chat-transport';
14
+ import {
15
+ createStreamingUIMessageState,
16
+ processUIMessageStream,
17
+ StreamingUIMessageState,
18
+ } from './process-ui-message-stream';
19
+ import {
20
+ InferUIMessageToolCall,
21
+ isToolUIPart,
22
+ UIMessagePart,
23
+ UITools,
24
+ type DataUIPart,
25
+ type FileUIPart,
26
+ type InferUIMessageData,
27
+ type InferUIMessageMetadata,
28
+ type InferUIMessageTools,
29
+ type UIDataTypes,
30
+ type UIMessage,
31
+ } from './ui-messages';
32
+
33
+ export type CreateUIMessage<UI_MESSAGE extends UIMessage> = Omit<
34
+ UI_MESSAGE,
35
+ 'id' | 'role'
36
+ > & {
37
+ id?: UI_MESSAGE['id'];
38
+ role?: UI_MESSAGE['role'];
39
+ };
40
+
41
+ export type UIDataPartSchemas = Record<string, FlexibleSchema>;
42
+
43
+ export type UIDataTypesToSchemas<T extends UIDataTypes> = {
44
+ [K in keyof T]: FlexibleSchema<T[K]>;
45
+ };
46
+
47
+ export type InferUIDataParts<T extends UIDataPartSchemas> = {
48
+ [K in keyof T]: InferSchema<T[K]>;
49
+ };
50
+
51
+ export type ChatRequestOptions = {
52
+ /**
53
+ * Additional headers that should be to be passed to the API endpoint.
54
+ */
55
+ headers?: Record<string, string> | Headers;
56
+
57
+ /**
58
+ * Additional body JSON properties that should be sent to the API endpoint.
59
+ */
60
+ body?: object; // TODO JSONStringifyable
61
+
62
+ metadata?: unknown;
63
+ };
64
+
65
+ /**
66
+ * Function that can be called to add a tool approval response to the chat.
67
+ */
68
+ export type ChatAddToolApproveResponseFunction = ({
69
+ id,
70
+ approved,
71
+ reason,
72
+ options,
73
+ }: {
74
+ id: string;
75
+
76
+ /**
77
+ * Flag indicating whether the approval was granted or denied.
78
+ */
79
+ approved: boolean;
80
+
81
+ /**
82
+ * Optional reason for the approval or denial.
83
+ */
84
+ reason?: string;
85
+
86
+ /**
87
+ * Optional request options to be used if `sendAutomaticallyWhen` callback returns true.
88
+ */
89
+ options?: ChatRequestOptions;
90
+ }) => void | PromiseLike<void>;
91
+
92
+ /**
93
+ * Function that can be called to add a tool output to the chat.
94
+ */
95
+ export type ChatAddToolOutputFunction<UI_MESSAGE extends UIMessage> = <
96
+ TOOL extends keyof InferUIMessageTools<UI_MESSAGE>,
97
+ >({
98
+ state,
99
+ tool,
100
+ toolCallId,
101
+ output,
102
+ errorText,
103
+ options,
104
+ }: {
105
+ /**
106
+ * Name of the tool that was called.
107
+ */
108
+ tool: TOOL;
109
+
110
+ /**
111
+ * Identifier of the tool call to add output for.
112
+ */
113
+ toolCallId: string;
114
+
115
+ /**
116
+ * Optional request options to be used if `sendAutomaticallyWhen` callback returns true.
117
+ */
118
+ options?: ChatRequestOptions;
119
+ } & (
120
+ | {
121
+ state?: 'output-available';
122
+ output: InferUIMessageTools<UI_MESSAGE>[TOOL]['output'];
123
+ errorText?: never;
124
+ }
125
+ | {
126
+ state: 'output-error';
127
+ output?: never;
128
+ errorText: string;
129
+ }
130
+ )) => void | PromiseLike<void>;
131
+
132
+ export type ChatStatus = 'submitted' | 'streaming' | 'ready' | 'error';
133
+
134
+ type ActiveResponse<UI_MESSAGE extends UIMessage> = {
135
+ state: StreamingUIMessageState<UI_MESSAGE>;
136
+ abortController: AbortController;
137
+ };
138
+
139
+ export interface ChatState<UI_MESSAGE extends UIMessage> {
140
+ status: ChatStatus;
141
+
142
+ error: Error | undefined;
143
+
144
+ messages: UI_MESSAGE[];
145
+ pushMessage: (message: UI_MESSAGE) => void;
146
+ popMessage: () => void;
147
+ replaceMessage: (index: number, message: UI_MESSAGE) => void;
148
+
149
+ snapshot: <T>(thing: T) => T;
150
+ }
151
+
152
+ export type ChatOnErrorCallback = (error: Error) => void;
153
+
154
+ export type ChatOnToolCallCallback<UI_MESSAGE extends UIMessage = UIMessage> =
155
+ (options: {
156
+ toolCall: InferUIMessageToolCall<UI_MESSAGE>;
157
+ }) => void | PromiseLike<void>;
158
+
159
+ export type ChatOnDataCallback<UI_MESSAGE extends UIMessage> = (
160
+ dataPart: DataUIPart<InferUIMessageData<UI_MESSAGE>>,
161
+ ) => void;
162
+
163
+ /**
164
+ * Function that is called when the assistant response has finished streaming.
165
+ *
166
+ * @param message The assistant message that was streamed.
167
+ * @param messages The full chat history, including the assistant message.
168
+ *
169
+ * @param isAbort Indicates whether the request has been aborted.
170
+ * @param isDisconnect Indicates whether the request has been ended by a network error.
171
+ * @param isError Indicates whether the request has been ended by an error.
172
+ * @param finishReason The reason why the generation finished.
173
+ */
174
+ export type ChatOnFinishCallback<UI_MESSAGE extends UIMessage> = (options: {
175
+ message: UI_MESSAGE;
176
+ messages: UI_MESSAGE[];
177
+ isAbort: boolean;
178
+ isDisconnect: boolean;
179
+ isError: boolean;
180
+ finishReason?: FinishReason;
181
+ }) => void;
182
+
183
+ export interface ChatInit<UI_MESSAGE extends UIMessage> {
184
+ /**
185
+ * A unique identifier for the chat. If not provided, a random one will be
186
+ * generated.
187
+ */
188
+ id?: string;
189
+
190
+ messageMetadataSchema?: FlexibleSchema<InferUIMessageMetadata<UI_MESSAGE>>;
191
+ dataPartSchemas?: UIDataTypesToSchemas<InferUIMessageData<UI_MESSAGE>>;
192
+
193
+ messages?: UI_MESSAGE[];
194
+
195
+ /**
196
+ * A way to provide a function that is going to be used for ids for messages and the chat.
197
+ * If not provided the default AI SDK `generateId` is used.
198
+ */
199
+ generateId?: IdGenerator;
200
+
201
+ transport?: ChatTransport<UI_MESSAGE>;
202
+
203
+ /**
204
+ * Callback function to be called when an error is encountered.
205
+ */
206
+ onError?: ChatOnErrorCallback;
207
+
208
+ /**
209
+ * Optional callback function that is invoked when a tool call is received.
210
+ * Intended for automatic client-side tool execution.
211
+ *
212
+ * You can optionally return a result for the tool call,
213
+ * either synchronously or asynchronously.
214
+ */
215
+ onToolCall?: ChatOnToolCallCallback<UI_MESSAGE>;
216
+
217
+ /**
218
+ * Function that is called when the assistant response has finished streaming.
219
+ */
220
+ onFinish?: ChatOnFinishCallback<UI_MESSAGE>;
221
+
222
+ /**
223
+ * Optional callback function that is called when a data part is received.
224
+ *
225
+ * @param data The data part that was received.
226
+ */
227
+ onData?: ChatOnDataCallback<UI_MESSAGE>;
228
+
229
+ /**
230
+ * When provided, this function will be called when the stream is finished or a tool call is added
231
+ * to determine if the current messages should be resubmitted.
232
+ */
233
+ sendAutomaticallyWhen?: (options: {
234
+ messages: UI_MESSAGE[];
235
+ }) => boolean | PromiseLike<boolean>;
236
+ }
237
+
238
+ export abstract class AbstractChat<UI_MESSAGE extends UIMessage> {
239
+ readonly id: string;
240
+ readonly generateId: IdGenerator;
241
+
242
+ protected state: ChatState<UI_MESSAGE>;
243
+
244
+ private messageMetadataSchema:
245
+ | FlexibleSchema<InferUIMessageMetadata<UI_MESSAGE>>
246
+ | undefined;
247
+ private dataPartSchemas:
248
+ | UIDataTypesToSchemas<InferUIMessageData<UI_MESSAGE>>
249
+ | undefined;
250
+ private readonly transport: ChatTransport<UI_MESSAGE>;
251
+ private onError?: ChatInit<UI_MESSAGE>['onError'];
252
+ private onToolCall?: ChatInit<UI_MESSAGE>['onToolCall'];
253
+ private onFinish?: ChatInit<UI_MESSAGE>['onFinish'];
254
+ private onData?: ChatInit<UI_MESSAGE>['onData'];
255
+ private sendAutomaticallyWhen?: ChatInit<UI_MESSAGE>['sendAutomaticallyWhen'];
256
+
257
+ private activeResponse: ActiveResponse<UI_MESSAGE> | undefined = undefined;
258
+ private jobExecutor = new SerialJobExecutor();
259
+
260
+ constructor({
261
+ generateId = generateIdFunc,
262
+ id = generateId(),
263
+ transport = new DefaultChatTransport(),
264
+ messageMetadataSchema,
265
+ dataPartSchemas,
266
+ state,
267
+ onError,
268
+ onToolCall,
269
+ onFinish,
270
+ onData,
271
+ sendAutomaticallyWhen,
272
+ }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {
273
+ state: ChatState<UI_MESSAGE>;
274
+ }) {
275
+ this.id = id;
276
+ this.transport = transport;
277
+ this.generateId = generateId;
278
+ this.messageMetadataSchema = messageMetadataSchema;
279
+ this.dataPartSchemas = dataPartSchemas;
280
+ this.state = state;
281
+ this.onError = onError;
282
+ this.onToolCall = onToolCall;
283
+ this.onFinish = onFinish;
284
+ this.onData = onData;
285
+ this.sendAutomaticallyWhen = sendAutomaticallyWhen;
286
+ }
287
+
288
+ /**
289
+ * Hook status:
290
+ *
291
+ * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
292
+ * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
293
+ * - `ready`: The full response has been received and processed; a new user message can be submitted.
294
+ * - `error`: An error occurred during the API request, preventing successful completion.
295
+ */
296
+ get status(): ChatStatus {
297
+ return this.state.status;
298
+ }
299
+
300
+ protected setStatus({
301
+ status,
302
+ error,
303
+ }: {
304
+ status: ChatStatus;
305
+ error?: Error;
306
+ }) {
307
+ if (this.status === status) return;
308
+
309
+ this.state.status = status;
310
+ this.state.error = error;
311
+ }
312
+
313
+ get error() {
314
+ return this.state.error;
315
+ }
316
+
317
+ get messages(): UI_MESSAGE[] {
318
+ return this.state.messages;
319
+ }
320
+
321
+ get lastMessage(): UI_MESSAGE | undefined {
322
+ return this.state.messages[this.state.messages.length - 1];
323
+ }
324
+
325
+ set messages(messages: UI_MESSAGE[]) {
326
+ this.state.messages = messages;
327
+ }
328
+
329
+ /**
330
+ * Appends or replaces a user message to the chat list. This triggers the API call to fetch
331
+ * the assistant's response.
332
+ *
333
+ * If a messageId is provided, the message will be replaced.
334
+ */
335
+ sendMessage = async (
336
+ message?:
337
+ | (CreateUIMessage<UI_MESSAGE> & {
338
+ text?: never;
339
+ files?: never;
340
+ messageId?: string;
341
+ })
342
+ | {
343
+ text: string;
344
+ files?: FileList | FileUIPart[];
345
+ metadata?: InferUIMessageMetadata<UI_MESSAGE>;
346
+ parts?: never;
347
+ messageId?: string;
348
+ }
349
+ | {
350
+ files: FileList | FileUIPart[];
351
+ metadata?: InferUIMessageMetadata<UI_MESSAGE>;
352
+ parts?: never;
353
+ messageId?: string;
354
+ },
355
+ options?: ChatRequestOptions,
356
+ ): Promise<void> => {
357
+ if (message == null) {
358
+ await this.makeRequest({
359
+ trigger: 'submit-message',
360
+ messageId: this.lastMessage?.id,
361
+ ...options,
362
+ });
363
+ return;
364
+ }
365
+
366
+ let uiMessage: CreateUIMessage<UI_MESSAGE>;
367
+
368
+ if ('text' in message || 'files' in message) {
369
+ const fileParts = Array.isArray(message.files)
370
+ ? message.files
371
+ : await convertFileListToFileUIParts(message.files);
372
+
373
+ uiMessage = {
374
+ parts: [
375
+ ...fileParts,
376
+ ...('text' in message && message.text != null
377
+ ? [{ type: 'text' as const, text: message.text }]
378
+ : []),
379
+ ],
380
+ } as UI_MESSAGE;
381
+ } else {
382
+ uiMessage = message;
383
+ }
384
+
385
+ if (message.messageId != null) {
386
+ const messageIndex = this.state.messages.findIndex(
387
+ m => m.id === message.messageId,
388
+ );
389
+
390
+ if (messageIndex === -1) {
391
+ throw new Error(`message with id ${message.messageId} not found`);
392
+ }
393
+
394
+ if (this.state.messages[messageIndex].role !== 'user') {
395
+ throw new Error(
396
+ `message with id ${message.messageId} is not a user message`,
397
+ );
398
+ }
399
+
400
+ // remove all messages after the message with the given id
401
+ this.state.messages = this.state.messages.slice(0, messageIndex + 1);
402
+
403
+ // update the message with the new content
404
+ this.state.replaceMessage(messageIndex, {
405
+ ...uiMessage,
406
+ id: message.messageId,
407
+ role: uiMessage.role ?? 'user',
408
+ metadata: message.metadata,
409
+ } as UI_MESSAGE);
410
+ } else {
411
+ this.state.pushMessage({
412
+ ...uiMessage,
413
+ id: uiMessage.id ?? this.generateId(),
414
+ role: uiMessage.role ?? 'user',
415
+ metadata: message.metadata,
416
+ } as UI_MESSAGE);
417
+ }
418
+
419
+ await this.makeRequest({
420
+ trigger: 'submit-message',
421
+ messageId: message.messageId,
422
+ ...options,
423
+ });
424
+ };
425
+
426
+ /**
427
+ * Regenerate the assistant message with the provided message id.
428
+ * If no message id is provided, the last assistant message will be regenerated.
429
+ */
430
+ regenerate = async ({
431
+ messageId,
432
+ ...options
433
+ }: {
434
+ messageId?: string;
435
+ } & ChatRequestOptions = {}): Promise<void> => {
436
+ const messageIndex =
437
+ messageId == null
438
+ ? this.state.messages.length - 1
439
+ : this.state.messages.findIndex(message => message.id === messageId);
440
+
441
+ if (messageIndex === -1) {
442
+ throw new Error(`message ${messageId} not found`);
443
+ }
444
+
445
+ // set the messages to the message before the assistant message
446
+ this.state.messages = this.state.messages.slice(
447
+ 0,
448
+ // if the message is a user message, we need to include it in the request:
449
+ this.messages[messageIndex].role === 'assistant'
450
+ ? messageIndex
451
+ : messageIndex + 1,
452
+ );
453
+
454
+ await this.makeRequest({
455
+ trigger: 'regenerate-message',
456
+ messageId,
457
+ ...options,
458
+ });
459
+ };
460
+
461
+ /**
462
+ * Attempt to resume an ongoing streaming response.
463
+ */
464
+ resumeStream = async (options: ChatRequestOptions = {}): Promise<void> => {
465
+ await this.makeRequest({ trigger: 'resume-stream', ...options });
466
+ };
467
+
468
+ /**
469
+ * Clear the error state and set the status to ready if the chat is in an error state.
470
+ */
471
+ clearError = () => {
472
+ if (this.status === 'error') {
473
+ this.state.error = undefined;
474
+ this.setStatus({ status: 'ready' });
475
+ }
476
+ };
477
+
478
+ addToolApprovalResponse: ChatAddToolApproveResponseFunction = async ({
479
+ id,
480
+ approved,
481
+ reason,
482
+ options,
483
+ }) =>
484
+ this.jobExecutor.run(async () => {
485
+ const messages = this.state.messages;
486
+ const lastMessage = messages[messages.length - 1];
487
+
488
+ const updatePart = (
489
+ part: UIMessagePart<UIDataTypes, UITools>,
490
+ ): UIMessagePart<UIDataTypes, UITools> =>
491
+ isToolUIPart(part) &&
492
+ part.state === 'approval-requested' &&
493
+ part.approval.id === id
494
+ ? {
495
+ ...part,
496
+ state: 'approval-responded',
497
+ approval: { id, approved, reason },
498
+ }
499
+ : part;
500
+
501
+ // update the message to trigger an immediate UI update
502
+ this.state.replaceMessage(messages.length - 1, {
503
+ ...lastMessage,
504
+ parts: lastMessage.parts.map(updatePart),
505
+ });
506
+
507
+ // update the active response if it exists
508
+ if (this.activeResponse) {
509
+ this.activeResponse.state.message.parts =
510
+ this.activeResponse.state.message.parts.map(updatePart);
511
+ }
512
+
513
+ // automatically send the message if the sendAutomaticallyWhen function returns true
514
+ if (
515
+ this.status !== 'streaming' &&
516
+ this.status !== 'submitted' &&
517
+ this.sendAutomaticallyWhen
518
+ ) {
519
+ this.shouldSendAutomatically().then(shouldSend => {
520
+ if (shouldSend) {
521
+ // no await to avoid deadlocking
522
+ this.makeRequest({
523
+ trigger: 'submit-message',
524
+ messageId: this.lastMessage?.id,
525
+ ...options,
526
+ });
527
+ }
528
+ });
529
+ }
530
+ });
531
+
532
+ addToolOutput: ChatAddToolOutputFunction<UI_MESSAGE> = async ({
533
+ state = 'output-available',
534
+ toolCallId,
535
+ output,
536
+ errorText,
537
+ options,
538
+ }) =>
539
+ this.jobExecutor.run(async () => {
540
+ const messages = this.state.messages;
541
+ const lastMessage = messages[messages.length - 1];
542
+
543
+ const updatePart = (
544
+ part: UIMessagePart<UIDataTypes, UITools>,
545
+ ): UIMessagePart<UIDataTypes, UITools> =>
546
+ isToolUIPart(part) && part.toolCallId === toolCallId
547
+ ? ({ ...part, state, output, errorText } as typeof part)
548
+ : part;
549
+
550
+ // update the message to trigger an immediate UI update
551
+ this.state.replaceMessage(messages.length - 1, {
552
+ ...lastMessage,
553
+ parts: lastMessage.parts.map(updatePart),
554
+ });
555
+
556
+ // update the active response if it exists
557
+ if (this.activeResponse) {
558
+ this.activeResponse.state.message.parts =
559
+ this.activeResponse.state.message.parts.map(updatePart);
560
+ }
561
+
562
+ // automatically send the message if the sendAutomaticallyWhen function returns true
563
+ if (
564
+ this.status !== 'streaming' &&
565
+ this.status !== 'submitted' &&
566
+ this.sendAutomaticallyWhen
567
+ ) {
568
+ this.shouldSendAutomatically().then(shouldSend => {
569
+ if (shouldSend) {
570
+ // no await to avoid deadlocking
571
+ this.makeRequest({
572
+ trigger: 'submit-message',
573
+ messageId: this.lastMessage?.id,
574
+ ...options,
575
+ });
576
+ }
577
+ });
578
+ }
579
+ });
580
+
581
+ /** @deprecated Use addToolOutput */
582
+ addToolResult = this.addToolOutput;
583
+
584
+ /**
585
+ * Abort the current request immediately, keep the generated tokens if any.
586
+ */
587
+ stop = async () => {
588
+ if (this.status !== 'streaming' && this.status !== 'submitted') return;
589
+
590
+ if (this.activeResponse?.abortController) {
591
+ this.activeResponse.abortController.abort();
592
+ }
593
+ };
594
+
595
+ private async shouldSendAutomatically(): Promise<boolean> {
596
+ if (!this.sendAutomaticallyWhen) return false;
597
+
598
+ const result = this.sendAutomaticallyWhen({
599
+ messages: this.state.messages,
600
+ });
601
+
602
+ // Check if result is a promise
603
+ if (result && typeof result === 'object' && 'then' in result) {
604
+ return await result;
605
+ }
606
+
607
+ return result as boolean;
608
+ }
609
+
610
+ private async makeRequest({
611
+ trigger,
612
+ metadata,
613
+ headers,
614
+ body,
615
+ messageId,
616
+ }: {
617
+ trigger: 'submit-message' | 'resume-stream' | 'regenerate-message';
618
+ messageId?: string;
619
+ } & ChatRequestOptions) {
620
+ // For resume-stream, check if there's an active stream before
621
+ // changing status. This avoids a brief flash of 'submitted' status
622
+ // when there is no stream to resume (e.g. on page load).
623
+ let resumeStream: ReadableStream<UIMessageChunk> | undefined;
624
+ if (trigger === 'resume-stream') {
625
+ try {
626
+ const reconnect = await this.transport.reconnectToStream({
627
+ chatId: this.id,
628
+ metadata,
629
+ headers,
630
+ body,
631
+ });
632
+
633
+ if (reconnect == null) {
634
+ return; // no active stream found, so we do not resume
635
+ }
636
+
637
+ resumeStream = reconnect;
638
+ } catch (err) {
639
+ if (this.onError && err instanceof Error) {
640
+ this.onError(err);
641
+ }
642
+ this.setStatus({ status: 'error', error: err as Error });
643
+ return;
644
+ }
645
+ }
646
+
647
+ this.setStatus({ status: 'submitted', error: undefined });
648
+
649
+ const lastMessage = this.lastMessage;
650
+
651
+ let isAbort = false;
652
+ let isDisconnect = false;
653
+ let isError = false;
654
+
655
+ try {
656
+ const activeResponse = {
657
+ state: createStreamingUIMessageState({
658
+ lastMessage: this.state.snapshot(lastMessage),
659
+ messageId: this.generateId(),
660
+ }),
661
+ abortController: new AbortController(),
662
+ } as ActiveResponse<UI_MESSAGE>;
663
+
664
+ activeResponse.abortController.signal.addEventListener('abort', () => {
665
+ isAbort = true;
666
+ });
667
+
668
+ this.activeResponse = activeResponse;
669
+
670
+ let stream: ReadableStream<UIMessageChunk>;
671
+
672
+ if (trigger === 'resume-stream') {
673
+ stream = resumeStream!;
674
+ } else {
675
+ stream = await this.transport.sendMessages({
676
+ chatId: this.id,
677
+ messages: this.state.messages,
678
+ abortSignal: activeResponse.abortController.signal,
679
+ metadata,
680
+ headers,
681
+ body,
682
+ trigger,
683
+ messageId,
684
+ });
685
+ }
686
+
687
+ const runUpdateMessageJob = (
688
+ job: (options: {
689
+ state: StreamingUIMessageState<UI_MESSAGE>;
690
+ write: () => void;
691
+ }) => Promise<void>,
692
+ ) =>
693
+ // serialize the job execution to avoid race conditions:
694
+ this.jobExecutor.run(() =>
695
+ job({
696
+ state: activeResponse.state,
697
+ write: () => {
698
+ // streaming is set on first write (before it should be "submitted")
699
+ this.setStatus({ status: 'streaming' });
700
+
701
+ const replaceLastMessage =
702
+ activeResponse.state.message.id === this.lastMessage?.id;
703
+
704
+ if (replaceLastMessage) {
705
+ this.state.replaceMessage(
706
+ this.state.messages.length - 1,
707
+ activeResponse.state.message,
708
+ );
709
+ } else {
710
+ this.state.pushMessage(activeResponse.state.message);
711
+ }
712
+ },
713
+ }),
714
+ );
715
+
716
+ await consumeStream({
717
+ stream: processUIMessageStream({
718
+ stream,
719
+ onToolCall: this.onToolCall,
720
+ onData: this.onData,
721
+ messageMetadataSchema: this.messageMetadataSchema,
722
+ dataPartSchemas: this.dataPartSchemas,
723
+ runUpdateMessageJob,
724
+ onError: error => {
725
+ throw error;
726
+ },
727
+ }),
728
+ onError: error => {
729
+ throw error;
730
+ },
731
+ });
732
+
733
+ this.setStatus({ status: 'ready' });
734
+ } catch (err) {
735
+ // Ignore abort errors as they are expected.
736
+ if (isAbort || (err as any).name === 'AbortError') {
737
+ isAbort = true;
738
+ this.setStatus({ status: 'ready' });
739
+ return null;
740
+ }
741
+
742
+ isError = true;
743
+
744
+ // Network errors such as disconnected, timeout, etc.
745
+ if (
746
+ err instanceof TypeError &&
747
+ (err.message.toLowerCase().includes('fetch') ||
748
+ err.message.toLowerCase().includes('network'))
749
+ ) {
750
+ isDisconnect = true;
751
+ }
752
+
753
+ if (this.onError && err instanceof Error) {
754
+ this.onError(err);
755
+ }
756
+
757
+ this.setStatus({ status: 'error', error: err as Error });
758
+ } finally {
759
+ try {
760
+ this.onFinish?.({
761
+ message: this.activeResponse!.state.message,
762
+ messages: this.state.messages,
763
+ isAbort,
764
+ isDisconnect,
765
+ isError,
766
+ finishReason: this.activeResponse?.state.finishReason,
767
+ });
768
+ } catch (err) {
769
+ console.error(err);
770
+ }
771
+
772
+ this.activeResponse = undefined;
773
+ }
774
+
775
+ // automatically send the message if the sendAutomaticallyWhen function returns true
776
+ if (!isError && (await this.shouldSendAutomatically())) {
777
+ await this.makeRequest({
778
+ trigger: 'submit-message',
779
+ messageId: this.lastMessage?.id,
780
+ metadata,
781
+ headers,
782
+ body,
783
+ });
784
+ }
785
+ }
786
+ }