ai 6.0.31 → 6.0.32

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 (250) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/dist/internal/index.js +1 -1
  5. package/dist/internal/index.mjs +1 -1
  6. package/docs/00-introduction/index.mdx +76 -0
  7. package/docs/02-foundations/01-overview.mdx +43 -0
  8. package/docs/02-foundations/02-providers-and-models.mdx +163 -0
  9. package/docs/02-foundations/03-prompts.mdx +620 -0
  10. package/docs/02-foundations/04-tools.mdx +160 -0
  11. package/docs/02-foundations/05-streaming.mdx +62 -0
  12. package/docs/02-foundations/index.mdx +43 -0
  13. package/docs/02-getting-started/00-choosing-a-provider.mdx +110 -0
  14. package/docs/02-getting-started/01-navigating-the-library.mdx +85 -0
  15. package/docs/02-getting-started/02-nextjs-app-router.mdx +556 -0
  16. package/docs/02-getting-started/03-nextjs-pages-router.mdx +542 -0
  17. package/docs/02-getting-started/04-svelte.mdx +627 -0
  18. package/docs/02-getting-started/05-nuxt.mdx +566 -0
  19. package/docs/02-getting-started/06-nodejs.mdx +512 -0
  20. package/docs/02-getting-started/07-expo.mdx +766 -0
  21. package/docs/02-getting-started/08-tanstack-start.mdx +583 -0
  22. package/docs/02-getting-started/index.mdx +44 -0
  23. package/docs/03-agents/01-overview.mdx +96 -0
  24. package/docs/03-agents/02-building-agents.mdx +367 -0
  25. package/docs/03-agents/03-workflows.mdx +370 -0
  26. package/docs/03-agents/04-loop-control.mdx +350 -0
  27. package/docs/03-agents/05-configuring-call-options.mdx +286 -0
  28. package/docs/03-agents/index.mdx +40 -0
  29. package/docs/03-ai-sdk-core/01-overview.mdx +33 -0
  30. package/docs/03-ai-sdk-core/05-generating-text.mdx +600 -0
  31. package/docs/03-ai-sdk-core/10-generating-structured-data.mdx +662 -0
  32. package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +1102 -0
  33. package/docs/03-ai-sdk-core/16-mcp-tools.mdx +375 -0
  34. package/docs/03-ai-sdk-core/20-prompt-engineering.mdx +144 -0
  35. package/docs/03-ai-sdk-core/25-settings.mdx +198 -0
  36. package/docs/03-ai-sdk-core/30-embeddings.mdx +247 -0
  37. package/docs/03-ai-sdk-core/31-reranking.mdx +218 -0
  38. package/docs/03-ai-sdk-core/35-image-generation.mdx +341 -0
  39. package/docs/03-ai-sdk-core/36-transcription.mdx +173 -0
  40. package/docs/03-ai-sdk-core/37-speech.mdx +167 -0
  41. package/docs/03-ai-sdk-core/40-middleware.mdx +480 -0
  42. package/docs/03-ai-sdk-core/45-provider-management.mdx +349 -0
  43. package/docs/03-ai-sdk-core/50-error-handling.mdx +149 -0
  44. package/docs/03-ai-sdk-core/55-testing.mdx +218 -0
  45. package/docs/03-ai-sdk-core/60-telemetry.mdx +313 -0
  46. package/docs/03-ai-sdk-core/65-devtools.mdx +107 -0
  47. package/docs/03-ai-sdk-core/index.mdx +88 -0
  48. package/docs/04-ai-sdk-ui/01-overview.mdx +44 -0
  49. package/docs/04-ai-sdk-ui/02-chatbot.mdx +1313 -0
  50. package/docs/04-ai-sdk-ui/03-chatbot-message-persistence.mdx +535 -0
  51. package/docs/04-ai-sdk-ui/03-chatbot-resume-streams.mdx +263 -0
  52. package/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx +682 -0
  53. package/docs/04-ai-sdk-ui/04-generative-user-interfaces.mdx +389 -0
  54. package/docs/04-ai-sdk-ui/05-completion.mdx +186 -0
  55. package/docs/04-ai-sdk-ui/08-object-generation.mdx +344 -0
  56. package/docs/04-ai-sdk-ui/20-streaming-data.mdx +397 -0
  57. package/docs/04-ai-sdk-ui/21-error-handling.mdx +190 -0
  58. package/docs/04-ai-sdk-ui/21-transport.mdx +174 -0
  59. package/docs/04-ai-sdk-ui/24-reading-ui-message-streams.mdx +104 -0
  60. package/docs/04-ai-sdk-ui/25-message-metadata.mdx +152 -0
  61. package/docs/04-ai-sdk-ui/50-stream-protocol.mdx +477 -0
  62. package/docs/04-ai-sdk-ui/index.mdx +64 -0
  63. package/docs/05-ai-sdk-rsc/01-overview.mdx +45 -0
  64. package/docs/05-ai-sdk-rsc/02-streaming-react-components.mdx +209 -0
  65. package/docs/05-ai-sdk-rsc/03-generative-ui-state.mdx +279 -0
  66. package/docs/05-ai-sdk-rsc/03-saving-and-restoring-states.mdx +105 -0
  67. package/docs/05-ai-sdk-rsc/04-multistep-interfaces.mdx +282 -0
  68. package/docs/05-ai-sdk-rsc/05-streaming-values.mdx +158 -0
  69. package/docs/05-ai-sdk-rsc/06-loading-state.mdx +273 -0
  70. package/docs/05-ai-sdk-rsc/08-error-handling.mdx +96 -0
  71. package/docs/05-ai-sdk-rsc/09-authentication.mdx +42 -0
  72. package/docs/05-ai-sdk-rsc/10-migrating-to-ui.mdx +722 -0
  73. package/docs/05-ai-sdk-rsc/index.mdx +58 -0
  74. package/docs/06-advanced/01-prompt-engineering.mdx +96 -0
  75. package/docs/06-advanced/02-stopping-streams.mdx +184 -0
  76. package/docs/06-advanced/03-backpressure.mdx +173 -0
  77. package/docs/06-advanced/04-caching.mdx +169 -0
  78. package/docs/06-advanced/05-multiple-streamables.mdx +68 -0
  79. package/docs/06-advanced/06-rate-limiting.mdx +60 -0
  80. package/docs/06-advanced/07-rendering-ui-with-language-models.mdx +213 -0
  81. package/docs/06-advanced/08-model-as-router.mdx +120 -0
  82. package/docs/06-advanced/09-multistep-interfaces.mdx +115 -0
  83. package/docs/06-advanced/09-sequential-generations.mdx +55 -0
  84. package/docs/06-advanced/10-vercel-deployment-guide.mdx +117 -0
  85. package/docs/06-advanced/index.mdx +11 -0
  86. package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +2142 -0
  87. package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +3215 -0
  88. package/docs/07-reference/01-ai-sdk-core/03-generate-object.mdx +780 -0
  89. package/docs/07-reference/01-ai-sdk-core/04-stream-object.mdx +1140 -0
  90. package/docs/07-reference/01-ai-sdk-core/05-embed.mdx +190 -0
  91. package/docs/07-reference/01-ai-sdk-core/06-embed-many.mdx +171 -0
  92. package/docs/07-reference/01-ai-sdk-core/06-rerank.mdx +309 -0
  93. package/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx +227 -0
  94. package/docs/07-reference/01-ai-sdk-core/11-transcribe.mdx +138 -0
  95. package/docs/07-reference/01-ai-sdk-core/12-generate-speech.mdx +214 -0
  96. package/docs/07-reference/01-ai-sdk-core/15-agent.mdx +203 -0
  97. package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +449 -0
  98. package/docs/07-reference/01-ai-sdk-core/17-create-agent-ui-stream.mdx +148 -0
  99. package/docs/07-reference/01-ai-sdk-core/18-create-agent-ui-stream-response.mdx +168 -0
  100. package/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx +144 -0
  101. package/docs/07-reference/01-ai-sdk-core/20-tool.mdx +196 -0
  102. package/docs/07-reference/01-ai-sdk-core/22-dynamic-tool.mdx +175 -0
  103. package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +410 -0
  104. package/docs/07-reference/01-ai-sdk-core/24-mcp-stdio-transport.mdx +68 -0
  105. package/docs/07-reference/01-ai-sdk-core/25-json-schema.mdx +94 -0
  106. package/docs/07-reference/01-ai-sdk-core/26-zod-schema.mdx +109 -0
  107. package/docs/07-reference/01-ai-sdk-core/27-valibot-schema.mdx +55 -0
  108. package/docs/07-reference/01-ai-sdk-core/28-output.mdx +342 -0
  109. package/docs/07-reference/01-ai-sdk-core/30-model-message.mdx +415 -0
  110. package/docs/07-reference/01-ai-sdk-core/31-ui-message.mdx +246 -0
  111. package/docs/07-reference/01-ai-sdk-core/32-validate-ui-messages.mdx +101 -0
  112. package/docs/07-reference/01-ai-sdk-core/33-safe-validate-ui-messages.mdx +113 -0
  113. package/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +182 -0
  114. package/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +121 -0
  115. package/docs/07-reference/01-ai-sdk-core/50-cosine-similarity.mdx +52 -0
  116. package/docs/07-reference/01-ai-sdk-core/60-wrap-language-model.mdx +59 -0
  117. package/docs/07-reference/01-ai-sdk-core/61-wrap-image-model.mdx +64 -0
  118. package/docs/07-reference/01-ai-sdk-core/65-language-model-v2-middleware.mdx +46 -0
  119. package/docs/07-reference/01-ai-sdk-core/66-extract-reasoning-middleware.mdx +68 -0
  120. package/docs/07-reference/01-ai-sdk-core/67-simulate-streaming-middleware.mdx +71 -0
  121. package/docs/07-reference/01-ai-sdk-core/68-default-settings-middleware.mdx +80 -0
  122. package/docs/07-reference/01-ai-sdk-core/69-add-tool-input-examples-middleware.mdx +155 -0
  123. package/docs/07-reference/01-ai-sdk-core/70-extract-json-middleware.mdx +147 -0
  124. package/docs/07-reference/01-ai-sdk-core/70-step-count-is.mdx +84 -0
  125. package/docs/07-reference/01-ai-sdk-core/71-has-tool-call.mdx +120 -0
  126. package/docs/07-reference/01-ai-sdk-core/75-simulate-readable-stream.mdx +94 -0
  127. package/docs/07-reference/01-ai-sdk-core/80-smooth-stream.mdx +145 -0
  128. package/docs/07-reference/01-ai-sdk-core/90-generate-id.mdx +43 -0
  129. package/docs/07-reference/01-ai-sdk-core/91-create-id-generator.mdx +89 -0
  130. package/docs/07-reference/01-ai-sdk-core/index.mdx +159 -0
  131. package/docs/07-reference/02-ai-sdk-ui/01-use-chat.mdx +446 -0
  132. package/docs/07-reference/02-ai-sdk-ui/02-use-completion.mdx +179 -0
  133. package/docs/07-reference/02-ai-sdk-ui/03-use-object.mdx +178 -0
  134. package/docs/07-reference/02-ai-sdk-ui/31-convert-to-model-messages.mdx +230 -0
  135. package/docs/07-reference/02-ai-sdk-ui/32-prune-messages.mdx +108 -0
  136. package/docs/07-reference/02-ai-sdk-ui/40-create-ui-message-stream.mdx +151 -0
  137. package/docs/07-reference/02-ai-sdk-ui/41-create-ui-message-stream-response.mdx +113 -0
  138. package/docs/07-reference/02-ai-sdk-ui/42-pipe-ui-message-stream-to-response.mdx +73 -0
  139. package/docs/07-reference/02-ai-sdk-ui/43-read-ui-message-stream.mdx +57 -0
  140. package/docs/07-reference/02-ai-sdk-ui/46-infer-ui-tools.mdx +99 -0
  141. package/docs/07-reference/02-ai-sdk-ui/47-infer-ui-tool.mdx +75 -0
  142. package/docs/07-reference/02-ai-sdk-ui/50-direct-chat-transport.mdx +333 -0
  143. package/docs/07-reference/02-ai-sdk-ui/index.mdx +89 -0
  144. package/docs/07-reference/03-ai-sdk-rsc/01-stream-ui.mdx +767 -0
  145. package/docs/07-reference/03-ai-sdk-rsc/02-create-ai.mdx +90 -0
  146. package/docs/07-reference/03-ai-sdk-rsc/03-create-streamable-ui.mdx +91 -0
  147. package/docs/07-reference/03-ai-sdk-rsc/04-create-streamable-value.mdx +48 -0
  148. package/docs/07-reference/03-ai-sdk-rsc/05-read-streamable-value.mdx +78 -0
  149. package/docs/07-reference/03-ai-sdk-rsc/06-get-ai-state.mdx +50 -0
  150. package/docs/07-reference/03-ai-sdk-rsc/07-get-mutable-ai-state.mdx +70 -0
  151. package/docs/07-reference/03-ai-sdk-rsc/08-use-ai-state.mdx +26 -0
  152. package/docs/07-reference/03-ai-sdk-rsc/09-use-actions.mdx +42 -0
  153. package/docs/07-reference/03-ai-sdk-rsc/10-use-ui-state.mdx +35 -0
  154. package/docs/07-reference/03-ai-sdk-rsc/11-use-streamable-value.mdx +46 -0
  155. package/docs/07-reference/03-ai-sdk-rsc/20-render.mdx +262 -0
  156. package/docs/07-reference/03-ai-sdk-rsc/index.mdx +67 -0
  157. package/docs/07-reference/04-stream-helpers/01-ai-stream.mdx +89 -0
  158. package/docs/07-reference/04-stream-helpers/02-streaming-text-response.mdx +79 -0
  159. package/docs/07-reference/04-stream-helpers/05-stream-to-response.mdx +108 -0
  160. package/docs/07-reference/04-stream-helpers/07-openai-stream.mdx +77 -0
  161. package/docs/07-reference/04-stream-helpers/08-anthropic-stream.mdx +79 -0
  162. package/docs/07-reference/04-stream-helpers/09-aws-bedrock-stream.mdx +91 -0
  163. package/docs/07-reference/04-stream-helpers/10-aws-bedrock-anthropic-stream.mdx +96 -0
  164. package/docs/07-reference/04-stream-helpers/10-aws-bedrock-messages-stream.mdx +96 -0
  165. package/docs/07-reference/04-stream-helpers/11-aws-bedrock-cohere-stream.mdx +93 -0
  166. package/docs/07-reference/04-stream-helpers/12-aws-bedrock-llama-2-stream.mdx +93 -0
  167. package/docs/07-reference/04-stream-helpers/13-cohere-stream.mdx +78 -0
  168. package/docs/07-reference/04-stream-helpers/14-google-generative-ai-stream.mdx +85 -0
  169. package/docs/07-reference/04-stream-helpers/15-hugging-face-stream.mdx +84 -0
  170. package/docs/07-reference/04-stream-helpers/16-langchain-adapter.mdx +98 -0
  171. package/docs/07-reference/04-stream-helpers/16-llamaindex-adapter.mdx +70 -0
  172. package/docs/07-reference/04-stream-helpers/17-mistral-stream.mdx +81 -0
  173. package/docs/07-reference/04-stream-helpers/18-replicate-stream.mdx +83 -0
  174. package/docs/07-reference/04-stream-helpers/19-inkeep-stream.mdx +80 -0
  175. package/docs/07-reference/04-stream-helpers/index.mdx +103 -0
  176. package/docs/07-reference/05-ai-sdk-errors/ai-api-call-error.mdx +30 -0
  177. package/docs/07-reference/05-ai-sdk-errors/ai-download-error.mdx +27 -0
  178. package/docs/07-reference/05-ai-sdk-errors/ai-empty-response-body-error.mdx +24 -0
  179. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-argument-error.mdx +26 -0
  180. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-data-content-error.mdx +25 -0
  181. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-data-content.mdx +26 -0
  182. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-message-role-error.mdx +25 -0
  183. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-prompt-error.mdx +47 -0
  184. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-response-data-error.mdx +25 -0
  185. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-approval-error.mdx +25 -0
  186. package/docs/07-reference/05-ai-sdk-errors/ai-invalid-tool-input-error.mdx +27 -0
  187. package/docs/07-reference/05-ai-sdk-errors/ai-json-parse-error.mdx +25 -0
  188. package/docs/07-reference/05-ai-sdk-errors/ai-load-api-key-error.mdx +24 -0
  189. package/docs/07-reference/05-ai-sdk-errors/ai-load-setting-error.mdx +24 -0
  190. package/docs/07-reference/05-ai-sdk-errors/ai-message-conversion-error.mdx +25 -0
  191. package/docs/07-reference/05-ai-sdk-errors/ai-no-content-generated-error.mdx +24 -0
  192. package/docs/07-reference/05-ai-sdk-errors/ai-no-image-generated-error.mdx +36 -0
  193. package/docs/07-reference/05-ai-sdk-errors/ai-no-object-generated-error.mdx +43 -0
  194. package/docs/07-reference/05-ai-sdk-errors/ai-no-speech-generated-error.mdx +25 -0
  195. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-model-error.mdx +26 -0
  196. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-provider-error.mdx +28 -0
  197. package/docs/07-reference/05-ai-sdk-errors/ai-no-such-tool-error.mdx +26 -0
  198. package/docs/07-reference/05-ai-sdk-errors/ai-no-transcript-generated-error.mdx +25 -0
  199. package/docs/07-reference/05-ai-sdk-errors/ai-retry-error.mdx +27 -0
  200. package/docs/07-reference/05-ai-sdk-errors/ai-too-many-embedding-values-for-call-error.mdx +27 -0
  201. package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-not-found-for-approval-error.mdx +26 -0
  202. package/docs/07-reference/05-ai-sdk-errors/ai-tool-call-repair-error.mdx +28 -0
  203. package/docs/07-reference/05-ai-sdk-errors/ai-type-validation-error.mdx +25 -0
  204. package/docs/07-reference/05-ai-sdk-errors/ai-unsupported-functionality-error.mdx +25 -0
  205. package/docs/07-reference/05-ai-sdk-errors/index.mdx +38 -0
  206. package/docs/07-reference/index.mdx +34 -0
  207. package/docs/08-migration-guides/00-versioning.mdx +46 -0
  208. package/docs/08-migration-guides/24-migration-guide-6-0.mdx +823 -0
  209. package/docs/08-migration-guides/25-migration-guide-5-0-data.mdx +882 -0
  210. package/docs/08-migration-guides/26-migration-guide-5-0.mdx +3427 -0
  211. package/docs/08-migration-guides/27-migration-guide-4-2.mdx +99 -0
  212. package/docs/08-migration-guides/28-migration-guide-4-1.mdx +14 -0
  213. package/docs/08-migration-guides/29-migration-guide-4-0.mdx +1157 -0
  214. package/docs/08-migration-guides/36-migration-guide-3-4.mdx +14 -0
  215. package/docs/08-migration-guides/37-migration-guide-3-3.mdx +64 -0
  216. package/docs/08-migration-guides/38-migration-guide-3-2.mdx +46 -0
  217. package/docs/08-migration-guides/39-migration-guide-3-1.mdx +168 -0
  218. package/docs/08-migration-guides/index.mdx +22 -0
  219. package/docs/09-troubleshooting/01-azure-stream-slow.mdx +33 -0
  220. package/docs/09-troubleshooting/02-client-side-function-calls-not-invoked.mdx +22 -0
  221. package/docs/09-troubleshooting/03-server-actions-in-client-components.mdx +40 -0
  222. package/docs/09-troubleshooting/04-strange-stream-output.mdx +36 -0
  223. package/docs/09-troubleshooting/05-streamable-ui-errors.mdx +16 -0
  224. package/docs/09-troubleshooting/05-tool-invocation-missing-result.mdx +106 -0
  225. package/docs/09-troubleshooting/06-streaming-not-working-when-deployed.mdx +31 -0
  226. package/docs/09-troubleshooting/06-streaming-not-working-when-proxied.mdx +31 -0
  227. package/docs/09-troubleshooting/06-timeout-on-vercel.mdx +60 -0
  228. package/docs/09-troubleshooting/07-unclosed-streams.mdx +34 -0
  229. package/docs/09-troubleshooting/08-use-chat-failed-to-parse-stream.mdx +26 -0
  230. package/docs/09-troubleshooting/09-client-stream-error.mdx +25 -0
  231. package/docs/09-troubleshooting/10-use-chat-tools-no-response.mdx +32 -0
  232. package/docs/09-troubleshooting/11-use-chat-custom-request-options.mdx +149 -0
  233. package/docs/09-troubleshooting/12-typescript-performance-zod.mdx +46 -0
  234. package/docs/09-troubleshooting/12-use-chat-an-error-occurred.mdx +59 -0
  235. package/docs/09-troubleshooting/13-repeated-assistant-messages.mdx +73 -0
  236. package/docs/09-troubleshooting/14-stream-abort-handling.mdx +73 -0
  237. package/docs/09-troubleshooting/14-tool-calling-with-structured-outputs.mdx +48 -0
  238. package/docs/09-troubleshooting/15-abort-breaks-resumable-streams.mdx +55 -0
  239. package/docs/09-troubleshooting/15-stream-text-not-working.mdx +33 -0
  240. package/docs/09-troubleshooting/16-streaming-status-delay.mdx +63 -0
  241. package/docs/09-troubleshooting/17-use-chat-stale-body-data.mdx +141 -0
  242. package/docs/09-troubleshooting/18-ontoolcall-type-narrowing.mdx +66 -0
  243. package/docs/09-troubleshooting/19-unsupported-model-version.mdx +50 -0
  244. package/docs/09-troubleshooting/20-no-object-generated-content-filter.mdx +72 -0
  245. package/docs/09-troubleshooting/30-model-is-not-assignable-to-type.mdx +21 -0
  246. package/docs/09-troubleshooting/40-typescript-cannot-find-namespace-jsx.mdx +24 -0
  247. package/docs/09-troubleshooting/50-react-maximum-update-depth-exceeded.mdx +39 -0
  248. package/docs/09-troubleshooting/60-jest-cannot-find-module-ai-rsc.mdx +22 -0
  249. package/docs/09-troubleshooting/index.mdx +11 -0
  250. package/package.json +8 -4
@@ -0,0 +1,535 @@
1
+ ---
2
+ title: Chatbot Message Persistence
3
+ description: Learn how to store and load chat messages in a chatbot.
4
+ ---
5
+
6
+ # Chatbot Message Persistence
7
+
8
+ Being able to store and load chat messages is crucial for most AI chatbots.
9
+ In this guide, we'll show how to implement message persistence with `useChat` and `streamText`.
10
+
11
+ <Note>
12
+ This guide does not cover authorization, error handling, or other real-world
13
+ considerations. It is intended to be a simple example of how to implement
14
+ message persistence.
15
+ </Note>
16
+
17
+ ## Starting a new chat
18
+
19
+ When the user navigates to the chat page without providing a chat ID,
20
+ we need to create a new chat and redirect to the chat page with the new chat ID.
21
+
22
+ ```tsx filename="app/chat/page.tsx"
23
+ import { redirect } from 'next/navigation';
24
+ import { createChat } from '@util/chat-store';
25
+
26
+ export default async function Page() {
27
+ const id = await createChat(); // create a new chat
28
+ redirect(`/chat/${id}`); // redirect to chat page, see below
29
+ }
30
+ ```
31
+
32
+ Our example chat store implementation uses files to store the chat messages.
33
+ In a real-world application, you would use a database or a cloud storage service,
34
+ and get the chat ID from the database.
35
+ That being said, the function interfaces are designed to be easily replaced with other implementations.
36
+
37
+ ```tsx filename="util/chat-store.ts"
38
+ import { generateId } from 'ai';
39
+ import { existsSync, mkdirSync } from 'fs';
40
+ import { writeFile } from 'fs/promises';
41
+ import path from 'path';
42
+
43
+ export async function createChat(): Promise<string> {
44
+ const id = generateId(); // generate a unique chat ID
45
+ await writeFile(getChatFile(id), '[]'); // create an empty chat file
46
+ return id;
47
+ }
48
+
49
+ function getChatFile(id: string): string {
50
+ const chatDir = path.join(process.cwd(), '.chats');
51
+ if (!existsSync(chatDir)) mkdirSync(chatDir, { recursive: true });
52
+ return path.join(chatDir, `${id}.json`);
53
+ }
54
+ ```
55
+
56
+ ## Loading an existing chat
57
+
58
+ When the user navigates to the chat page with a chat ID, we need to load the chat messages from storage.
59
+
60
+ The `loadChat` function in our file-based chat store is implemented as follows:
61
+
62
+ ```tsx filename="util/chat-store.ts"
63
+ import { UIMessage } from 'ai';
64
+ import { readFile } from 'fs/promises';
65
+
66
+ export async function loadChat(id: string): Promise<UIMessage[]> {
67
+ return JSON.parse(await readFile(getChatFile(id), 'utf8'));
68
+ }
69
+
70
+ // ... rest of the file
71
+ ```
72
+
73
+ ## Validating messages on the server
74
+
75
+ When processing messages on the server that contain tool calls, custom metadata, or data parts, you should validate them using `validateUIMessages` before sending them to the model.
76
+
77
+ ### Validation with tools
78
+
79
+ When your messages include tool calls, validate them against your tool definitions:
80
+
81
+ ```tsx filename="app/api/chat/route.ts" highlight="7-25,32-37"
82
+ import {
83
+ convertToModelMessages,
84
+ streamText,
85
+ UIMessage,
86
+ validateUIMessages,
87
+ tool,
88
+ } from 'ai';
89
+ import { z } from 'zod';
90
+ import { loadChat, saveChat } from '@util/chat-store';
91
+ import { openai } from '@ai-sdk/openai';
92
+ import { dataPartsSchema, metadataSchema } from '@util/schemas';
93
+
94
+ // Define your tools
95
+ const tools = {
96
+ weather: tool({
97
+ description: 'Get weather information',
98
+ parameters: z.object({
99
+ location: z.string(),
100
+ units: z.enum(['celsius', 'fahrenheit']),
101
+ }),
102
+ execute: async ({ location, units }) => {
103
+ /* tool implementation */
104
+ },
105
+ }),
106
+ // other tools
107
+ };
108
+
109
+ export async function POST(req: Request) {
110
+ const { message, id } = await req.json();
111
+
112
+ // Load previous messages from database
113
+ const previousMessages = await loadChat(id);
114
+
115
+ // Append new message to previousMessages messages
116
+ const messages = [...previousMessages, message];
117
+
118
+ // Validate loaded messages against
119
+ // tools, data parts schema, and metadata schema
120
+ const validatedMessages = await validateUIMessages({
121
+ messages,
122
+ tools, // Ensures tool calls in messages match current schemas
123
+ dataPartsSchema,
124
+ metadataSchema,
125
+ });
126
+
127
+ const result = streamText({
128
+ model: 'openai/gpt-5-mini',
129
+ messages: convertToModelMessages(validatedMessages),
130
+ tools,
131
+ });
132
+
133
+ return result.toUIMessageStreamResponse({
134
+ originalMessages: messages,
135
+ onFinish: ({ messages }) => {
136
+ saveChat({ chatId: id, messages });
137
+ },
138
+ });
139
+ }
140
+ ```
141
+
142
+ ### Handling validation errors
143
+
144
+ Handle validation errors gracefully when messages from the database don't match current schemas:
145
+
146
+ ```tsx filename="app/api/chat/route.ts" highlight="3,10-24"
147
+ import {
148
+ convertToModelMessages,
149
+ streamText,
150
+ validateUIMessages,
151
+ TypeValidationError,
152
+ } from 'ai';
153
+ import { type MyUIMessage } from '@/types';
154
+
155
+ export async function POST(req: Request) {
156
+ const { message, id } = await req.json();
157
+
158
+ // Load and validate messages from database
159
+ let validatedMessages: MyUIMessage[];
160
+
161
+ try {
162
+ const previousMessages = await loadMessagesFromDB(id);
163
+ validatedMessages = await validateUIMessages({
164
+ // append the new message to the previous messages:
165
+ messages: [...previousMessages, message],
166
+ tools,
167
+ metadataSchema,
168
+ });
169
+ } catch (error) {
170
+ if (error instanceof TypeValidationError) {
171
+ // Log validation error for monitoring
172
+ console.error('Database messages validation failed:', error);
173
+ // Could implement message migration or filtering here
174
+ // For now, start with empty history
175
+ validatedMessages = [];
176
+ } else {
177
+ throw error;
178
+ }
179
+ }
180
+
181
+ // Continue with validated messages...
182
+ }
183
+ ```
184
+
185
+ ## Displaying the chat
186
+
187
+ Once messages are loaded from storage, you can display them in your chat UI. Here's how to set up the page component and the chat display:
188
+
189
+ ```tsx filename="app/chat/[id]/page.tsx"
190
+ import { loadChat } from '@util/chat-store';
191
+ import Chat from '@ui/chat';
192
+
193
+ export default async function Page(props: { params: Promise<{ id: string }> }) {
194
+ const { id } = await props.params;
195
+ const messages = await loadChat(id);
196
+ return <Chat id={id} initialMessages={messages} />;
197
+ }
198
+ ```
199
+
200
+ The chat component uses the `useChat` hook to manage the conversation:
201
+
202
+ ```tsx filename="ui/chat.tsx" highlight="10-16"
203
+ 'use client';
204
+
205
+ import { UIMessage, useChat } from '@ai-sdk/react';
206
+ import { DefaultChatTransport } from 'ai';
207
+ import { useState } from 'react';
208
+
209
+ export default function Chat({
210
+ id,
211
+ initialMessages,
212
+ }: { id?: string | undefined; initialMessages?: UIMessage[] } = {}) {
213
+ const [input, setInput] = useState('');
214
+ const { sendMessage, messages } = useChat({
215
+ id, // use the provided chat ID
216
+ messages: initialMessages, // load initial messages
217
+ transport: new DefaultChatTransport({
218
+ api: '/api/chat',
219
+ }),
220
+ });
221
+
222
+ const handleSubmit = (e: React.FormEvent) => {
223
+ e.preventDefault();
224
+ if (input.trim()) {
225
+ sendMessage({ text: input });
226
+ setInput('');
227
+ }
228
+ };
229
+
230
+ // simplified rendering code, extend as needed:
231
+ return (
232
+ <div>
233
+ {messages.map(m => (
234
+ <div key={m.id}>
235
+ {m.role === 'user' ? 'User: ' : 'AI: '}
236
+ {m.parts
237
+ .map(part => (part.type === 'text' ? part.text : ''))
238
+ .join('')}
239
+ </div>
240
+ ))}
241
+
242
+ <form onSubmit={handleSubmit}>
243
+ <input
244
+ value={input}
245
+ onChange={e => setInput(e.target.value)}
246
+ placeholder="Type a message..."
247
+ />
248
+ <button type="submit">Send</button>
249
+ </form>
250
+ </div>
251
+ );
252
+ }
253
+ ```
254
+
255
+ ## Storing messages
256
+
257
+ `useChat` sends the chat id and the messages to the backend.
258
+
259
+ <Note>
260
+ The `useChat` message format is different from the `ModelMessage` format. The
261
+ `useChat` message format is designed for frontend display, and contains
262
+ additional fields such as `id` and `createdAt`. We recommend storing the
263
+ messages in the `useChat` message format.
264
+
265
+ When loading messages from storage that contain tools, metadata, or custom data
266
+ parts, validate them using `validateUIMessages` before processing (see the
267
+ [validation section](#validating-messages-from-database) above).
268
+
269
+ </Note>
270
+
271
+ Storing messages is done in the `onFinish` callback of the `toUIMessageStreamResponse` function.
272
+ `onFinish` receives the complete messages including the new AI response as `UIMessage[]`.
273
+
274
+ ```tsx filename="app/api/chat/route.ts" highlight="6,11-17"
275
+ import { openai } from '@ai-sdk/openai';
276
+ import { saveChat } from '@util/chat-store';
277
+ import { convertToModelMessages, streamText, UIMessage } from 'ai';
278
+
279
+ export async function POST(req: Request) {
280
+ const { messages, chatId }: { messages: UIMessage[]; chatId: string } =
281
+ await req.json();
282
+
283
+ const result = streamText({
284
+ model: 'openai/gpt-5-mini',
285
+ messages: await convertToModelMessages(messages),
286
+ });
287
+
288
+ return result.toUIMessageStreamResponse({
289
+ originalMessages: messages,
290
+ onFinish: ({ messages }) => {
291
+ saveChat({ chatId, messages });
292
+ },
293
+ });
294
+ }
295
+ ```
296
+
297
+ The actual storage of the messages is done in the `saveChat` function, which in
298
+ our file-based chat store is implemented as follows:
299
+
300
+ ```tsx filename="util/chat-store.ts"
301
+ import { UIMessage } from 'ai';
302
+ import { writeFile } from 'fs/promises';
303
+
304
+ export async function saveChat({
305
+ chatId,
306
+ messages,
307
+ }: {
308
+ chatId: string;
309
+ messages: UIMessage[];
310
+ }): Promise<void> {
311
+ const content = JSON.stringify(messages, null, 2);
312
+ await writeFile(getChatFile(chatId), content);
313
+ }
314
+
315
+ // ... rest of the file
316
+ ```
317
+
318
+ ## Message IDs
319
+
320
+ In addition to a chat ID, each message has an ID.
321
+ You can use this message ID to e.g. manipulate individual messages.
322
+
323
+ ### Client-side vs Server-side ID Generation
324
+
325
+ By default, message IDs are generated client-side:
326
+
327
+ - User message IDs are generated by the `useChat` hook on the client
328
+ - AI response message IDs are generated by `streamText` on the server
329
+
330
+ For applications without persistence, client-side ID generation works perfectly.
331
+ However, **for persistence, you need server-side generated IDs** to ensure consistency across sessions and prevent ID conflicts when messages are stored and retrieved.
332
+
333
+ ### Setting Up Server-side ID Generation
334
+
335
+ When implementing persistence, you have two options for generating server-side IDs:
336
+
337
+ 1. **Using `generateMessageId` in `toUIMessageStreamResponse`**
338
+ 2. **Setting IDs in your start message part with `createUIMessageStream`**
339
+
340
+ #### Option 1: Using `generateMessageId` in `toUIMessageStreamResponse`
341
+
342
+ You can control the ID format by providing ID generators using [`createIdGenerator()`](/docs/reference/ai-sdk-core/create-id-generator):
343
+
344
+ ```tsx filename="app/api/chat/route.ts" highlight="7-11"
345
+ import { createIdGenerator, streamText } from 'ai';
346
+
347
+ export async function POST(req: Request) {
348
+ // ...
349
+ const result = streamText({
350
+ // ...
351
+ });
352
+
353
+ return result.toUIMessageStreamResponse({
354
+ originalMessages: messages,
355
+ // Generate consistent server-side IDs for persistence:
356
+ generateMessageId: createIdGenerator({
357
+ prefix: 'msg',
358
+ size: 16,
359
+ }),
360
+ onFinish: ({ messages }) => {
361
+ saveChat({ chatId, messages });
362
+ },
363
+ });
364
+ }
365
+ ```
366
+
367
+ #### Option 2: Setting IDs with `createUIMessageStream`
368
+
369
+ Alternatively, you can use `createUIMessageStream` to control the message ID by writing a start message part:
370
+
371
+ ```tsx filename="app/api/chat/route.ts" highlight="8-18"
372
+ import {
373
+ generateId,
374
+ streamText,
375
+ createUIMessageStream,
376
+ createUIMessageStreamResponse,
377
+ } from 'ai';
378
+
379
+ export async function POST(req: Request) {
380
+ const { messages, chatId } = await req.json();
381
+
382
+ const stream = createUIMessageStream({
383
+ execute: ({ writer }) => {
384
+ // Write start message part with custom ID
385
+ writer.write({
386
+ type: 'start',
387
+ messageId: generateId(), // Generate server-side ID for persistence
388
+ });
389
+
390
+ const result = streamText({
391
+ model: 'openai/gpt-5-mini',
392
+ messages: await convertToModelMessages(messages),
393
+ });
394
+
395
+ writer.merge(result.toUIMessageStream({ sendStart: false })); // omit start message part
396
+ },
397
+ originalMessages: messages,
398
+ onFinish: ({ responseMessage }) => {
399
+ // save your chat here
400
+ },
401
+ });
402
+
403
+ return createUIMessageStreamResponse({ stream });
404
+ }
405
+ ```
406
+
407
+ <Note>
408
+ For client-side applications that don't require persistence, you can still customize client-side ID generation:
409
+
410
+ ```tsx filename="ui/chat.tsx"
411
+ import { createIdGenerator } from 'ai';
412
+ import { useChat } from '@ai-sdk/react';
413
+
414
+ const { ... } = useChat({
415
+ generateId: createIdGenerator({
416
+ prefix: 'msgc',
417
+ size: 16,
418
+ }),
419
+ // ...
420
+ });
421
+ ```
422
+
423
+ </Note>
424
+
425
+ ## Sending only the last message
426
+
427
+ Once you have implemented message persistence, you might want to send only the last message to the server.
428
+ This reduces the amount of data sent to the server on each request and can improve performance.
429
+
430
+ To achieve this, you can provide a `prepareSendMessagesRequest` function to the transport.
431
+ This function receives the messages and the chat ID, and returns the request body to be sent to the server.
432
+
433
+ ```tsx filename="ui/chat.tsx" highlight="7-12"
434
+ import { useChat } from '@ai-sdk/react';
435
+ import { DefaultChatTransport } from 'ai';
436
+
437
+ const {
438
+ // ...
439
+ } = useChat({
440
+ // ...
441
+ transport: new DefaultChatTransport({
442
+ api: '/api/chat',
443
+ // only send the last message to the server:
444
+ prepareSendMessagesRequest({ messages, id }) {
445
+ return { body: { message: messages[messages.length - 1], id } };
446
+ },
447
+ }),
448
+ });
449
+ ```
450
+
451
+ On the server, you can then load the previous messages and append the new message to the previous messages. If your messages contain tools, metadata, or custom data parts, you should validate them:
452
+
453
+ ```tsx filename="app/api/chat/route.ts" highlight="2-11,14-18"
454
+ import { convertToModelMessages, UIMessage, validateUIMessages } from 'ai';
455
+ // import your tools and schemas
456
+
457
+ export async function POST(req: Request) {
458
+ // get the last message from the client:
459
+ const { message, id } = await req.json();
460
+
461
+ // load the previous messages from the server:
462
+ const previousMessages = await loadChat(id);
463
+
464
+ // validate messages if they contain tools, metadata, or data parts:
465
+ const validatedMessages = await validateUIMessages({
466
+ // append the new message to the previous messages:
467
+ messages: [...previousMessages, message],
468
+ tools, // if using tools
469
+ metadataSchema, // if using custom metadata
470
+ dataSchemas, // if using custom data parts
471
+ });
472
+
473
+ const result = streamText({
474
+ // ...
475
+ messages: convertToModelMessages(validatedMessages),
476
+ });
477
+
478
+ return result.toUIMessageStreamResponse({
479
+ originalMessages: validatedMessages,
480
+ onFinish: ({ messages }) => {
481
+ saveChat({ chatId: id, messages });
482
+ },
483
+ });
484
+ }
485
+ ```
486
+
487
+ ## Handling client disconnects
488
+
489
+ By default, the AI SDK `streamText` function uses backpressure to the language model provider to prevent
490
+ the consumption of tokens that are not yet requested.
491
+
492
+ However, this means that when the client disconnects, e.g. by closing the browser tab or because of a network issue,
493
+ the stream from the LLM will be aborted and the conversation may end up in a broken state.
494
+
495
+ Assuming that you have a [storage solution](#storing-messages) in place, you can use the `consumeStream` method to consume the stream on the backend,
496
+ and then save the result as usual.
497
+ `consumeStream` effectively removes the backpressure,
498
+ meaning that the result is stored even when the client has already disconnected.
499
+
500
+ ```tsx filename="app/api/chat/route.ts" highlight="19-21"
501
+ import { convertToModelMessages, streamText, UIMessage } from 'ai';
502
+ import { saveChat } from '@util/chat-store';
503
+
504
+ export async function POST(req: Request) {
505
+ const { messages, chatId }: { messages: UIMessage[]; chatId: string } =
506
+ await req.json();
507
+
508
+ const result = streamText({
509
+ model,
510
+ messages: await convertToModelMessages(messages),
511
+ });
512
+
513
+ // consume the stream to ensure it runs to completion & triggers onFinish
514
+ // even when the client response is aborted:
515
+ result.consumeStream(); // no await
516
+
517
+ return result.toUIMessageStreamResponse({
518
+ originalMessages: messages,
519
+ onFinish: ({ messages }) => {
520
+ saveChat({ chatId, messages });
521
+ },
522
+ });
523
+ }
524
+ ```
525
+
526
+ When the client reloads the page after a disconnect, the chat will be restored from the storage solution.
527
+
528
+ <Note>
529
+ In production applications, you would also track the state of the request (in
530
+ progress, complete) in your stored messages and use it on the client to cover
531
+ the case where the client reloads the page after a disconnection, but the
532
+ streaming is not yet complete.
533
+ </Note>
534
+
535
+ For more robust handling of disconnects, you may want to add resumability on disconnects. Check out the [Chatbot Resume Streams](/docs/ai-sdk-ui/chatbot-resume-streams) documentation to learn more.