@assistant-ui/mcp-docs-server 0.1.31 → 0.1.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 (247) hide show
  1. package/.docs/organized/code-examples/waterfall.md +8 -8
  2. package/.docs/organized/code-examples/with-a2a.md +10 -10
  3. package/.docs/organized/code-examples/with-ag-ui.md +11 -11
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +13 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +13 -13
  6. package/.docs/organized/code-examples/with-assistant-transport.md +10 -10
  7. package/.docs/organized/code-examples/with-browser-extension.md +345 -0
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +54 -17
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +13 -13
  10. package/.docs/organized/code-examples/with-cloud.md +13 -13
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +13 -13
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +17 -16
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +17 -16
  14. package/.docs/organized/code-examples/with-expo.md +24 -24
  15. package/.docs/organized/code-examples/with-external-store.md +10 -10
  16. package/.docs/organized/code-examples/with-ffmpeg.md +13 -13
  17. package/.docs/organized/code-examples/with-generative-ui.md +210 -13
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -10
  19. package/.docs/organized/code-examples/with-heat-graph.md +8 -8
  20. package/.docs/organized/code-examples/with-image-generation.md +454 -0
  21. package/.docs/organized/code-examples/with-interactables.md +13 -13
  22. package/.docs/organized/code-examples/with-langchain.md +12 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +15 -12
  24. package/.docs/organized/code-examples/with-livekit.md +18 -17
  25. package/.docs/organized/code-examples/with-mcp.md +748 -0
  26. package/.docs/organized/code-examples/with-opencode.md +11 -11
  27. package/.docs/organized/code-examples/with-parent-id-grouping.md +11 -11
  28. package/.docs/organized/code-examples/with-react-hook-form.md +14 -14
  29. package/.docs/organized/code-examples/with-react-ink.md +4 -4
  30. package/.docs/organized/code-examples/with-react-router.md +15 -15
  31. package/.docs/organized/code-examples/with-resumable-stream.md +660 -0
  32. package/.docs/organized/code-examples/with-store.md +8 -8
  33. package/.docs/organized/code-examples/with-tanstack.md +14 -14
  34. package/.docs/organized/code-examples/with-tap-runtime.md +11 -10
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/index.mdx +2 -2
  37. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  38. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +26 -24
  39. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback.mdx +20 -0
  40. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +20 -12
  41. package/.docs/raw/docs/(reference)/api-reference/adapters/model.mdx +44 -0
  42. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +37 -16
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +12 -23
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +20 -0
  45. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +37 -8
  46. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +11 -9
  47. package/.docs/raw/docs/(reference)/api-reference/context-providers/scoped-providers.mdx +64 -0
  48. package/.docs/raw/docs/(reference)/api-reference/external-store/index.mdx +22 -0
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +52 -0
  50. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +36 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +98 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +18 -13
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +18 -57
  54. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +640 -0
  55. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +15 -28
  56. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +64 -18
  57. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +434 -0
  58. package/.docs/raw/docs/(reference)/api-reference/integrations/cloud-ai-sdk.mdx +24 -0
  59. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +11 -12
  60. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +79 -0
  61. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +52 -0
  62. package/.docs/raw/docs/(reference)/api-reference/model-context/index.mdx +22 -0
  63. package/.docs/raw/docs/(reference)/api-reference/model-context/registry.mdx +20 -0
  64. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +110 -131
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +78 -221
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +127 -242
  67. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +39 -20
  68. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +66 -87
  69. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +50 -58
  70. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +80 -48
  71. package/.docs/raw/docs/(reference)/api-reference/primitives/chain-of-thought.mdx +67 -0
  72. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +323 -461
  73. package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +36 -43
  74. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +29 -24
  75. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +63 -245
  76. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +175 -591
  77. package/.docs/raw/docs/(reference)/api-reference/primitives/queue-item.mdx +65 -0
  78. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +35 -22
  79. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +57 -140
  80. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +70 -161
  81. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +84 -108
  82. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +77 -96
  83. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +173 -349
  84. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +9 -21
  85. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +10 -21
  86. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +15 -70
  87. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +18 -13
  88. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +25 -28
  89. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +11 -63
  90. package/.docs/raw/docs/(reference)/api-reference/runtimes/queue-state.mdx +20 -0
  91. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +11 -48
  92. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +10 -47
  93. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +18 -30
  94. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +68 -0
  95. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +39 -0
  96. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +79 -0
  97. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +42 -0
  98. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +92 -0
  99. package/.docs/raw/docs/(reference)/api-reference/transport/assistant-transport.mdx +48 -0
  100. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +62 -0
  101. package/.docs/raw/docs/(reference)/api-reference/transport/index.mdx +22 -0
  102. package/.docs/raw/docs/(reference)/api-reference/utilities/index.mdx +19 -0
  103. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +131 -0
  104. package/.docs/raw/docs/(reference)/api-reference/voice/index.mdx +22 -0
  105. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +54 -0
  106. package/.docs/raw/docs/(reference)/api-reference/voice/speech-dictation.mdx +36 -0
  107. package/.docs/raw/docs/cloud/ai-sdk.mdx +1 -1
  108. package/.docs/raw/docs/cloud/index.mdx +2 -2
  109. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  110. package/.docs/raw/docs/guides/branching.mdx +1 -1
  111. package/.docs/raw/docs/guides/chain-of-thought.mdx +5 -5
  112. package/.docs/raw/docs/guides/context-api.mdx +4 -4
  113. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  114. package/.docs/raw/docs/guides/editing.mdx +1 -1
  115. package/.docs/raw/docs/guides/generative-ui.mdx +142 -0
  116. package/.docs/raw/docs/guides/image-generation.mdx +74 -0
  117. package/.docs/raw/docs/guides/index.mdx +2 -2
  118. package/.docs/raw/docs/guides/interactables.mdx +2 -2
  119. package/.docs/raw/docs/guides/latex.mdx +2 -2
  120. package/.docs/raw/docs/guides/mcp-apps.mdx +231 -0
  121. package/.docs/raw/docs/guides/mentions.mdx +2 -2
  122. package/.docs/raw/docs/guides/message-timing.mdx +38 -5
  123. package/.docs/raw/docs/guides/multi-agent.mdx +2 -2
  124. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  125. package/.docs/raw/docs/guides/resumable-stream-deployment.mdx +212 -0
  126. package/.docs/raw/docs/guides/resumable-stream-stores.mdx +152 -0
  127. package/.docs/raw/docs/guides/resumable-streams.mdx +210 -0
  128. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  129. package/.docs/raw/docs/guides/speech.mdx +2 -2
  130. package/.docs/raw/docs/guides/suggestions.mdx +88 -4
  131. package/.docs/raw/docs/guides/tool-ui.mdx +2 -2
  132. package/.docs/raw/docs/guides/tools.mdx +66 -5
  133. package/.docs/raw/docs/guides/voice.mdx +2 -2
  134. package/.docs/raw/docs/ink/adapters.mdx +37 -1
  135. package/.docs/raw/docs/ink/custom-backend.mdx +59 -8
  136. package/.docs/raw/docs/ink/index.mdx +10 -11
  137. package/.docs/raw/docs/ink/primitives.mdx +349 -8
  138. package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
  139. package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
  140. package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
  141. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +2 -2
  142. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +282 -0
  143. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +2 -2
  144. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  145. package/.docs/raw/docs/integrations/gateways/index.mdx +9 -4
  146. package/.docs/raw/docs/integrations/index.mdx +15 -3
  147. package/.docs/raw/docs/integrations/observability/langfuse.mdx +8 -1
  148. package/.docs/raw/docs/integrations/observability/langsmith.mdx +8 -4
  149. package/.docs/raw/docs/integrations/tools/react-mcp.mdx +337 -0
  150. package/.docs/raw/docs/primitives/composer.mdx +53 -0
  151. package/.docs/raw/docs/primitives/index.mdx +2 -2
  152. package/.docs/raw/docs/primitives/suggestion.mdx +9 -0
  153. package/.docs/raw/docs/react-native/hooks.mdx +2 -2
  154. package/.docs/raw/docs/react-native/index.mdx +4 -4
  155. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +4 -4
  156. package/.docs/raw/docs/runtimes/a2a/overview.mdx +2 -2
  157. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +2 -2
  158. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +32 -1
  159. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +2 -2
  160. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +7 -2
  161. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
  162. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -0
  163. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +27 -2
  164. package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -1
  165. package/.docs/raw/docs/runtimes/custom/overview.mdx +2 -2
  166. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +2 -2
  167. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  168. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +2 -2
  169. package/.docs/raw/docs/runtimes/opencode/overview.mdx +2 -2
  170. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  171. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +12 -5
  172. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +11 -1
  173. package/.docs/raw/docs/ui/mcp-config.mdx +102 -0
  174. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  175. package/.docs/raw/docs/ui/sources.mdx +17 -0
  176. package/.docs/raw/docs/ui/streamdown.mdx +34 -2
  177. package/.docs/raw/docs/ui/thread-list.mdx +2 -2
  178. package/.docs/raw/docs/ui/thread.mdx +2 -2
  179. package/README.md +14 -72
  180. package/dist/constants.d.ts +12 -9
  181. package/dist/constants.d.ts.map +1 -1
  182. package/dist/constants.js +13 -9
  183. package/dist/constants.js.map +1 -1
  184. package/dist/index.d.ts +7 -3
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +25 -24
  187. package/dist/index.js.map +1 -1
  188. package/dist/prepare-docs/code-examples.d.ts +4 -1
  189. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  190. package/dist/prepare-docs/code-examples.js +109 -121
  191. package/dist/prepare-docs/code-examples.js.map +1 -1
  192. package/dist/prepare-docs/copy-raw.d.ts +4 -1
  193. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  194. package/dist/prepare-docs/copy-raw.js +45 -42
  195. package/dist/prepare-docs/copy-raw.js.map +1 -1
  196. package/dist/prepare-docs/prepare.d.ts +1 -2
  197. package/dist/prepare-docs/prepare.js +17 -17
  198. package/dist/prepare-docs/prepare.js.map +1 -1
  199. package/dist/stdio.d.ts +1 -3
  200. package/dist/stdio.js +6 -3
  201. package/dist/stdio.js.map +1 -1
  202. package/dist/tools/docs.d.ts +20 -15
  203. package/dist/tools/docs.d.ts.map +1 -1
  204. package/dist/tools/docs.js +140 -161
  205. package/dist/tools/docs.js.map +1 -1
  206. package/dist/tools/examples.d.ts +20 -15
  207. package/dist/tools/examples.d.ts.map +1 -1
  208. package/dist/tools/examples.js +74 -86
  209. package/dist/tools/examples.js.map +1 -1
  210. package/dist/tools/tests/test-setup.d.ts +5 -2
  211. package/dist/tools/tests/test-setup.d.ts.map +1 -1
  212. package/dist/tools/tests/test-setup.js +21 -28
  213. package/dist/tools/tests/test-setup.js.map +1 -1
  214. package/dist/utils/logger.d.ts +8 -5
  215. package/dist/utils/logger.d.ts.map +1 -1
  216. package/dist/utils/logger.js +17 -17
  217. package/dist/utils/logger.js.map +1 -1
  218. package/dist/utils/mcp-format.d.ts +8 -5
  219. package/dist/utils/mcp-format.d.ts.map +1 -1
  220. package/dist/utils/mcp-format.js +9 -9
  221. package/dist/utils/mcp-format.js.map +1 -1
  222. package/dist/utils/mdx.d.ts +8 -6
  223. package/dist/utils/mdx.d.ts.map +1 -1
  224. package/dist/utils/mdx.js +22 -22
  225. package/dist/utils/mdx.js.map +1 -1
  226. package/dist/utils/paths.d.ts +9 -6
  227. package/dist/utils/paths.d.ts.map +1 -1
  228. package/dist/utils/paths.js +66 -76
  229. package/dist/utils/paths.js.map +1 -1
  230. package/dist/utils/security.d.ts +4 -1
  231. package/dist/utils/security.d.ts.map +1 -1
  232. package/dist/utils/security.js +19 -40
  233. package/dist/utils/security.js.map +1 -1
  234. package/package.json +5 -5
  235. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +0 -41
  236. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -40
  237. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +0 -260
  238. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -103
  239. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -254
  240. package/dist/prepare-docs/prepare.d.ts.map +0 -1
  241. package/dist/stdio.d.ts.map +0 -1
  242. /package/.docs/raw/docs/{(reference)/migrations → migrations}/deprecation-policy.mdx +0 -0
  243. /package/.docs/raw/docs/{(reference) → migrations}/react-compatibility.mdx +0 -0
  244. /package/.docs/raw/docs/{(reference)/migrations → migrations}/react-langgraph-v0-7.mdx +0 -0
  245. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-11.mdx +0 -0
  246. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-12.mdx +0 -0
  247. /package/.docs/raw/docs/{(reference)/migrations → migrations}/v0-14.mdx +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Suggestions
3
- description: Display suggested prompts to help users get started with your assistant.
2
+ title: Suggested Prompts
3
+ description: Display suggested starter prompts in your AI chat to onboard users faster. Configurable suggestion components for React, built into assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -136,9 +136,93 @@ Suggestions dismiss automatically once the user sends a message because `thread.
136
136
 
137
137
  The primitives available for rendering suggestions are `ThreadPrimitive.Suggestions`, `ThreadPrimitive.SuggestionByIndex`, `SuggestionPrimitive.Title`, `SuggestionPrimitive.Description`, and `SuggestionPrimitive.Trigger`. `ThreadPrimitive.SuggestionByIndex` is useful when you need layout control over a specific suggestion slot rather than iterating all of them. For the full prop reference and usage patterns, see the [Suggestion primitive docs](/docs/primitives/suggestion).
138
138
 
139
- ## Dynamic Suggestions
139
+ ## Runtime driven suggestions
140
140
 
141
- You can dynamically change suggestions based on your application state:
141
+ The static `Suggestions(...)` API covers welcome screens. For follow up prompts that depend on the conversation, a tool result, or your backend, push suggestions through the runtime itself. They land on `thread.suggestions` rather than the static `suggestions` scope, so they render through a different component.
142
+
143
+ ### Local runtime: `SuggestionAdapter`
144
+
145
+ Pass a `suggestion` adapter to `useLocalRuntime`. Its `generate` function runs after every assistant turn and may return a promise or an async generator for streaming updates.
146
+
147
+ ```tsx
148
+ import { useLocalRuntime, type SuggestionAdapter } from "@assistant-ui/react";
149
+
150
+ const suggestionAdapter: SuggestionAdapter = {
151
+ async generate({ messages }) {
152
+ const response = await fetch("/api/follow-ups", {
153
+ method: "POST",
154
+ body: JSON.stringify({ messages }),
155
+ });
156
+ const data: { prompt: string }[] = await response.json();
157
+ return data;
158
+ },
159
+ };
160
+
161
+ const runtime = useLocalRuntime(myChatModel, {
162
+ adapters: { suggestion: suggestionAdapter },
163
+ });
164
+ ```
165
+
166
+ ### External store runtime
167
+
168
+ `useExternalStoreRuntime` exposes a `suggestions` field, so you can drive follow ups straight from your application state.
169
+
170
+ ```tsx
171
+ const [suggestions, setSuggestions] = useState<ThreadSuggestion[]>([]);
172
+
173
+ const runtime = useExternalStoreRuntime({
174
+ messages,
175
+ onNew,
176
+ suggestions,
177
+ });
178
+
179
+ // Push a follow up after a tool result, a stream chunk, or any app event.
180
+ setSuggestions([{ prompt: "Summarize this case" }]);
181
+ ```
182
+
183
+ ### AI SDK runtime
184
+
185
+ `useChatRuntime` and `useAISDKRuntime` accept the same `suggestions` field and forward it to the underlying external store.
186
+
187
+ ```tsx
188
+ const [suggestions, setSuggestions] = useState<ThreadSuggestion[]>([]);
189
+
190
+ const runtime = useChatRuntime({ suggestions });
191
+ ```
192
+
193
+ The local runtime clears its suggestions when a new run starts. External store and AI SDK runtimes keep whatever state you push, so you control the lifetime.
194
+
195
+ ### Rendering runtime suggestions
196
+
197
+ Static suggestions go through `ThreadPrimitive.Suggestions`; runtime suggestions go through `thread.suggestions`. The shadcn registry ships `ThreadFollowupSuggestions` for the common single line pill layout. For a custom layout, read the array yourself:
198
+
199
+ ```tsx
200
+ import { useAuiState, ThreadPrimitive, AuiIf } from "@assistant-ui/react";
201
+
202
+ function FollowUps() {
203
+ const suggestions = useAuiState((s) => s.thread.suggestions);
204
+ return (
205
+ <AuiIf condition={(s) => !s.thread.isEmpty && !s.thread.isRunning}>
206
+ <div className="flex gap-2">
207
+ {suggestions.map((s, i) => (
208
+ <ThreadPrimitive.Suggestion
209
+ key={i}
210
+ prompt={s.prompt}
211
+ method="replace"
212
+ autoSend
213
+ >
214
+ {s.prompt}
215
+ </ThreadPrimitive.Suggestion>
216
+ ))}
217
+ </div>
218
+ </AuiIf>
219
+ );
220
+ }
221
+ ```
222
+
223
+ ## Reacting to application state
224
+
225
+ You can dynamically change the static suggestion list based on your application state:
142
226
 
143
227
  ```tsx
144
228
  import { useMemo } from "react";
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Generative UI
3
- description: Render tool calls as interactive UI instead of plain text.
3
+ description: Render AI tool calls as interactive React components — charts, forms, maps, and custom widgets. Build generative UI patterns in chat with assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -200,7 +200,7 @@ export async function POST(req: Request) {
200
200
  const { messages } = await req.json();
201
201
 
202
202
  const result = streamText({
203
- model: openai("gpt-4o"),
203
+ model: openai("gpt-5.4-nano"),
204
204
  messages: await convertToModelMessages(messages),
205
205
  tools: {
206
206
  getWeather: tool({
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Tools
3
- description: Give your assistant actions like API calls, database queries, and more.
2
+ title: Tool Calling
3
+ description: Add API calls, database queries, and custom actions to your AI chat with assistant-ui's tool calling. Real-time visualization, type safety, and streaming.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -100,6 +100,7 @@ type ToolDefinition =
100
100
  description?: string;
101
101
  parameters: StandardSchemaV1 | JSONSchema7; // e.g. a Zod schema
102
102
  execute: (args, context) => Promise<any>;
103
+ toModelOutput?: (opts) => ToolModelContentPart[]; // see "Multi-modal tool results"
103
104
  render?: (props) => React.ReactNode;
104
105
  }
105
106
  | {
@@ -116,6 +117,66 @@ type ToolDefinition =
116
117
  };
117
118
  ```
118
119
 
120
+ ### Multi-modal Tool Results
121
+
122
+ By default, the value returned from `execute` is sent to the model as a single JSON blob. That is fine for most tools, but it does not work for tools whose useful output is a file or image: a "read PDF" tool, an OCR tool, a chart-rendering tool, etc.
123
+
124
+ `toModelOutput` is an optional callback that maps the developer-facing `execute` result into the multi-modal content the model actually sees. Your `render` function still receives the rich, typed `result`; the model receives the projection.
125
+
126
+ ```tsx
127
+ import { tool } from "@assistant-ui/react";
128
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
129
+ import { z } from "zod";
130
+
131
+ const readPdfTool = tool({
132
+ description: "Fetch a PDF from a URL and return it",
133
+ parameters: z.object({ url: z.string().url() }),
134
+ execute: async ({ url }) => {
135
+ const res = await fetch(url);
136
+ const buf = new Uint8Array(await res.arrayBuffer());
137
+ const base64 = convertUint8ArrayToBase64(buf);
138
+ return { mediaType: "application/pdf", base64, byteLength: buf.byteLength };
139
+ },
140
+ toModelOutput: ({ output }) => [
141
+ { type: "text", text: "PDF contents:" },
142
+ {
143
+ type: "file",
144
+ data: output.base64,
145
+ mediaType: output.mediaType,
146
+ },
147
+ ],
148
+ });
149
+ ```
150
+
151
+ `ToolModelContentPart` is a union of `{ type: "text"; text }` and `{ type: "file"; data; mediaType; filename? }`. Use `mediaType` (e.g. `image/png`, `application/pdf`) to tell the model how to interpret the bytes.
152
+
153
+ When using the AI SDK runtime, frontend tool results round-trip through the AI SDK chat protocol back to your route handler on the next turn. For `toModelOutput` to fire on those round-tripped results, your route handler must also pass the tool registry to `convertToModelMessages`. This is the [same pattern AI SDK documents](https://ai-sdk.dev/docs/reference/ai-sdk-ui/convert-to-model-messages#multi-modal-tool-responses) for any multi-modal tool response:
154
+
155
+ ```ts
156
+ import { frontendTools } from "@assistant-ui/react-ai-sdk";
157
+ import { convertToModelMessages, streamText } from "ai";
158
+
159
+ const aiSDKTools = { ...frontendTools(tools ?? {}) };
160
+
161
+ const result = streamText({
162
+ model,
163
+ // Pass tools to both calls. convertToModelMessages reads `toModelOutput`
164
+ // from `tools[toolName]` to project prior tool results.
165
+ messages: await convertToModelMessages(messages, { tools: aiSDKTools }),
166
+ tools: aiSDKTools,
167
+ });
168
+ ```
169
+
170
+ If you skip the `{ tools: aiSDKTools }` argument, prior tool results will be sent to the model as a plain JSON blob (the AI SDK default), and your `toModelOutput` will be silently ignored. Tools that do not declare `toModelOutput` are unaffected either way.
171
+
172
+ <Callout type="warn">
173
+ **Reserved property name.** When `toModelOutput` is set, the runtime wraps the AI SDK chat output as `{ __aui_modelContent: ToolModelContentPart[], value: <your result> }` before persisting. Do not return objects whose top-level key is literally `__aui_modelContent` from any tool's `execute`, or it will be misread as the envelope. The prefix is namespaced for this reason; any other property name is fine.
174
+ </Callout>
175
+
176
+ <Callout type="warn">
177
+ **Read/write compatibility for persisted threads.** The `__aui_modelContent` envelope is recognized by `@assistant-ui/react-ai-sdk` from this version onward. If you persist UI messages (thread history adapter, cloud, etc.) and read them from multiple environments, upgrade every reader before any writer starts producing `toModelOutput`. Older readers will treat the entire envelope as the `result`, which breaks tool `render` functions for those messages.
178
+ </Callout>
179
+
119
180
  ### Organizing Large Toolkits
120
181
 
121
182
  For larger applications, split tools across multiple files:
@@ -464,7 +525,7 @@ import { z } from "zod";
464
525
  export async function POST(req: Request) {
465
526
  const { messages } = await req.json();
466
527
  const result = streamText({
467
- model: openai("gpt-4o"),
528
+ model: openai("gpt-5.4-nano"),
468
529
  messages: await convertToModelMessages(messages),
469
530
  tools: {
470
531
  queryDatabase: tool({
@@ -519,7 +580,7 @@ export async function POST(req: Request) {
519
580
  const { messages, tools } = await req.json();
520
581
 
521
582
  const result = streamText({
522
- model: openai("gpt-4o"),
583
+ model: openai("gpt-5.4-nano"),
523
584
  messages: await convertToModelMessages(messages),
524
585
  tools: {
525
586
  ...frontendTools(tools), // Client-defined tools
@@ -558,7 +619,7 @@ export async function POST(req: Request) {
558
619
  const tools = await client.tools();
559
620
 
560
621
  const result = streamText({
561
- model: openai("gpt-4o"),
622
+ model: openai("gpt-5.4-nano"),
562
623
  tools,
563
624
  messages: await convertToModelMessages(messages),
564
625
  });
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Realtime Voice
3
- description: Bidirectional realtime voice conversations with AI agents.
2
+ title: Realtime Voice Chat
3
+ description: Build bidirectional voice conversations with AI in React — realtime audio streaming, interruption handling, and visual state, integrated via assistant-ui.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
@@ -1,10 +1,46 @@
1
1
  ---
2
2
  title: Adapters
3
- description: Title generation adapters for React Ink.
3
+ description: Title generation and storage adapters for React Ink.
4
4
  ---
5
5
 
6
6
  Adapters customize runtime behavior. They can be passed as options to `useLocalRuntime` or `useRemoteThreadListRuntime`.
7
7
 
8
+ ## createFileStorageAdapter
9
+
10
+ A `RemoteThreadListAdapter` that persists threads and messages to a local directory. See [Custom Backend → Option 2](/docs/ink/custom-backend#option-2-local-file-persistence) for usage.
11
+
12
+ ```ts
13
+ import { createFileStorageAdapter } from "@assistant-ui/react-ink";
14
+
15
+ const adapter = createFileStorageAdapter({
16
+ dir: "/path/to/threads",
17
+ });
18
+ ```
19
+
20
+ ## TitleGenerationAdapter
21
+
22
+ Produces a thread title from a thread's messages. Pass one as the `titleGenerator` option to `createFileStorageAdapter`, or call it from a custom `RemoteThreadListAdapter`.
23
+
24
+ ```ts
25
+ type TitleGenerationAdapter = {
26
+ generateTitle(messages: readonly ThreadMessage[]): Promise<string>;
27
+ };
28
+ ```
29
+
30
+ `createSimpleTitleAdapter` is the built-in implementation; it derives the title from the first user message, truncated to 50 characters.
31
+
32
+ ```ts
33
+ import {
34
+ createFileStorageAdapter,
35
+ createSimpleTitleAdapter,
36
+ } from "@assistant-ui/react-ink";
37
+
38
+ const adapter = createFileStorageAdapter({
39
+ dir: "/path/to/threads",
40
+ titleGenerator: createSimpleTitleAdapter(),
41
+ });
42
+ ```
43
+
8
44
  ## RemoteThreadListAdapter
9
45
 
10
46
  Title generation is configured via the `generateTitle` method on `RemoteThreadListAdapter`. See the [Custom Backend](/docs/ink/custom-backend) page for a full example.
@@ -59,7 +59,57 @@ This gives you:
59
59
  - In-memory thread list (lost on process exit)
60
60
  - Multi-thread support
61
61
 
62
- ## Option 2: Full backend thread management
62
+ ## Option 2: Local file persistence
63
+
64
+ When you want threads and messages to survive across sessions without running a backend, use `createFileStorageAdapter`. It writes each thread to a JSON file on disk and plugs into `useRemoteThreadListRuntime`.
65
+
66
+ ```tsx title="app.tsx"
67
+ import { join } from "node:path";
68
+ import { homedir } from "node:os";
69
+ import {
70
+ useLocalRuntime,
71
+ useRemoteThreadListRuntime,
72
+ createFileStorageAdapter,
73
+ AssistantRuntimeProvider,
74
+ } from "@assistant-ui/react-ink";
75
+ import { myChatAdapter } from "./adapters/my-chat-adapter.js";
76
+
77
+ const threadListAdapter = createFileStorageAdapter({
78
+ dir: join(homedir(), ".my-cli", "threads"),
79
+ });
80
+
81
+ function useAppRuntime() {
82
+ return useRemoteThreadListRuntime({
83
+ runtimeHook: () => useLocalRuntime(myChatAdapter),
84
+ adapter: threadListAdapter,
85
+ });
86
+ }
87
+
88
+ export function App() {
89
+ const runtime = useAppRuntime();
90
+ return (
91
+ <AssistantRuntimeProvider runtime={runtime}>
92
+ {/* your chat UI */}
93
+ </AssistantRuntimeProvider>
94
+ );
95
+ }
96
+ ```
97
+
98
+ Writes are atomic (temp file + `rename`), so a crash mid-write cannot leave a partial JSON file. The directory is created lazily on first write.
99
+
100
+ ### Options
101
+
102
+ | Option | Description |
103
+ |---|---|
104
+ | `dir` | Directory where thread files are stored. Created if missing. |
105
+ | `prefix` | Key prefix for stored files. Defaults to `@assistant-ui:`. Useful when two apps share a directory. |
106
+ | `titleGenerator` | Optional [`TitleGenerationAdapter`](/docs/ink/adapters#titlegenerationadapter) that auto-generates thread titles from the first messages. Pass `createSimpleTitleAdapter()` for the built-in implementation. |
107
+
108
+ ### When this fits
109
+
110
+ Designed for single-process terminal apps where one user has one CLI running at a time. The wrapped read-modify-write on the thread list isn't lock-safe, so two CLI processes pointed at the same directory can lose updates to thread metadata (rename, archive). If that's your scenario, use Option 3 instead.
111
+
112
+ ## Option 3: Full backend thread management
63
113
 
64
114
  When you want your backend to own thread state (e.g. for persistence across sessions, team sharing, or server-side history), implement a `RemoteThreadListAdapter`.
65
115
 
@@ -194,10 +244,11 @@ export function App() {
194
244
 
195
245
  ## Which option to choose?
196
246
 
197
- | | Option 1: ChatModelAdapter | Option 2: RemoteThreadListAdapter |
198
- |---|---|---|
199
- | **Thread storage** | In-memory (process lifetime) | Your backend |
200
- | **Message storage** | In-memory | On-device (can add history adapter for server-side) |
201
- | **Cross-session persistence** | No | Yes |
202
- | **Setup complexity** | Minimal | Moderate |
203
- | **Best for** | CLI tools, demos, prototypes | Production apps with persistence |
247
+ | | Option 1: ChatModelAdapter | Option 2: createFileStorageAdapter | Option 3: RemoteThreadListAdapter |
248
+ |---|---|---|---|
249
+ | **Thread storage** | In-memory (process lifetime) | Local disk | Your backend |
250
+ | **Message storage** | In-memory | Local disk | In-memory (can add history adapter for server-side) |
251
+ | **Cross-session persistence** | No | Yes | Yes |
252
+ | **Multi-process safe** | N/A | No | Depends on backend |
253
+ | **Setup complexity** | Minimal | Minimal | Moderate |
254
+ | **Best for** | Demos, prototypes | Local CLI tools | Production apps with sync / team sharing |
@@ -1,6 +1,6 @@
1
1
  ---
2
- title: Getting Started
3
- description: Build AI chat interfaces for the terminal with @assistant-ui/react-ink.
2
+ title: Terminal AI Chat with Ink
3
+ description: Build AI chat interfaces for the terminal in TypeScript with @assistant-ui/react-ink — streaming, tool calls, and keyboard navigation in CLI apps.
4
4
  ---
5
5
 
6
6
  ## Quick Start
@@ -129,6 +129,7 @@ import { Box, Text } from "ink";
129
129
  import {
130
130
  ThreadPrimitive,
131
131
  ComposerPrimitive,
132
+ LoadingPrimitive,
132
133
  useAuiState,
133
134
  } from "@assistant-ui/react-ink";
134
135
  import { MarkdownText } from "@assistant-ui/react-ink-markdown";
@@ -158,15 +159,13 @@ const Message = () => {
158
159
  );
159
160
  };
160
161
 
161
- const StatusIndicator = () => {
162
- const isRunning = useAuiState((s) => s.thread.isRunning);
163
- if (!isRunning) return null;
164
- return (
165
- <Box marginBottom={1}>
166
- <Text color="yellow">Thinking...</Text>
167
- </Box>
168
- );
169
- };
162
+ const StatusIndicator = () => (
163
+ <LoadingPrimitive.Root marginBottom={1} gap={1}>
164
+ <LoadingPrimitive.Spinner variant="bar" />
165
+ <LoadingPrimitive.Text />
166
+ <LoadingPrimitive.ElapsedTime />
167
+ </LoadingPrimitive.Root>
168
+ );
170
169
 
171
170
  export const Thread = () => {
172
171
  return (