@assistant-ui/mcp-docs-server 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/README.md +16 -43
  2. package/dist/index.d.ts +2 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -91
  5. package/dist/index.js.map +1 -1
  6. package/dist/proxy.d.ts +9 -0
  7. package/dist/proxy.d.ts.map +1 -0
  8. package/dist/proxy.js +76 -0
  9. package/dist/proxy.js.map +1 -0
  10. package/package.json +9 -13
  11. package/src/index.ts +3 -115
  12. package/src/proxy.test.ts +250 -0
  13. package/src/proxy.ts +111 -0
  14. package/.docs/organized/code-examples/waterfall.md +0 -807
  15. package/.docs/organized/code-examples/with-a2a.md +0 -674
  16. package/.docs/organized/code-examples/with-ag-ui.md +0 -552
  17. package/.docs/organized/code-examples/with-ai-sdk-v7.md +0 -465
  18. package/.docs/organized/code-examples/with-artifacts.md +0 -814
  19. package/.docs/organized/code-examples/with-assistant-transport.md +0 -575
  20. package/.docs/organized/code-examples/with-browser-extension.md +0 -371
  21. package/.docs/organized/code-examples/with-chain-of-thought.md +0 -960
  22. package/.docs/organized/code-examples/with-cloud-standalone.md +0 -681
  23. package/.docs/organized/code-examples/with-cloud.md +0 -438
  24. package/.docs/organized/code-examples/with-custom-thread-list.md +0 -568
  25. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +0 -526
  26. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +0 -696
  27. package/.docs/organized/code-examples/with-eve.md +0 -404
  28. package/.docs/organized/code-examples/with-expo.md +0 -2063
  29. package/.docs/organized/code-examples/with-external-store.md +0 -420
  30. package/.docs/organized/code-examples/with-ffmpeg.md +0 -828
  31. package/.docs/organized/code-examples/with-generative-ui.md +0 -1812
  32. package/.docs/organized/code-examples/with-google-adk.md +0 -367
  33. package/.docs/organized/code-examples/with-heat-graph.md +0 -304
  34. package/.docs/organized/code-examples/with-image-generation.md +0 -462
  35. package/.docs/organized/code-examples/with-interactables.md +0 -732
  36. package/.docs/organized/code-examples/with-langchain.md +0 -445
  37. package/.docs/organized/code-examples/with-langgraph.md +0 -854
  38. package/.docs/organized/code-examples/with-livekit.md +0 -642
  39. package/.docs/organized/code-examples/with-mcp.md +0 -780
  40. package/.docs/organized/code-examples/with-nuxt.md +0 -2428
  41. package/.docs/organized/code-examples/with-opencode.md +0 -1974
  42. package/.docs/organized/code-examples/with-openui.md +0 -449
  43. package/.docs/organized/code-examples/with-pi.md +0 -2083
  44. package/.docs/organized/code-examples/with-react-hook-form.md +0 -724
  45. package/.docs/organized/code-examples/with-react-ink-web.md +0 -690
  46. package/.docs/organized/code-examples/with-react-ink.md +0 -472
  47. package/.docs/organized/code-examples/with-react-router.md +0 -935
  48. package/.docs/organized/code-examples/with-resumable-stream.md +0 -667
  49. package/.docs/organized/code-examples/with-store.md +0 -679
  50. package/.docs/organized/code-examples/with-svelte.md +0 -415
  51. package/.docs/organized/code-examples/with-sveltekit.md +0 -1061
  52. package/.docs/organized/code-examples/with-tanstack.md +0 -811
  53. package/.docs/organized/code-examples/with-tap-runtime.md +0 -812
  54. package/.docs/organized/code-examples/with-virtualized-thread.md +0 -680
  55. package/.docs/organized/code-examples/with-vue.md +0 -408
  56. package/.docs/raw/docs/(docs)/architecture.mdx +0 -146
  57. package/.docs/raw/docs/(docs)/base-ui.mdx +0 -39
  58. package/.docs/raw/docs/(docs)/cli.mdx +0 -542
  59. package/.docs/raw/docs/(docs)/devtools.mdx +0 -79
  60. package/.docs/raw/docs/(docs)/index.mdx +0 -21
  61. package/.docs/raw/docs/(docs)/installation.mdx +0 -483
  62. package/.docs/raw/docs/(docs)/llm.mdx +0 -211
  63. package/.docs/raw/docs/(docs)/rtl.mdx +0 -78
  64. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +0 -36
  65. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +0 -20
  66. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +0 -34
  67. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +0 -44
  68. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +0 -59
  69. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +0 -20
  70. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +0 -20
  71. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +0 -84
  72. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +0 -22
  73. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +0 -64
  74. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +0 -22
  75. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +0 -52
  76. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +0 -49
  77. package/.docs/raw/docs/(reference)/api-reference/generative-ui/a2ui.mdx +0 -40
  78. package/.docs/raw/docs/(reference)/api-reference/generative-ui/actions.mdx +0 -56
  79. package/.docs/raw/docs/(reference)/api-reference/generative-ui/components.mdx +0 -86
  80. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +0 -39
  81. package/.docs/raw/docs/(reference)/api-reference/generative-ui/json-generative-ui.mdx +0 -42
  82. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +0 -84
  83. package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +0 -85
  84. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +0 -45
  85. package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +0 -93
  86. package/.docs/raw/docs/(reference)/api-reference/generative-ui/tokens.mdx +0 -62
  87. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +0 -129
  88. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +0 -31
  89. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +0 -34
  90. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +0 -350
  91. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +0 -28
  92. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +0 -97
  93. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +0 -24
  94. package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +0 -97
  95. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +0 -28
  96. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +0 -200
  97. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -37
  98. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +0 -50
  99. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +0 -22
  100. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +0 -20
  101. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +0 -566
  102. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +0 -152
  103. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +0 -239
  104. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +0 -208
  105. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +0 -108
  106. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +0 -99
  107. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +0 -145
  108. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +0 -82
  109. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +0 -619
  110. package/.docs/raw/docs/(reference)/api-reference/primitives/composition.mdx +0 -22
  111. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +0 -65
  112. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +0 -73
  113. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +0 -117
  114. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +0 -339
  115. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +0 -77
  116. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +0 -88
  117. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +0 -81
  118. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +0 -129
  119. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +0 -138
  120. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +0 -122
  121. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +0 -289
  122. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +0 -20
  123. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +0 -24
  124. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +0 -32
  125. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +0 -43
  126. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +0 -43
  127. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +0 -24
  128. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +0 -20
  129. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +0 -24
  130. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +0 -24
  131. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +0 -36
  132. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +0 -85
  133. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +0 -45
  134. package/.docs/raw/docs/(reference)/api-reference/tools/interactables-legacy.mdx +0 -55
  135. package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +0 -151
  136. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +0 -106
  137. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +0 -62
  138. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +0 -178
  139. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +0 -48
  140. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +0 -62
  141. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +0 -22
  142. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +0 -19
  143. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +0 -149
  144. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +0 -22
  145. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +0 -54
  146. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +0 -36
  147. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +0 -527
  148. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -602
  149. package/.docs/raw/docs/cloud/authorization.mdx +0 -252
  150. package/.docs/raw/docs/cloud/index.mdx +0 -46
  151. package/.docs/raw/docs/cloud/langgraph.mdx +0 -554
  152. package/.docs/raw/docs/copilots/assistant-frame.mdx +0 -400
  153. package/.docs/raw/docs/copilots/make-assistant-visible.mdx +0 -82
  154. package/.docs/raw/docs/copilots/model-context.mdx +0 -156
  155. package/.docs/raw/docs/copilots/motivation.mdx +0 -202
  156. package/.docs/raw/docs/copilots/use-assistant-instructions.mdx +0 -64
  157. package/.docs/raw/docs/guides/attachments.mdx +0 -619
  158. package/.docs/raw/docs/guides/branching.mdx +0 -76
  159. package/.docs/raw/docs/guides/chain-of-thought.mdx +0 -164
  160. package/.docs/raw/docs/guides/chatgpt-subscription.mdx +0 -108
  161. package/.docs/raw/docs/guides/context-api.mdx +0 -619
  162. package/.docs/raw/docs/guides/dictation.mdx +0 -298
  163. package/.docs/raw/docs/guides/editing.mdx +0 -102
  164. package/.docs/raw/docs/guides/electron.mdx +0 -369
  165. package/.docs/raw/docs/guides/headless-composer-input.mdx +0 -113
  166. package/.docs/raw/docs/guides/image-generation.mdx +0 -74
  167. package/.docs/raw/docs/guides/index.mdx +0 -117
  168. package/.docs/raw/docs/guides/input-history.mdx +0 -55
  169. package/.docs/raw/docs/guides/latex.mdx +0 -158
  170. package/.docs/raw/docs/guides/mentions.mdx +0 -575
  171. package/.docs/raw/docs/guides/message-timing.mdx +0 -209
  172. package/.docs/raw/docs/guides/quoting.mdx +0 -169
  173. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +0 -212
  174. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +0 -152
  175. package/.docs/raw/docs/guides/resumable-streams.mdx +0 -292
  176. package/.docs/raw/docs/guides/slash-commands.mdx +0 -358
  177. package/.docs/raw/docs/guides/speech.mdx +0 -172
  178. package/.docs/raw/docs/guides/suggestions.mdx +0 -384
  179. package/.docs/raw/docs/guides/virtualization.mdx +0 -133
  180. package/.docs/raw/docs/guides/voice.mdx +0 -310
  181. package/.docs/raw/docs/ink/adapters.mdx +0 -99
  182. package/.docs/raw/docs/ink/custom-backend.mdx +0 -254
  183. package/.docs/raw/docs/ink/hooks.mdx +0 -469
  184. package/.docs/raw/docs/ink/index.mdx +0 -236
  185. package/.docs/raw/docs/ink/migration.mdx +0 -138
  186. package/.docs/raw/docs/ink/primitives.mdx +0 -1259
  187. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +0 -528
  188. package/.docs/raw/docs/integrations/auth/better-auth.mdx +0 -188
  189. package/.docs/raw/docs/integrations/auth/clerk.mdx +0 -166
  190. package/.docs/raw/docs/integrations/auth/next-auth.mdx +0 -191
  191. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +0 -88
  192. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +0 -282
  193. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +0 -188
  194. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +0 -57
  195. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +0 -201
  196. package/.docs/raw/docs/integrations/gateways/index.mdx +0 -162
  197. package/.docs/raw/docs/integrations/index.mdx +0 -178
  198. package/.docs/raw/docs/integrations/observability/helicone.mdx +0 -129
  199. package/.docs/raw/docs/integrations/observability/langfuse.mdx +0 -161
  200. package/.docs/raw/docs/integrations/observability/langsmith.mdx +0 -151
  201. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +0 -773
  202. package/.docs/raw/docs/migrations/deprecation-policy.mdx +0 -42
  203. package/.docs/raw/docs/migrations/index.mdx +0 -50
  204. package/.docs/raw/docs/migrations/react-compatibility.mdx +0 -74
  205. package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +0 -328
  206. package/.docs/raw/docs/migrations/toolkit-tools.mdx +0 -236
  207. package/.docs/raw/docs/migrations/v0-11.mdx +0 -172
  208. package/.docs/raw/docs/migrations/v0-12.mdx +0 -302
  209. package/.docs/raw/docs/migrations/v0-14.mdx +0 -297
  210. package/.docs/raw/docs/migrations/v0-15.mdx +0 -270
  211. package/.docs/raw/docs/primitives/action-bar.mdx +0 -352
  212. package/.docs/raw/docs/primitives/assistant-modal.mdx +0 -216
  213. package/.docs/raw/docs/primitives/attachment.mdx +0 -217
  214. package/.docs/raw/docs/primitives/branch-picker.mdx +0 -222
  215. package/.docs/raw/docs/primitives/chain-of-thought.mdx +0 -315
  216. package/.docs/raw/docs/primitives/composer.mdx +0 -659
  217. package/.docs/raw/docs/primitives/error.mdx +0 -142
  218. package/.docs/raw/docs/primitives/index.mdx +0 -99
  219. package/.docs/raw/docs/primitives/message.mdx +0 -618
  220. package/.docs/raw/docs/primitives/selection-toolbar.mdx +0 -191
  221. package/.docs/raw/docs/primitives/suggestion.mdx +0 -254
  222. package/.docs/raw/docs/primitives/thread-list.mdx +0 -467
  223. package/.docs/raw/docs/primitives/thread.mdx +0 -509
  224. package/.docs/raw/docs/react-native/adapters.mdx +0 -94
  225. package/.docs/raw/docs/react-native/custom-backend.mdx +0 -207
  226. package/.docs/raw/docs/react-native/hooks.mdx +0 -339
  227. package/.docs/raw/docs/react-native/index.mdx +0 -289
  228. package/.docs/raw/docs/react-native/migration.mdx +0 -142
  229. package/.docs/raw/docs/react-native/primitives.mdx +0 -839
  230. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +0 -399
  231. package/.docs/raw/docs/runtimes/a2a/overview.mdx +0 -60
  232. package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +0 -216
  233. package/.docs/raw/docs/runtimes/ag-ui/agent-state.mdx +0 -124
  234. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +0 -70
  235. package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +0 -243
  236. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +0 -255
  237. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +0 -61
  238. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +0 -122
  239. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +0 -135
  240. package/.docs/raw/docs/runtimes/ai-sdk/v6-legacy.mdx +0 -636
  241. package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +0 -716
  242. package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +0 -118
  243. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +0 -265
  244. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +0 -167
  245. package/.docs/raw/docs/runtimes/concepts/stability.mdx +0 -68
  246. package/.docs/raw/docs/runtimes/concepts/threads.mdx +0 -513
  247. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +0 -763
  248. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +0 -339
  249. package/.docs/raw/docs/runtimes/custom/external-store.mdx +0 -957
  250. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +0 -902
  251. package/.docs/raw/docs/runtimes/custom/overview.mdx +0 -71
  252. package/.docs/raw/docs/runtimes/eve/overview.mdx +0 -151
  253. package/.docs/raw/docs/runtimes/eve/quickstart.mdx +0 -192
  254. package/.docs/raw/docs/runtimes/google-adk/api.mdx +0 -256
  255. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +0 -784
  256. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +0 -69
  257. package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +0 -229
  258. package/.docs/raw/docs/runtimes/langchain.mdx +0 -901
  259. package/.docs/raw/docs/runtimes/langgraph/agent-state.mdx +0 -181
  260. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +0 -305
  261. package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +0 -104
  262. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +0 -84
  263. package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +0 -496
  264. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +0 -144
  265. package/.docs/raw/docs/runtimes/langgraph/threads.mdx +0 -113
  266. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +0 -29
  267. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -93
  268. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +0 -347
  269. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +0 -393
  270. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +0 -194
  271. package/.docs/raw/docs/runtimes/opencode/overview.mdx +0 -58
  272. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +0 -119
  273. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +0 -133
  274. package/.docs/raw/docs/tools/a2ui.mdx +0 -107
  275. package/.docs/raw/docs/tools/backend.mdx +0 -147
  276. package/.docs/raw/docs/tools/defining-tools.mdx +0 -574
  277. package/.docs/raw/docs/tools/dynamic-tools.mdx +0 -112
  278. package/.docs/raw/docs/tools/generative-ui-primitive.mdx +0 -180
  279. package/.docs/raw/docs/tools/generative-ui-slack.mdx +0 -167
  280. package/.docs/raw/docs/tools/generative-ui-teams.mdx +0 -160
  281. package/.docs/raw/docs/tools/generative-ui.mdx +0 -322
  282. package/.docs/raw/docs/tools/index.mdx +0 -72
  283. package/.docs/raw/docs/tools/interactables.mdx +0 -1084
  284. package/.docs/raw/docs/tools/mcp-apps.mdx +0 -346
  285. package/.docs/raw/docs/tools/mcp.mdx +0 -466
  286. package/.docs/raw/docs/tools/multi-agent.mdx +0 -237
  287. package/.docs/raw/docs/tools/openui.mdx +0 -175
  288. package/.docs/raw/docs/tools/tool-ui.mdx +0 -1008
  289. package/.docs/raw/docs/tools/user-managed-mcp.mdx +0 -428
  290. package/.docs/raw/docs/ui/accordion.mdx +0 -266
  291. package/.docs/raw/docs/ui/assistant-modal.mdx +0 -166
  292. package/.docs/raw/docs/ui/assistant-sidebar.mdx +0 -89
  293. package/.docs/raw/docs/ui/attachment.mdx +0 -259
  294. package/.docs/raw/docs/ui/badge.mdx +0 -150
  295. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +0 -212
  296. package/.docs/raw/docs/ui/context-display.mdx +0 -148
  297. package/.docs/raw/docs/ui/diff-viewer.mdx +0 -280
  298. package/.docs/raw/docs/ui/directive-text.mdx +0 -114
  299. package/.docs/raw/docs/ui/dot-matrix.mdx +0 -133
  300. package/.docs/raw/docs/ui/file.mdx +0 -159
  301. package/.docs/raw/docs/ui/follow-up-suggestions.mdx +0 -82
  302. package/.docs/raw/docs/ui/image.mdx +0 -102
  303. package/.docs/raw/docs/ui/markdown.mdx +0 -64
  304. package/.docs/raw/docs/ui/mcp-config.mdx +0 -107
  305. package/.docs/raw/docs/ui/mermaid.mdx +0 -92
  306. package/.docs/raw/docs/ui/message-timing.mdx +0 -93
  307. package/.docs/raw/docs/ui/model-selector.mdx +0 -455
  308. package/.docs/raw/docs/ui/number-roll.mdx +0 -154
  309. package/.docs/raw/docs/ui/part-grouping.mdx +0 -614
  310. package/.docs/raw/docs/ui/quote.mdx +0 -211
  311. package/.docs/raw/docs/ui/reasoning.mdx +0 -186
  312. package/.docs/raw/docs/ui/scrollbar.mdx +0 -77
  313. package/.docs/raw/docs/ui/select.mdx +0 -254
  314. package/.docs/raw/docs/ui/sources.mdx +0 -177
  315. package/.docs/raw/docs/ui/streamdown.mdx +0 -392
  316. package/.docs/raw/docs/ui/syntax-highlighting.mdx +0 -205
  317. package/.docs/raw/docs/ui/tabs.mdx +0 -271
  318. package/.docs/raw/docs/ui/thread-list.mdx +0 -372
  319. package/.docs/raw/docs/ui/thread.mdx +0 -512
  320. package/.docs/raw/docs/ui/tool-fallback.mdx +0 -127
  321. package/.docs/raw/docs/ui/tool-group.mdx +0 -240
  322. package/.docs/raw/docs/ui/voice.mdx +0 -173
  323. package/.docs/raw/docs/utilities/heat-graph.mdx +0 -237
  324. package/.docs/raw/docs/utilities/react-o11y.mdx +0 -362
  325. package/.docs/raw/docs/utilities/tw-shimmer.mdx +0 -212
  326. package/dist/constants.d.ts +0 -14
  327. package/dist/constants.d.ts.map +0 -1
  328. package/dist/constants.js +0 -19
  329. package/dist/constants.js.map +0 -1
  330. package/dist/prepare-docs/code-examples.d.ts +0 -5
  331. package/dist/prepare-docs/code-examples.d.ts.map +0 -1
  332. package/dist/prepare-docs/code-examples.js +0 -117
  333. package/dist/prepare-docs/code-examples.js.map +0 -1
  334. package/dist/prepare-docs/copy-raw.d.ts +0 -5
  335. package/dist/prepare-docs/copy-raw.d.ts.map +0 -1
  336. package/dist/prepare-docs/copy-raw.js +0 -49
  337. package/dist/prepare-docs/copy-raw.js.map +0 -1
  338. package/dist/prepare-docs/prepare.d.ts +0 -1
  339. package/dist/prepare-docs/prepare.js +0 -22
  340. package/dist/prepare-docs/prepare.js.map +0 -1
  341. package/dist/prompts/xulux-playground.d.ts +0 -12
  342. package/dist/prompts/xulux-playground.d.ts.map +0 -1
  343. package/dist/prompts/xulux-playground.js +0 -33
  344. package/dist/prompts/xulux-playground.js.map +0 -1
  345. package/dist/tools/docs.d.ts +0 -22
  346. package/dist/tools/docs.d.ts.map +0 -1
  347. package/dist/tools/docs.js +0 -177
  348. package/dist/tools/docs.js.map +0 -1
  349. package/dist/tools/examples.d.ts +0 -24
  350. package/dist/tools/examples.d.ts.map +0 -1
  351. package/dist/tools/examples.js +0 -87
  352. package/dist/tools/examples.js.map +0 -1
  353. package/dist/tools/resources.d.ts +0 -6
  354. package/dist/tools/resources.d.ts.map +0 -1
  355. package/dist/tools/resources.js +0 -75
  356. package/dist/tools/resources.js.map +0 -1
  357. package/dist/tools/search.d.ts +0 -24
  358. package/dist/tools/search.d.ts.map +0 -1
  359. package/dist/tools/search.js +0 -39
  360. package/dist/tools/search.js.map +0 -1
  361. package/dist/tools/tests/mcp-test-client.d.ts +0 -15
  362. package/dist/tools/tests/mcp-test-client.d.ts.map +0 -1
  363. package/dist/tools/tests/mcp-test-client.js +0 -68
  364. package/dist/tools/tests/mcp-test-client.js.map +0 -1
  365. package/dist/tools/tests/test-setup.d.ts +0 -7
  366. package/dist/tools/tests/test-setup.d.ts.map +0 -1
  367. package/dist/tools/tests/test-setup.js +0 -36
  368. package/dist/tools/tests/test-setup.js.map +0 -1
  369. package/dist/tools/xulux-templates.d.ts +0 -58
  370. package/dist/tools/xulux-templates.d.ts.map +0 -1
  371. package/dist/tools/xulux-templates.js +0 -84
  372. package/dist/tools/xulux-templates.js.map +0 -1
  373. package/dist/utils/cache.d.ts +0 -5
  374. package/dist/utils/cache.d.ts.map +0 -1
  375. package/dist/utils/cache.js +0 -18
  376. package/dist/utils/cache.js.map +0 -1
  377. package/dist/utils/logger.d.ts +0 -10
  378. package/dist/utils/logger.d.ts.map +0 -1
  379. package/dist/utils/logger.js +0 -20
  380. package/dist/utils/logger.js.map +0 -1
  381. package/dist/utils/mcp-format.d.ts +0 -11
  382. package/dist/utils/mcp-format.d.ts.map +0 -1
  383. package/dist/utils/mcp-format.js +0 -14
  384. package/dist/utils/mcp-format.js.map +0 -1
  385. package/dist/utils/mdx.d.ts +0 -12
  386. package/dist/utils/mdx.d.ts.map +0 -1
  387. package/dist/utils/mdx.js +0 -45
  388. package/dist/utils/mdx.js.map +0 -1
  389. package/dist/utils/paths.d.ts +0 -12
  390. package/dist/utils/paths.d.ts.map +0 -1
  391. package/dist/utils/paths.js +0 -93
  392. package/dist/utils/paths.js.map +0 -1
  393. package/dist/utils/search.d.ts +0 -10
  394. package/dist/utils/search.d.ts.map +0 -1
  395. package/dist/utils/search.js +0 -97
  396. package/dist/utils/search.js.map +0 -1
  397. package/dist/utils/security.d.ts +0 -5
  398. package/dist/utils/security.d.ts.map +0 -1
  399. package/dist/utils/security.js +0 -22
  400. package/dist/utils/security.js.map +0 -1
  401. package/dist/xulux/catalog-client.d.ts +0 -14
  402. package/dist/xulux/catalog-client.d.ts.map +0 -1
  403. package/dist/xulux/catalog-client.js +0 -67
  404. package/dist/xulux/catalog-client.js.map +0 -1
  405. package/dist/xulux/fallback-catalog.d.ts +0 -7
  406. package/dist/xulux/fallback-catalog.d.ts.map +0 -1
  407. package/dist/xulux/fallback-catalog.js +0 -47
  408. package/dist/xulux/fallback-catalog.js.map +0 -1
  409. package/dist/xulux/fetch-sandbox.d.ts +0 -5
  410. package/dist/xulux/fetch-sandbox.d.ts.map +0 -1
  411. package/dist/xulux/fetch-sandbox.js +0 -40
  412. package/dist/xulux/fetch-sandbox.js.map +0 -1
  413. package/dist/xulux/template-service.d.ts +0 -84
  414. package/dist/xulux/template-service.d.ts.map +0 -1
  415. package/dist/xulux/template-service.js +0 -223
  416. package/dist/xulux/template-service.js.map +0 -1
  417. package/dist/xulux/types.d.ts +0 -55
  418. package/dist/xulux/types.d.ts.map +0 -1
  419. package/dist/xulux/types.js +0 -6
  420. package/dist/xulux/types.js.map +0 -1
  421. package/src/constants.ts +0 -24
  422. package/src/prepare-docs/code-examples.ts +0 -158
  423. package/src/prepare-docs/copy-raw.ts +0 -50
  424. package/src/prepare-docs/prepare.ts +0 -24
  425. package/src/prompts/xulux-playground.ts +0 -36
  426. package/src/tools/docs.ts +0 -255
  427. package/src/tools/examples.ts +0 -114
  428. package/src/tools/resources.ts +0 -111
  429. package/src/tools/search.ts +0 -46
  430. package/src/tools/tests/completions.test.ts +0 -60
  431. package/src/tools/tests/directory-size-cap.test.ts +0 -50
  432. package/src/tools/tests/docs.test.ts +0 -144
  433. package/src/tools/tests/examples.test.ts +0 -94
  434. package/src/tools/tests/integration.test.ts +0 -45
  435. package/src/tools/tests/json-parsing.test.ts +0 -23
  436. package/src/tools/tests/listings-cache.test.ts +0 -19
  437. package/src/tools/tests/mcp-protocol.test.ts +0 -216
  438. package/src/tools/tests/mcp-test-client.ts +0 -111
  439. package/src/tools/tests/path-traversal.test.ts +0 -81
  440. package/src/tools/tests/resources.test.ts +0 -133
  441. package/src/tools/tests/search.test.ts +0 -37
  442. package/src/tools/tests/test-setup.ts +0 -50
  443. package/src/tools/tests/xulux-templates.test.ts +0 -262
  444. package/src/tools/xulux-templates.ts +0 -141
  445. package/src/utils/cache.ts +0 -20
  446. package/src/utils/logger.ts +0 -20
  447. package/src/utils/mcp-format.ts +0 -14
  448. package/src/utils/mdx.ts +0 -59
  449. package/src/utils/paths.ts +0 -139
  450. package/src/utils/search.ts +0 -131
  451. package/src/utils/security.ts +0 -52
  452. package/src/utils/tests/cache.test.ts +0 -51
  453. package/src/utils/tests/mcp-format.test.ts +0 -22
  454. package/src/utils/tests/security.test.ts +0 -119
  455. package/src/xulux/catalog-client.ts +0 -105
  456. package/src/xulux/fallback-catalog.ts +0 -63
  457. package/src/xulux/fetch-sandbox.ts +0 -56
  458. package/src/xulux/template-service.ts +0 -406
  459. package/src/xulux/types.ts +0 -60
@@ -1,152 +0,0 @@
1
- ---
2
- title: Custom Resumable Stream Stores
3
- description: Implement the ResumableStreamStore interface to back resumable streams with Postgres, Cloudflare Durable Objects, Upstash REST, InstantDB, or any other backend.
4
- platforms: ["react"]
5
- ---
6
-
7
- The built-in InMemory and Redis adapters cover most deployments. Write your own `ResumableStreamStore` when you need a backend you already operate (Postgres, MySQL), an edge-native primitive (Cloudflare Durable Objects, Workers KV), an HTTP-only key-value service (Upstash REST), or a realtime database (InstantDB). The contract is six async methods over an opaque `streamId` and a monotonic byte log.
8
-
9
- ## Interface walkthrough
10
-
11
- The full interface lives in `assistant-stream/resumable`:
12
-
13
- ```ts title="packages/assistant-stream/src/resumable/types.ts"
14
- export interface ResumableStreamStore {
15
- acquire(
16
- streamId: string,
17
- options?: ResumableStreamAcquireOptions,
18
- ): Promise<ResumableStreamRole>;
19
- append(streamId: string, chunk: Uint8Array): Promise<void>;
20
- finalize(
21
- streamId: string,
22
- status: "done" | "error",
23
- error?: string,
24
- ): Promise<void>;
25
- read(
26
- streamId: string,
27
- cursor: string,
28
- signal: AbortSignal,
29
- ): AsyncIterable<ResumableStreamEntry>;
30
- status(streamId: string): Promise<ResumableStreamStatus>;
31
- delete(streamId: string): Promise<void>;
32
- }
33
- ```
34
-
35
- `acquire(streamId, options?)` arbitrates ownership. The first caller for a given `streamId` resolves to `"producer"`; every later caller, including those arriving after `finalize`, resolves to `"consumer"`. Implementations must perform the check and the insert atomically (see below). `options.ttlMs` overrides the store default for this stream; honor it when you set the expiration timestamp.
36
-
37
- `append(streamId, chunk)` adds a `Uint8Array` to the log under a fresh, monotonically increasing cursor. Callers expect the chunk to be observable to `read` before the promise resolves. Implementations should refresh the TTL on each call so a stream that is still actively producing does not expire mid-flight, and should reject when the stream is missing or already finalized.
38
-
39
- `finalize(streamId, status, error?)` flips the stream into a terminal state. Pending and future `read` iterables drain buffered entries and then either complete (`"done"`) or throw with `error` (`"error"`). Implementations must make `finalize` idempotent: a duplicate call with the same status is a no-op, and the producer task may retry on transient errors.
40
-
41
- `read(streamId, cursor, signal)` is the only streaming method. It yields every entry whose cursor sorts strictly after the supplied `cursor`, then waits for new appends, then completes when the stream finalizes. Aborting `signal` resolves the iterable cleanly without throwing. Networked stores typically combine a bounded fetch loop with pub/sub, long-poll, or notify wakeups; do not busy-loop.
42
-
43
- `status(streamId)` returns one of `"streaming" | "done" | "error" | "missing"` synchronously with respect to the underlying store. It exists so the context can decide whether to start a new producer or attach a consumer without holding a `read` iterator open.
44
-
45
- `delete(streamId)` removes all state for the stream. It must be a no-op when the stream does not exist, and it should cause active `read` iterables to terminate (treat outstanding readers as if the stream finalized).
46
-
47
- ## Acquire semantics
48
-
49
- `acquire` is the only method that requires linearizability across processes. Two route handlers that race to start the same `streamId` must see exactly one `"producer"` result; the loser becomes a `"consumer"` and replays the winner's bytes. A single-process store can guard a `Map` with a synchronous `if (!map.has(id)) map.set(id, ...)`. Networked stores need a primitive that does the check and the insert in one round trip:
50
-
51
- - Redis: `SET key value NX EX ttl`, or `INCR` against a per-stream counter.
52
- - Postgres: `INSERT ... ON CONFLICT (stream_id) DO NOTHING RETURNING ...`.
53
- - Durable Objects: a single object instance per `streamId` plus a boolean field.
54
- - Upstash REST: `set` with `nx=true`.
55
-
56
- If your backend cannot offer atomicity, do not paper over it with read-then-write; you will silently produce two writers for the same stream under contention, and consumers will observe interleaved bytes.
57
-
58
- ## The cursor contract
59
-
60
- Cursors are opaque strings. Callers never inspect them; the store assigns them, the context echoes them back on the next `read` call, and the store uses them to resume from the correct position. Two rules:
61
-
62
- - Cursors must be strictly monotonic per stream. Whatever scheme you pick (sequence number, ULID, Postgres `bigserial`, Redis stream id), entry N+1 sorts after entry N.
63
- - The empty string means start from the beginning. `read(streamId, "", signal)` yields every entry the store has, oldest first.
64
-
65
- You do not need cross-stream ordering. You do need a deterministic mapping from cursor back to position so that `read` can resume a consumer that disconnected mid-replay.
66
-
67
- ## A worked example
68
-
69
- A `Map`-backed implementation suitable for a single-process server. It is deliberately small and skips TTL eviction; treat it as a starting point for a custom backend rather than a replacement for `createInMemoryResumableStreamStore`.
70
-
71
- ```ts title="/lib/map-resumable-store.ts"
72
- import type { ResumableStreamStore } from "assistant-stream/resumable";
73
-
74
- type State = {
75
- entries: { cursor: string; chunk: Uint8Array }[];
76
- seq: number;
77
- final?: { status: "done" | "error"; error?: string };
78
- waiters: Array<() => void>;
79
- };
80
-
81
- export function createMapResumableStreamStore(): ResumableStreamStore {
82
- const streams = new Map<string, State>();
83
- const wake = (s: State) => s.waiters.splice(0).forEach((fn) => fn());
84
- return {
85
- async acquire(id) {
86
- if (streams.has(id)) return "consumer";
87
- streams.set(id, { entries: [], seq: 0, waiters: [] });
88
- return "producer";
89
- },
90
- async append(id, chunk) {
91
- const s = streams.get(id);
92
- if (!s || s.final) throw new Error(`Cannot append: ${id}`);
93
- s.entries.push({ cursor: (++s.seq).toString(36), chunk });
94
- wake(s);
95
- },
96
- async finalize(id, status, error) {
97
- const s = streams.get(id);
98
- if (!s || s.final) return;
99
- s.final = { status, error };
100
- wake(s);
101
- },
102
- async *read(id, cursor, signal) {
103
- const s = streams.get(id);
104
- if (!s) throw new Error(`Stream not found: ${id}`);
105
- let i = cursor === "" ? 0 : Number.parseInt(cursor, 36);
106
- while (!signal.aborted) {
107
- while (i < s.entries.length) yield s.entries[i++]!;
108
- if (s.final) {
109
- if (s.final.status === "error") throw new Error(s.final.error);
110
- return;
111
- }
112
- await new Promise<void>((r) => {
113
- s.waiters.push(r);
114
- signal.addEventListener("abort", () => r(), { once: true });
115
- });
116
- }
117
- },
118
- async status(id) {
119
- const s = streams.get(id);
120
- return !s ? "missing" : s.final ? s.final.status : "streaming";
121
- },
122
- async delete(id) {
123
- const s = streams.get(id);
124
- if (!s) return;
125
- streams.delete(id);
126
- s.final ??= { status: "done" };
127
- wake(s);
128
- },
129
- };
130
- }
131
- ```
132
-
133
- ## TTL and eviction
134
-
135
- `acquire` receives `options.ttlMs`; if absent, fall back to a store-level default (the built-in stores use 24 hours). Refresh the expiration on every `append` and on `finalize` so a stream that finishes near the deadline still has time to be consumed. Persist the TTL alongside the entries so a worker reading the stream much later can decide whether the data is still valid.
136
-
137
- When a stream expires, treat it the same as `finalize(streamId, "error", "Stream expired")`: any active `read` iterable must throw or terminate, and `status` must transition to `"missing"` once the eviction has run. Stores backed by Redis or a similar TTL-aware engine can lean on the engine's own expiration; SQL-backed stores need a periodic sweep, and Durable Objects can use `setAlarm`.
138
-
139
- ## Wiring it up
140
-
141
- `createResumableStreamContext` takes any object that satisfies `ResumableStreamStore`. There is no registry and no extra configuration; pass your instance as `store`:
142
-
143
- ```ts title="/lib/resumable-context.ts"
144
- import { createResumableStreamContext } from "assistant-stream/resumable";
145
- import { createMapResumableStreamStore } from "@/lib/map-resumable-store";
146
-
147
- export const resumableContext = createResumableStreamContext({
148
- store: createMapResumableStreamStore(),
149
- });
150
- ```
151
-
152
- From this point the route handlers in [Resumable Streams](/docs/guides/resumable-streams) work unchanged: `resumableContext.run(streamId, makeStream)` calls your `acquire`, `append`, and `finalize`, and `resumableContext.resume(streamId)` calls your `read`.
@@ -1,292 +0,0 @@
1
- ---
2
- title: "Resumable Streams"
3
- description: Persist an in-flight LLM response on the server so the client can reload, lose its connection, or open a new tab and pick up the same stream.
4
- platforms: ["react"]
5
- ---
6
-
7
- `assistant-stream/resumable` lets you continue a streaming LLM response across client reconnects. The server keeps writing to a store while the original request is in flight; if the browser reloads or loses its connection, a follow-up request replays the persisted bytes plus any new ones until the producer finalizes.
8
-
9
- It works with any encoder that already ships in `assistant-stream` (the AI SDK UI message stream, the data stream protocol, the assistant transport SSE format, or your own), because persistence happens at the byte level after encoding.
10
-
11
- ## What it solves
12
-
13
- A user sends a long prompt, walks away, and reloads the tab. Without resumable streams the LLM call is wasted; with them the client picks up where it left off. The same flow handles dropped mobile connections and lets a stream started on one device be read on another, gated by an opaque stream id.
14
-
15
- If your responses are short or you do not care about reload survival, the standard `streamText().toUIMessageStreamResponse()` path is enough.
16
-
17
- ## Server side: minimum wiring
18
-
19
- Construct a `ResumableStreamContext` once per process and reuse it across requests. The context is the seam between your route handlers and the storage backend.
20
-
21
- ```ts title="/lib/resumable-context.ts"
22
- import {
23
- createInMemoryResumableStreamStore,
24
- createResumableStreamContext,
25
- } from "assistant-stream/resumable";
26
-
27
- const store = createInMemoryResumableStreamStore();
28
- export const resumableContext = createResumableStreamContext({ store });
29
- ```
30
-
31
- In your chat route, wrap the response body in `ctx.run(streamId, makeStream)`. The first caller for `streamId` becomes the producer (your `makeStream` callback runs); later callers and reconnects become consumers that replay the persisted bytes.
32
-
33
- ```ts title="/app/api/chat/route.ts"
34
- import { streamText } from "ai";
35
- import { RESUMABLE_STREAM_ID_HEADER } from "assistant-stream/resumable";
36
- import { resumableContext } from "@/lib/resumable-context";
37
-
38
- export async function POST(req: Request) {
39
- const { messages } = await req.json();
40
- const streamId = crypto.randomUUID();
41
-
42
- const result = streamText({ /* model, messages, tools, ... */ });
43
- const sourceBody = result.toUIMessageStreamResponse().body!;
44
-
45
- const stream = await resumableContext.run(streamId, () => sourceBody);
46
-
47
- return new Response(stream, {
48
- headers: {
49
- "Content-Type": "text/event-stream",
50
- [RESUMABLE_STREAM_ID_HEADER]: streamId,
51
- },
52
- });
53
- }
54
- ```
55
-
56
- A separate GET endpoint replays the persisted bytes for reconnecting clients. `ctx.resume(streamId)` returns `null` when no stream exists; use `ctx.requireResume(streamId)` if you prefer to surface a `ResumableStreamError` with code `"missing"` instead.
57
-
58
- ```ts title="/app/api/chat/resume/[streamId]/route.ts"
59
- import { RESUMABLE_STREAM_ID_HEADER } from "assistant-stream/resumable";
60
- import { resumableContext } from "@/lib/resumable-context";
61
-
62
- export async function GET(
63
- _req: Request,
64
- ctx: { params: Promise<{ streamId: string }> },
65
- ) {
66
- const { streamId } = await ctx.params;
67
- const stream = await resumableContext.resume(streamId);
68
- if (!stream) {
69
- return new Response(JSON.stringify({ error: "stream not found" }), {
70
- status: 404,
71
- headers: { "Content-Type": "application/json" },
72
- });
73
- }
74
- return new Response(stream, {
75
- headers: {
76
- "Content-Type": "text/event-stream",
77
- [RESUMABLE_STREAM_ID_HEADER]: streamId,
78
- },
79
- });
80
- }
81
- ```
82
-
83
- The context exposes two more verbs: `ctx.status(streamId)` returns `"streaming" | "done" | "error" | "missing"`, and `ctx.delete(streamId)` removes all persisted state for a stream and terminates active readers. The remaining options on `createResumableStreamContext` (`onAcquire`, `onAppend`, `onFinalize`, `onError`) are observability hooks covered in [Resumable Stream Deployment](/docs/guides/resumable-stream-deployment).
84
-
85
- ## Client side: native integration
86
-
87
- `@assistant-ui/react-ai-sdk` ships a `resumable` option on `AssistantChatTransport`. It captures the stream id from the response header, redirects `chat.resumeStream()` reconnects to your resume route, and clears the stored id when the response finishes naturally. Pair it with `useChatRuntime`, which fires `chat.resumeStream()` whenever its resumable storage reports a pending id, including ids discovered after mount.
88
-
89
- ```tsx title="/app/page.tsx"
90
- "use client";
91
-
92
- import { AssistantRuntimeProvider } from "@assistant-ui/react";
93
- import {
94
- AssistantChatTransport,
95
- createResumableSessionStorage,
96
- useChatRuntime,
97
- } from "@assistant-ui/react-ai-sdk";
98
- import { useMemo } from "react";
99
- import { Thread } from "@/components/assistant-ui/thread";
100
-
101
- const storage = createResumableSessionStorage();
102
-
103
- export default function Page() {
104
- const transport = useMemo(
105
- () =>
106
- new AssistantChatTransport({
107
- api: "/api/chat",
108
- resumable: {
109
- storage,
110
- resumeApi: (streamId) => `/api/chat/resume/${streamId}`,
111
- },
112
- }),
113
- [],
114
- );
115
- const runtime = useChatRuntime({
116
- transport,
117
- onResumeError: (error) => {
118
- console.error("Could not resume the previous response", error);
119
- },
120
- });
121
-
122
- return (
123
- <AssistantRuntimeProvider runtime={runtime}>
124
- <Thread />
125
- </AssistantRuntimeProvider>
126
- );
127
- }
128
- ```
129
-
130
- `onResumeError` runs when the client finds a stored stream id but the reconnect attempt fails. Use it to show a toast, report telemetry, or mark the thread as needing retry. Assistant-ui clears the failed stream id after the callback unless a newer id has replaced it.
131
-
132
- `createResumableSessionStorage` returns a `ResumableClientStorage` backed by `window.sessionStorage`. Pass `{ key }` to namespace per route or chat surface; `key` also accepts a getter that is read lazily on every access, so you can derive it from the active thread's identity (see [Multiple threads](#multiple-threads)). While the getter returns `undefined`, reads report no pending stream and writes are dropped. Reuse one storage instance per key, because separate instances do not synchronize their in-memory caches. The persisted entry survives reloads, while in-memory ownership prevents one mounted thread from attaching to another thread's pending stream. An idle follower that learns a stream id from its backend can call `storage.setStreamId(streamId, threadId)` after the corresponding message exists in local history; the runtime attaches when that thread is current, without requiring a remount. The built-in storage holds one pending stream id per key; the [Multiple threads](#multiple-threads) pattern gives each thread its own key, so several threads stay resumable at once. A custom `ResumableClientStorage` can instead key its records by the optional `threadId` arguments and implement `subscribe(listener, threadId)` for post-mount updates, or replace the storage methods entirely. If you are running on a transport that already wraps `fetch` or `prepareReconnectToStreamRequest`, the `resumable` option composes with your existing handlers.
133
-
134
- The default finish detector scans the SSE body for the AI SDK `"type":"finish"` marker. Override `isFinishEvent` on the `resumable` option when you ship a custom encoder.
135
-
136
- ### Multiple threads
137
-
138
- The snippet above stores the pending stream id under one `sessionStorage` key, which is correct for a single chat surface. Under a thread list runtime (`useRemoteThreadListRuntime`, which `useChatRuntime` wraps) with more than one alive thread, a single shared key is written and cleared by whichever thread acts last: switch threads while a response is in flight and the response header writes its stream id to the shared key, which the thread you switched to reads on mount and resumes — replaying the other conversation's stream into this one. An unscoped clear when a stream finishes can also drop another thread's pending id. And after a reload, a pending id under the shared key is claimed by whichever thread is main at mount, which with a thread list is a fresh empty thread rather than the one that started the stream.
139
-
140
- Scope the key to the thread, and construct the transport and storage per thread inside the per-thread runtime hook rather than once at module level. Derive the key from the thread's identity with a getter so it is read lazily on every access:
141
-
142
- ```tsx title="/app/page.tsx"
143
- "use client";
144
-
145
- import {
146
- AssistantCloud,
147
- AssistantRuntimeProvider,
148
- useAui,
149
- useCloudThreadListAdapter,
150
- useRemoteThreadListRuntime,
151
- } from "@assistant-ui/react";
152
- import {
153
- AssistantChatTransport,
154
- createResumableSessionStorage,
155
- useChatRuntime,
156
- } from "@assistant-ui/react-ai-sdk";
157
- import { useMemo } from "react";
158
- import { Thread } from "@/components/assistant-ui/thread";
159
- import { ThreadList } from "@/components/assistant-ui/thread-list";
160
-
161
- const cloud = new AssistantCloud({
162
- baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
163
- anonymous: true,
164
- });
165
-
166
- function ResumableThreadRuntime() {
167
- const aui = useAui();
168
- const transport = useMemo(
169
- () =>
170
- new AssistantChatTransport({
171
- api: "/api/chat",
172
- resumable: {
173
- storage: createResumableSessionStorage({
174
- key: () => {
175
- const item = aui.threadListItem.getState();
176
- return `aui-resumable-stream-id:${item.remoteId ?? item.id}`;
177
- },
178
- }),
179
- resumeApi: (streamId) => `/api/chat/resume/${streamId}`,
180
- },
181
- }),
182
- [aui],
183
- );
184
- return useChatRuntime({ transport });
185
- }
186
-
187
- export default function Page() {
188
- const adapter = useCloudThreadListAdapter({ cloud });
189
- const runtime = useRemoteThreadListRuntime({
190
- adapter,
191
- runtimeHook: ResumableThreadRuntime,
192
- });
193
-
194
- return (
195
- <AssistantRuntimeProvider runtime={runtime}>
196
- <ThreadList />
197
- <Thread />
198
- </AssistantRuntimeProvider>
199
- );
200
- }
201
- ```
202
-
203
- `useCloudThreadListAdapter` is the same adapter `useChatRuntime({ cloud })` builds internally, so cloud thread history and attachments keep working; to bring your own backend, pass a custom `RemoteThreadListAdapter` instead. Each thread's runtime hook constructs its own transport and storage, keyed by that thread's identity, so one conversation's stream id can never be read or cleared by another. `useChatRuntime` is a no-op thread list when nested as a `runtimeHook`, so it only runs the per-thread chat runtime against the per-thread transport; the real thread list is the outer `useRemoteThreadListRuntime`.
204
-
205
- Key by `remoteId ?? id` under a recognizable prefix, read lazily. A brand-new thread has no `remoteId` yet, but the transport initializes the thread before the request goes out, so by the time the response header delivers the stream id the getter resolves to the `remoteId`. After a reload the same conversation comes back with that `remoteId` as its id, so the stored entry is found again and the pending stream resumes. The local-id fallback covers a thread that has never sent, whose key nothing else reads or writes. Keying by the local id alone would break resume across reloads for threads created in the current session, because their local `__LOCALID_` id is replaced by the `remoteId` when the list reloads.
206
-
207
- ## Storage choices
208
-
209
- The core package ships `createInMemoryResumableStreamStore` for development and tests. State lives in a process-local `Map`, so it does not survive a server restart. Useful options include `defaultTtlMs`, `maxChunkBytes`, `maxEntriesPerStream`, `maxStreams`, and `gcIntervalMs` for periodic eviction.
210
-
211
- For production, use one of the optional Redis adapters via the `assistant-stream/resumable/redis` (node-redis v5) or `assistant-stream/resumable/ioredis` sub-paths. Both adapters batch the per-append `XADD` and TTL refresh into a single pipelined round trip, store chunk values as binary, and accept the same `keyPrefix`, `defaultTtlMs`, `pollIntervalMs`, and `maxChunkBytes` options. Cluster routing works because each stream's keys share a `{streamId}` hash tag.
212
-
213
- ```ts title="/lib/resumable-context.ts"
214
- import {
215
- createResumableStreamContext,
216
- type ResumableStreamStore,
217
- } from "assistant-stream/resumable";
218
-
219
- async function createStore(): Promise<ResumableStreamStore> {
220
- if (!process.env.REDIS_URL) {
221
- const { createInMemoryResumableStreamStore } = await import(
222
- "assistant-stream/resumable"
223
- );
224
- return createInMemoryResumableStreamStore();
225
- }
226
- const { createClient } = await import("redis");
227
- const { createRedisResumableStreamStore } = await import(
228
- "assistant-stream/resumable/redis"
229
- );
230
- const client = createClient({ url: process.env.REDIS_URL });
231
- await client.connect();
232
- return createRedisResumableStreamStore(client);
233
- }
234
-
235
- export const resumableContext = createResumableStreamContext({
236
- store: await createStore(),
237
- });
238
- ```
239
-
240
- For Postgres, Cloudflare Durable Objects, Upstash REST, or any other backend, implement the `ResumableStreamStore` interface directly. See [Custom Resumable Stream Stores](/docs/guides/resumable-stream-stores) for the contract walkthrough and a worked example.
241
-
242
- ## Production checklist
243
-
244
- - **Auth.** The resume route in the snippets above will serve any caller that knows the stream id. Bind `streamId` to the requesting user at acquire time and verify the binding inside the resume handler. Treat the id as opaque, not as a credential; it leaks via response headers, `sessionStorage`, browser history, and access logs.
245
- - **`waitUntil` on serverless.** On Vercel and Cloudflare the request handler is killed once the response returns, which interrupts the producer task. Pass `after` from `next/server` (or your platform's `ctx.waitUntil`) when constructing the context so the task survives past the response: `createResumableStreamContext({ store, waitUntil: after })`.
246
- - **TTL.** Streams expire 24 hours after the last write by default. Configure with `defaultTtlMs` on the store, or override per deployment via `ttlMs` on the context. Match TTLs across the store, any owner-binding key, and any signed cookie that references a `streamId`.
247
- - **Stream id format.** The Redis adapters validate `streamId` against `/^[A-Za-z0-9_.:-]{1,256}$/` to keep keys well-formed. UUIDv4 is fine.
248
-
249
- For the full treatment of authorization, multi-tenant key prefixes, observability hooks, resource limits, and incident response, see [Resumable Stream Deployment](/docs/guides/resumable-stream-deployment).
250
-
251
- A new `ResumableStreamError` class is exported from `assistant-stream/resumable` with codes `"missing" | "exists" | "finalized" | "invalid-id"`; catch it in the resume route to distinguish "stream gone" from other failures.
252
-
253
- ## Helpers for `AssistantStreamController` callbacks
254
-
255
- If you produce streams via `createAssistantStream` rather than the AI SDK, the package ships two helpers that bridge the controller-callback style and any encoder to the store:
256
-
257
- ```ts
258
- import {
259
- createResumableAssistantStreamResponse,
260
- createResumeAssistantStreamResponse,
261
- } from "assistant-stream/resumable";
262
- import { resumableContext } from "@/lib/resumable-context";
263
-
264
- // POST handler
265
- return createResumableAssistantStreamResponse({
266
- context: resumableContext,
267
- streamId,
268
- callback: (controller) => {
269
- /* same shape as createAssistantStreamResponse */
270
- },
271
- });
272
-
273
- // GET resume handler
274
- return createResumeAssistantStreamResponse({
275
- context: resumableContext,
276
- streamId,
277
- });
278
- ```
279
-
280
- Both helpers default to the data-stream encoder; pass `encoder: () => new AssistantTransportEncoder()` (or any custom encoder) to override. They set the `x-resumable-stream-id` response header automatically, which is what `AssistantChatTransport`'s `resumable` adapter looks for.
281
-
282
- ## Example app
283
-
284
- [`examples/with-resumable-stream`](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-resumable-stream) is a runnable Next.js app that uses `useChat`, the `resumable` transport option, and `useChatRuntime`. It falls back to a built-in mock when `OPENAI_API_KEY` is unset, and switches the store from in-memory to Redis when `REDIS_URL` is set.
285
-
286
- ```sh
287
- npx assistant-ui create my-app -e with-resumable-stream
288
- ```
289
-
290
- To drop the resumable chat and resume routes into an existing project (in-memory store only; upgrade via [Storage choices](#storage-choices)):
291
-
292
- <InstallCommand shadcn={["ai-sdk-backend-resumable"]} />