@assistant-ui/mcp-docs-server 0.2.1 → 0.2.3

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 (187) hide show
  1. package/.docs/organized/code-examples/waterfall.md +3 -3
  2. package/.docs/organized/code-examples/with-a2a.md +5 -4
  3. package/.docs/organized/code-examples/with-ag-ui.md +7 -6
  4. package/.docs/organized/code-examples/with-ai-sdk-v7.md +14 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +12 -11
  6. package/.docs/organized/code-examples/with-assistant-transport.md +6 -5
  7. package/.docs/organized/code-examples/with-browser-extension.md +6 -6
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +16 -14
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +7 -7
  10. package/.docs/organized/code-examples/with-cloud.md +11 -10
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +11 -10
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +14 -13
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +15 -14
  14. package/.docs/organized/code-examples/with-eve.md +6 -5
  15. package/.docs/organized/code-examples/with-expo.md +213 -36
  16. package/.docs/organized/code-examples/with-external-store.md +6 -5
  17. package/.docs/organized/code-examples/with-ffmpeg.md +11 -10
  18. package/.docs/organized/code-examples/with-generative-ui.md +263 -29
  19. package/.docs/organized/code-examples/with-google-adk.md +5 -4
  20. package/.docs/organized/code-examples/with-heat-graph.md +3 -3
  21. package/.docs/organized/code-examples/with-image-generation.md +8 -7
  22. package/.docs/organized/code-examples/with-interactables.md +11 -10
  23. package/.docs/organized/code-examples/with-langchain.md +10 -9
  24. package/.docs/organized/code-examples/with-langgraph.md +7 -6
  25. package/.docs/organized/code-examples/with-livekit.md +15 -14
  26. package/.docs/organized/code-examples/with-mcp.md +14 -12
  27. package/.docs/organized/code-examples/with-nuxt.md +511 -575
  28. package/.docs/organized/code-examples/with-opencode.md +4 -4
  29. package/.docs/organized/code-examples/with-openui.md +450 -0
  30. package/.docs/organized/code-examples/with-pi.md +6 -5
  31. package/.docs/organized/code-examples/with-react-hook-form.md +16 -13
  32. package/.docs/organized/code-examples/with-react-ink-web.md +65 -15
  33. package/.docs/organized/code-examples/with-react-ink.md +5 -4
  34. package/.docs/organized/code-examples/with-react-router.md +8 -7
  35. package/.docs/organized/code-examples/with-resumable-stream.md +13 -12
  36. package/.docs/organized/code-examples/with-store.md +3 -3
  37. package/.docs/organized/code-examples/with-svelte.md +415 -0
  38. package/.docs/organized/code-examples/with-sveltekit.md +1061 -0
  39. package/.docs/organized/code-examples/with-tanstack.md +10 -9
  40. package/.docs/organized/code-examples/with-tap-runtime.md +5 -4
  41. package/.docs/organized/code-examples/with-virtualized-thread.md +6 -5
  42. package/.docs/organized/code-examples/with-vue.md +2 -2
  43. package/.docs/raw/docs/{(docs) → (getting-started)}/cli.mdx +6 -1
  44. package/.docs/raw/docs/{(docs) → (getting-started)}/devtools.mdx +1 -1
  45. package/.docs/raw/docs/{(docs) → (getting-started)}/index.mdx +4 -2
  46. package/.docs/raw/docs/{(docs) → (getting-started)}/installation.mdx +26 -26
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +6 -0
  48. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +1 -1
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +6 -1
  50. package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +5 -1
  51. package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +9 -2
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +2 -2
  53. package/.docs/raw/docs/(reference)/api-reference/integrations/{react-ai-sdk.mdx → ai-sdk.mdx} +43 -18
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +61 -2
  55. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +3 -3
  56. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +2 -2
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +20 -2
  58. package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +1 -1
  59. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +1 -1
  60. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +1 -1
  61. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +32 -1
  62. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +1 -1
  63. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +10 -10
  64. package/.docs/raw/docs/cloud/ai-sdk.mdx +4 -2
  65. package/.docs/raw/docs/cloud/index.mdx +1 -1
  66. package/.docs/raw/docs/copilots/assistant-frame.mdx +19 -8
  67. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  68. package/.docs/raw/docs/guides/branching.mdx +1 -1
  69. package/.docs/raw/docs/guides/chatgpt-subscription.mdx +1 -1
  70. package/.docs/raw/docs/guides/context-api.mdx +15 -17
  71. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  72. package/.docs/raw/docs/guides/electron.mdx +1 -1
  73. package/.docs/raw/docs/guides/latex.mdx +1 -1
  74. package/.docs/raw/docs/guides/mentions.mdx +2 -0
  75. package/.docs/raw/docs/guides/message-timing.mdx +11 -5
  76. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  77. package/.docs/raw/docs/guides/resumable-streams.mdx +3 -3
  78. package/.docs/raw/docs/guides/speech.mdx +1 -1
  79. package/.docs/raw/docs/guides/suggestions.mdx +8 -5
  80. package/.docs/raw/docs/guides/voice.mdx +1 -1
  81. package/.docs/raw/docs/ink/hooks.mdx +1 -1
  82. package/.docs/raw/docs/ink/index.mdx +3 -2
  83. package/.docs/raw/docs/ink/migration.mdx +1 -1
  84. package/.docs/raw/docs/ink/primitives.mdx +1 -1
  85. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +3 -3
  86. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +3 -3
  87. package/.docs/raw/docs/integrations/frameworks/{cloudflare-agents/overview.mdx → cloudflare-agents.mdx} +4 -3
  88. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +1 -1
  89. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  90. package/.docs/raw/docs/integrations/index.mdx +2 -2
  91. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +149 -131
  92. package/.docs/raw/docs/migrations/toolkit-tools.mdx +2 -2
  93. package/.docs/raw/docs/migrations/v0-15.mdx +34 -0
  94. package/.docs/raw/docs/primitives/action-bar.mdx +1 -1
  95. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -1
  96. package/.docs/raw/docs/primitives/attachment.mdx +1 -1
  97. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -1
  98. package/.docs/raw/docs/primitives/chain-of-thought.mdx +3 -3
  99. package/.docs/raw/docs/primitives/composer.mdx +1 -1
  100. package/.docs/raw/docs/primitives/error.mdx +1 -1
  101. package/.docs/raw/docs/primitives/message.mdx +1 -1
  102. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -1
  103. package/.docs/raw/docs/primitives/suggestion.mdx +4 -2
  104. package/.docs/raw/docs/primitives/thread-list.mdx +1 -1
  105. package/.docs/raw/docs/primitives/thread.mdx +2 -2
  106. package/.docs/raw/docs/react-native/adapters.mdx +1 -1
  107. package/.docs/raw/docs/react-native/index.mdx +2 -2
  108. package/.docs/raw/docs/react-native/migration.mdx +2 -2
  109. package/.docs/raw/docs/react-native/primitives.mdx +142 -5
  110. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +48 -6
  111. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +3 -3
  112. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +4 -4
  113. package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +31 -16
  114. package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +118 -0
  115. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +3 -3
  116. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +3 -3
  117. package/.docs/raw/docs/runtimes/concepts/stability.mdx +2 -1
  118. package/.docs/raw/docs/runtimes/concepts/threads.mdx +73 -33
  119. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +1 -1
  120. package/.docs/raw/docs/runtimes/custom/external-store.mdx +6 -2
  121. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  122. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +4 -0
  123. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  124. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +9 -2
  125. package/.docs/raw/docs/tools/backend.mdx +4 -4
  126. package/.docs/raw/docs/tools/defining-tools.mdx +21 -2
  127. package/.docs/raw/docs/tools/generative-ui-primitive.mdx +180 -0
  128. package/.docs/raw/docs/tools/generative-ui-slack.mdx +167 -0
  129. package/.docs/raw/docs/tools/generative-ui-teams.mdx +160 -0
  130. package/.docs/raw/docs/tools/generative-ui.mdx +224 -211
  131. package/.docs/raw/docs/tools/index.mdx +2 -1
  132. package/.docs/raw/docs/tools/interactables.mdx +8 -7
  133. package/.docs/raw/docs/tools/mcp-apps.mdx +18 -1
  134. package/.docs/raw/docs/tools/mcp.mdx +2 -2
  135. package/.docs/raw/docs/tools/openui.mdx +175 -0
  136. package/.docs/raw/docs/tools/tool-ui.mdx +18 -7
  137. package/.docs/raw/docs/tools/user-managed-mcp.mdx +7 -3
  138. package/.docs/raw/docs/ui/assistant-modal.mdx +3 -3
  139. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -1
  140. package/.docs/raw/docs/ui/attachment.mdx +50 -3
  141. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +36 -1
  142. package/.docs/raw/docs/ui/context-display.mdx +1 -1
  143. package/.docs/raw/docs/ui/directive-text.mdx +1 -1
  144. package/.docs/raw/docs/ui/file.mdx +2 -2
  145. package/.docs/raw/docs/ui/follow-up-suggestions.mdx +1 -1
  146. package/.docs/raw/docs/ui/image.mdx +2 -2
  147. package/.docs/raw/docs/ui/markdown.mdx +40 -1
  148. package/.docs/raw/docs/ui/mermaid.mdx +1 -1
  149. package/.docs/raw/docs/ui/message-timing.mdx +1 -1
  150. package/.docs/raw/docs/ui/model-selector.mdx +4 -4
  151. package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
  152. package/.docs/raw/docs/ui/quote.mdx +3 -3
  153. package/.docs/raw/docs/ui/reasoning.mdx +31 -3
  154. package/.docs/raw/docs/ui/scrollbar.mdx +1 -1
  155. package/.docs/raw/docs/ui/sources.mdx +10 -1
  156. package/.docs/raw/docs/ui/streamdown.mdx +2 -2
  157. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -1
  158. package/.docs/raw/docs/ui/thread-list.mdx +40 -1
  159. package/.docs/raw/docs/ui/thread.mdx +49 -2
  160. package/.docs/raw/docs/ui/tool-fallback.mdx +23 -9
  161. package/.docs/raw/docs/ui/tool-group.mdx +1 -1
  162. package/.docs/raw/docs/ui/voice.mdx +1 -1
  163. package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
  164. package/dist/xulux/catalog-client.d.ts.map +1 -1
  165. package/dist/xulux/catalog-client.js +51 -6
  166. package/dist/xulux/catalog-client.js.map +1 -1
  167. package/dist/xulux/types.d.ts +7 -7
  168. package/dist/xulux/types.d.ts.map +1 -1
  169. package/dist/xulux/types.js.map +1 -1
  170. package/package.json +5 -5
  171. package/src/tools/tests/docs.test.ts +10 -7
  172. package/src/tools/tests/path-traversal.test.ts +5 -2
  173. package/src/tools/tests/xulux-templates.test.ts +63 -0
  174. package/src/xulux/catalog-client.ts +68 -23
  175. package/src/xulux/types.ts +17 -13
  176. package/.docs/raw/docs/tools/interactables-legacy.mdx +0 -423
  177. package/.docs/raw/docs/ui/accordion.mdx +0 -266
  178. package/.docs/raw/docs/ui/badge.mdx +0 -150
  179. package/.docs/raw/docs/ui/diff-viewer.mdx +0 -280
  180. package/.docs/raw/docs/ui/dot-matrix.mdx +0 -133
  181. package/.docs/raw/docs/ui/number-roll.mdx +0 -154
  182. package/.docs/raw/docs/ui/select.mdx +0 -254
  183. package/.docs/raw/docs/ui/tabs.mdx +0 -271
  184. /package/.docs/raw/docs/{(docs) → (getting-started)}/architecture.mdx +0 -0
  185. /package/.docs/raw/docs/{(docs) → (getting-started)}/base-ui.mdx +0 -0
  186. /package/.docs/raw/docs/{(docs) → (getting-started)}/llm.mdx +0 -0
  187. /package/.docs/raw/docs/{(docs) → (getting-started)}/rtl.mdx +0 -0
@@ -17,7 +17,7 @@ export async function POST(req: Request) {
17
17
  const { messages }: { messages: UIMessage[] } = await req.json();
18
18
 
19
19
  const result = streamText({
20
- model: openai("gpt-5.4-nano"),
20
+ model: openai("gpt-5.6-luna"),
21
21
  messages: await convertToModelMessages(messages),
22
22
  stopWhen: stepCountIs(10),
23
23
  });
@@ -127,7 +127,7 @@ export default function RootLayout({
127
127
  "use client";
128
128
 
129
129
  import { AssistantRuntimeProvider } from "@assistant-ui/react";
130
- import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
130
+ import { useChatRuntime } from "@assistant-ui/ai-sdk";
131
131
  import { ElevenLabsVoiceAdapter } from "@/lib/elevenlabs-voice-adapter";
132
132
  import { VoiceThread } from "./voice-thread";
133
133
 
@@ -423,7 +423,7 @@ export class ElevenLabsVoiceAdapter implements RealtimeVoiceAdapter {
423
423
  import { withAui } from "@assistant-ui/next";
424
424
  /** @type {import('next').NextConfig} */
425
425
  const nextConfig = {
426
- transpilePackages: ["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
426
+ transpilePackages: ["@assistant-ui/react", "@assistant-ui/ai-sdk"],
427
427
  };
428
428
 
429
429
  export default withAui(nextConfig);
@@ -439,20 +439,20 @@ export default withAui(nextConfig);
439
439
  "version": "0.0.0",
440
440
  "type": "module",
441
441
  "dependencies": {
442
- "@ai-sdk/openai": "^4.0.34",
443
- "@ai-sdk/react": "^4.0.59",
442
+ "@ai-sdk/openai": "^4.0.46",
443
+ "@ai-sdk/react": "^4.0.80",
444
+ "@assistant-ui/ai-sdk": "workspace:*",
444
445
  "@assistant-ui/react": "workspace:^",
445
- "@assistant-ui/react-ai-sdk": "workspace:*",
446
446
  "@assistant-ui/react-markdown": "workspace:^",
447
447
  "@assistant-ui/ui": "workspace:*",
448
- "@elevenlabs/client": "^1.17.0",
448
+ "@elevenlabs/client": "^1.21.0",
449
449
  "@tailwindcss/postcss": "^4.3.3",
450
- "ai": "^7.0.56",
450
+ "ai": "^7.0.77",
451
451
  "class-variance-authority": "^0.7.1",
452
452
  "clsx": "^2.1.1",
453
- "lucide-react": "^1.29.0",
454
- "motion": "^13.0.0",
455
- "next": "^16.3.0",
453
+ "lucide-react": "^1.33.0",
454
+ "motion": "^13.1.1",
455
+ "next": "^16.3.2",
456
456
  "postcss": "^8.5.26",
457
457
  "react": "^19.2.8",
458
458
  "react-dom": "^19.2.8",
@@ -463,9 +463,9 @@ export default withAui(nextConfig);
463
463
  "devDependencies": {
464
464
  "@assistant-ui/next": "workspace:*",
465
465
  "@assistant-ui/x-buildutils": "workspace:*",
466
- "@types/node": "^26.1.2",
466
+ "@types/node": "^26.2.0",
467
467
  "@types/react": "^19.2.18",
468
- "@types/react-dom": "^19.2.4",
468
+ "@types/react-dom": "^19.2.5",
469
469
  "tw-animate-css": "^1.4.0",
470
470
  "typescript": "^7.0.2"
471
471
  },
@@ -500,6 +500,7 @@ export default withAui(nextConfig);
500
500
  "@/components/assistant-ui/*": [
501
501
  "../../packages/ui/src/components/assistant-ui/*"
502
502
  ],
503
+ "@/hooks/*": ["../../packages/ui/src/hooks/*"],
503
504
  "@/components/ui/*": [
504
505
  "../../packages/ui/src/components/ui/base/*",
505
506
  "../../packages/ui/src/components/ui/radix/*"
@@ -21,7 +21,7 @@ export async function POST(req: Request) {
21
21
  const { messages }: { messages: UIMessage[] } = await req.json();
22
22
 
23
23
  const result = streamText({
24
- model: openai("gpt-5.4-nano"),
24
+ model: openai("gpt-5.6-luna"),
25
25
  messages: await convertToModelMessages(messages),
26
26
  stopWhen: stepCountIs(10),
27
27
  tools: {
@@ -240,7 +240,7 @@ import {
240
240
  AuiConfig,
241
241
  Suggestions,
242
242
  } from "@assistant-ui/react";
243
- import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
243
+ import { useChatRuntime } from "@assistant-ui/ai-sdk";
244
244
  import { ElevenLabsScribeAdapter } from "@/lib/elevenlabs-scribe-adapter";
245
245
 
246
246
  function ThreadWithSuggestions() {
@@ -548,7 +548,7 @@ export class ElevenLabsScribeAdapter implements DictationAdapter {
548
548
  import { withAui } from "@assistant-ui/next";
549
549
  /** @type {import('next').NextConfig} */
550
550
  const nextConfig = {
551
- transpilePackages: ["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
551
+ transpilePackages: ["@assistant-ui/react", "@assistant-ui/ai-sdk"],
552
552
  };
553
553
 
554
554
  export default withAui(nextConfig);
@@ -564,20 +564,20 @@ export default withAui(nextConfig);
564
564
  "version": "0.0.0",
565
565
  "type": "module",
566
566
  "dependencies": {
567
- "@ai-sdk/openai": "^4.0.34",
568
- "@ai-sdk/react": "^4.0.59",
567
+ "@ai-sdk/openai": "^4.0.46",
568
+ "@ai-sdk/react": "^4.0.80",
569
+ "@assistant-ui/ai-sdk": "workspace:*",
569
570
  "@assistant-ui/react": "workspace:^",
570
- "@assistant-ui/react-ai-sdk": "workspace:*",
571
571
  "@assistant-ui/react-markdown": "workspace:^",
572
572
  "@assistant-ui/ui": "workspace:*",
573
- "@elevenlabs/client": "^1.17.0",
573
+ "@elevenlabs/client": "^1.21.0",
574
574
  "@tailwindcss/postcss": "^4.3.3",
575
- "ai": "^7.0.56",
575
+ "ai": "^7.0.77",
576
576
  "class-variance-authority": "^0.7.1",
577
577
  "clsx": "^2.1.1",
578
- "lucide-react": "^1.29.0",
579
- "motion": "^13.0.0",
580
- "next": "^16.3.0",
578
+ "lucide-react": "^1.33.0",
579
+ "motion": "^13.1.1",
580
+ "next": "^16.3.2",
581
581
  "postcss": "^8.5.26",
582
582
  "react": "^19.2.8",
583
583
  "react-dom": "^19.2.8",
@@ -588,9 +588,9 @@ export default withAui(nextConfig);
588
588
  "devDependencies": {
589
589
  "@assistant-ui/next": "workspace:*",
590
590
  "@assistant-ui/x-buildutils": "workspace:*",
591
- "@types/node": "^26.1.2",
591
+ "@types/node": "^26.2.0",
592
592
  "@types/react": "^19.2.18",
593
- "@types/react-dom": "^19.2.4",
593
+ "@types/react-dom": "^19.2.5",
594
594
  "tw-animate-css": "^1.4.0",
595
595
  "typescript": "^7.0.2"
596
596
  },
@@ -644,7 +644,7 @@ npm run dev
644
644
  ## Related Documentation
645
645
 
646
646
  - [assistant-ui Documentation](https://www.assistant-ui.com/docs)
647
- - [ElevenLabs Scribe](https://elevenlabs.io/docs/api-reference/scribe)
647
+ - [ElevenLabs Scribe](https://elevenlabs.io/docs/overview/capabilities/speech-to-text)
648
648
 
649
649
  ```
650
650
 
@@ -670,6 +670,7 @@ npm run dev
670
670
  "@/components/assistant-ui/*": [
671
671
  "../../packages/ui/src/components/assistant-ui/*"
672
672
  ],
673
+ "@/hooks/*": ["../../packages/ui/src/hooks/*"],
673
674
  "@/components/ui/*": [
674
675
  "../../packages/ui/src/components/ui/base/*",
675
676
  "../../packages/ui/src/components/ui/radix/*"
@@ -336,9 +336,9 @@ export default withEve(withAui(nextConfig));
336
336
  "@assistant-ui/ui": "workspace:*",
337
337
  "class-variance-authority": "^0.7.1",
338
338
  "clsx": "^2.1.1",
339
- "eve": "^0.27.6",
340
- "lucide-react": "^1.29.0",
341
- "next": "^16.3.0",
339
+ "eve": "^0.44.4",
340
+ "lucide-react": "^1.33.0",
341
+ "next": "^16.3.2",
342
342
  "react": "^19.2.8",
343
343
  "react-dom": "^19.2.8",
344
344
  "tailwind-merge": "^3.6.0"
@@ -347,9 +347,9 @@ export default withEve(withAui(nextConfig));
347
347
  "@assistant-ui/next": "workspace:*",
348
348
  "@assistant-ui/x-buildutils": "workspace:*",
349
349
  "@tailwindcss/postcss": "^4.3.3",
350
- "@types/node": "^26.1.2",
350
+ "@types/node": "^26.2.0",
351
351
  "@types/react": "^19.2.18",
352
- "@types/react-dom": "^19.2.4",
352
+ "@types/react-dom": "^19.2.5",
353
353
  "postcss": "^8.5.26",
354
354
  "tailwindcss": "^4.3.3",
355
355
  "tw-animate-css": "^1.4.0",
@@ -385,6 +385,7 @@ The Eve channel is served on the same origin as the Next app, so the browser UI
385
385
  "@/components/assistant-ui/*": [
386
386
  "../../packages/ui/src/components/assistant-ui/*"
387
387
  ],
388
+ "@/hooks/*": ["../../packages/ui/src/hooks/*"],
388
389
  "@/components/ui/*": [
389
390
  "../../packages/ui/src/components/ui/base/*",
390
391
  "../../packages/ui/src/components/ui/radix/*"
@@ -115,6 +115,7 @@ function NewChatButton() {
115
115
  return (
116
116
  <Pressable
117
117
  accessibilityLabel="New chat"
118
+ accessibilityRole="button"
118
119
  hitSlop={8}
119
120
  onPress={() => {
120
121
  haptics.selection();
@@ -191,7 +192,7 @@ export default function RootLayout() {
191
192
  ## app/api/chat+api.ts
192
193
 
193
194
  ```typescript
194
- import { frontendTools } from "@assistant-ui/react-ai-sdk";
195
+ import { frontendTools } from "@assistant-ui/ai-sdk";
195
196
  import { openai } from "@ai-sdk/openai";
196
197
  import {
197
198
  convertToModelMessages,
@@ -204,7 +205,7 @@ export async function POST(req: Request) {
204
205
  const body = await req.json();
205
206
  const { messages, tools } = body;
206
207
 
207
- const model = openai("gpt-5.4-nano");
208
+ const model = openai("gpt-5.6-luna");
208
209
 
209
210
  const prunedMessages = pruneMessages({
210
211
  messages: await convertToModelMessages(messages),
@@ -375,6 +376,7 @@ function AttachButton() {
375
376
  return (
376
377
  <Pressable
377
378
  accessibilityLabel="Add image"
379
+ accessibilityRole="button"
378
380
  onPress={pickImage}
379
381
  hitSlop={6}
380
382
  style={({ pressed }) => [
@@ -636,6 +638,7 @@ import { useEffect, useRef } from "react";
636
638
  import { View, Text, Animated, Platform, StyleSheet } from "react-native";
637
639
  import { Image } from "expo-image";
638
640
  import {
641
+ AuiIf,
639
642
  useAuiState,
640
643
  MessagePrimitive,
641
644
  ErrorPrimitive,
@@ -764,12 +767,19 @@ function AssistantMessage() {
764
767
  />
765
768
  </ErrorPrimitive.Root>
766
769
  </View>
767
- <MessagePrimitive.If running={false}>
770
+ <AuiIf
771
+ condition={(s) =>
772
+ !(
773
+ s.message.role === "assistant" &&
774
+ s.message.status.type === "running"
775
+ )
776
+ }
777
+ >
768
778
  <View style={styles.actionsRow}>
769
779
  <MessageBranchPicker align="flex-start" />
770
780
  <MessageActionBar />
771
781
  </View>
772
- </MessagePrimitive.If>
782
+ </AuiIf>
773
783
  </MessagePrimitive.Root>
774
784
  );
775
785
  }
@@ -864,7 +874,7 @@ import {
864
874
  import { useSafeAreaInsets } from "react-native-safe-area-context";
865
875
  import { MessageBubble } from "./message";
866
876
  import { Composer } from "./composer";
867
- import { ThreadPrimitive } from "@assistant-ui/react-native";
877
+ import { AuiIf, ThreadPrimitive } from "@assistant-ui/react-native";
868
878
  import { useTheme } from "@/hooks/use-theme";
869
879
  import { Radius, Spacing } from "@/constants/theme";
870
880
  import { haptics } from "@/lib/haptics";
@@ -916,10 +926,10 @@ function EmptyState() {
916
926
  function ChatMessages() {
917
927
  return (
918
928
  <>
919
- <ThreadPrimitive.Empty>
929
+ <AuiIf condition={(s) => s.thread.isEmpty}>
920
930
  <EmptyState />
921
- </ThreadPrimitive.Empty>
922
- <ThreadPrimitive.If empty={false}>
931
+ </AuiIf>
932
+ <AuiIf condition={(s) => !s.thread.isEmpty}>
923
933
  <ThreadPrimitive.MessagesFlatList
924
934
  style={styles.flex}
925
935
  contentContainerStyle={styles.messageList}
@@ -927,7 +937,7 @@ function ChatMessages() {
927
937
  >
928
938
  {() => <MessageBubble />}
929
939
  </ThreadPrimitive.MessagesFlatList>
930
- </ThreadPrimitive.If>
940
+ </AuiIf>
931
941
  </>
932
942
  );
933
943
  }
@@ -1425,8 +1435,8 @@ import { View, Text, Pressable, StyleSheet } from "react-native";
1425
1435
  import { useSafeAreaInsets } from "react-native-safe-area-context";
1426
1436
  import {
1427
1437
  ThreadListPrimitive,
1428
- ThreadListItemByIndexProvider,
1429
1438
  useAui,
1439
+ useAuiState,
1430
1440
  } from "@assistant-ui/react-native";
1431
1441
  import type { DrawerContentComponentProps } from "expo-router/build/react-navigation/drawer/types";
1432
1442
  import { ThreadListItem } from "./ThreadListItem";
@@ -1438,6 +1448,9 @@ import { haptics } from "@/lib/haptics";
1438
1448
  export function ThreadListDrawer({ navigation }: DrawerContentComponentProps) {
1439
1449
  const { colors } = useTheme();
1440
1450
  const aui = useAui();
1451
+ const isNewThreadActive = useAuiState(
1452
+ (s) => s.threads.newThreadId === s.threads.mainThreadId,
1453
+ );
1441
1454
  const insets = useSafeAreaInsets();
1442
1455
 
1443
1456
  return (
@@ -1449,6 +1462,8 @@ export function ThreadListDrawer({ navigation }: DrawerContentComponentProps) {
1449
1462
  >
1450
1463
  <ThreadListPrimitive.Root style={styles.root}>
1451
1464
  <Pressable
1465
+ accessibilityRole="button"
1466
+ accessibilityState={{ selected: isNewThreadActive }}
1452
1467
  onPressIn={haptics.selection}
1453
1468
  onPress={() => {
1454
1469
  aui.threads.switchToNewThread();
@@ -1470,10 +1485,8 @@ export function ThreadListDrawer({ navigation }: DrawerContentComponentProps) {
1470
1485
  </Text>
1471
1486
 
1472
1487
  <ThreadListPrimitive.Items
1473
- renderItem={({ index }) => (
1474
- <ThreadListItemByIndexProvider index={index} archived={false}>
1475
- <ThreadListItem onSelect={() => navigation.closeDrawer()} />
1476
- </ThreadListItemByIndexProvider>
1488
+ renderItem={() => (
1489
+ <ThreadListItem onSelect={() => navigation.closeDrawer()} />
1477
1490
  )}
1478
1491
  style={styles.list}
1479
1492
  contentContainerStyle={styles.listContent}
@@ -1546,6 +1559,8 @@ export function ThreadListItem({ onSelect }: { onSelect: () => void }) {
1546
1559
  return (
1547
1560
  <ThreadListItemPrimitive.Root>
1548
1561
  <Pressable
1562
+ accessibilityRole="button"
1563
+ accessibilityState={{ selected: isActive }}
1549
1564
  onPressIn={haptics.selection}
1550
1565
  onPress={() => {
1551
1566
  aui.threadListItem.switchTo();
@@ -1777,21 +1792,181 @@ export const Spacing = {
1777
1792
 
1778
1793
  ```
1779
1794
 
1795
+ ## hooks/anonymous-session-fetch.test.ts
1796
+
1797
+ ```typescript
1798
+ import { describe, expect, it, vi } from "vitest";
1799
+ import {
1800
+ createAnonymousSessionFetch,
1801
+ shouldUseAnonymousSessionFetch,
1802
+ } from "./anonymous-session-fetch";
1803
+
1804
+ describe("Expo anonymous session fetch", () => {
1805
+ it("only bootstraps the protected browser flow on web", () => {
1806
+ expect(
1807
+ shouldUseAnonymousSessionFetch(
1808
+ "https://www.assistant-ui.com/api/chat",
1809
+ "web",
1810
+ ),
1811
+ ).toBe(true);
1812
+ expect(
1813
+ shouldUseAnonymousSessionFetch(
1814
+ "https://www.assistant-ui.com/api/chat",
1815
+ "ios",
1816
+ ),
1817
+ ).toBe(false);
1818
+ expect(shouldUseAnonymousSessionFetch("/api/chat", "web")).toBe(false);
1819
+ });
1820
+
1821
+ it("retries bootstrap on the next request after issuance fails", async () => {
1822
+ const fetchMock = vi
1823
+ .fn<typeof fetch>()
1824
+ .mockRejectedValueOnce(new Error("temporary network failure"))
1825
+ .mockResolvedValueOnce(new Response(null, { status: 403 }))
1826
+ .mockResolvedValueOnce(Response.json({ token: "signed-session" }))
1827
+ .mockResolvedValueOnce(new Response("ok"));
1828
+ const sessionFetch = createAnonymousSessionFetch(
1829
+ "https://www.assistant-ui.com/api/chat",
1830
+ fetchMock,
1831
+ );
1832
+
1833
+ const failedResponse = await sessionFetch(
1834
+ "https://www.assistant-ui.com/api/chat",
1835
+ { method: "POST" },
1836
+ );
1837
+ const recoveredResponse = await sessionFetch(
1838
+ "https://www.assistant-ui.com/api/chat",
1839
+ { method: "POST" },
1840
+ );
1841
+
1842
+ expect(failedResponse.status).toBe(403);
1843
+ expect(recoveredResponse.status).toBe(200);
1844
+ expect(fetchMock).toHaveBeenCalledTimes(4);
1845
+ expect(
1846
+ new Headers(fetchMock.mock.calls[1]?.[1]?.headers).get(
1847
+ "x-assistant-ui-anonymous-session",
1848
+ ),
1849
+ ).toBeNull();
1850
+ expect(
1851
+ new Headers(fetchMock.mock.calls[3]?.[1]?.headers).get(
1852
+ "x-assistant-ui-anonymous-session",
1853
+ ),
1854
+ ).toBe("signed-session");
1855
+ });
1856
+
1857
+ it("accepts a same-origin 204 cookie bootstrap", async () => {
1858
+ const fetchMock = vi
1859
+ .fn<typeof fetch>()
1860
+ .mockResolvedValueOnce(new Response(null, { status: 204 }))
1861
+ .mockResolvedValueOnce(new Response("ok"));
1862
+ const sessionFetch = createAnonymousSessionFetch(
1863
+ "https://example.com/api/chat",
1864
+ fetchMock,
1865
+ );
1866
+
1867
+ const response = await sessionFetch("https://example.com/api/chat", {
1868
+ method: "POST",
1869
+ });
1870
+
1871
+ expect(response.status).toBe(200);
1872
+ expect(fetchMock.mock.calls[0]?.[1]?.credentials).toBe("same-origin");
1873
+ expect(
1874
+ new Headers(fetchMock.mock.calls[1]?.[1]?.headers).get(
1875
+ "x-assistant-ui-anonymous-session",
1876
+ ),
1877
+ ).toBeNull();
1878
+ });
1879
+ });
1880
+
1881
+ ```
1882
+
1883
+ ## hooks/anonymous-session-fetch.ts
1884
+
1885
+ ```typescript
1886
+ // Mirrored inline in examples/with-react-ink-web/app/ink-app.tsx; keep in sync.
1887
+ const ANONYMOUS_SESSION_HEADER = "x-assistant-ui-anonymous-session";
1888
+
1889
+ export function shouldUseAnonymousSessionFetch(
1890
+ chatApi: string,
1891
+ platform: string,
1892
+ ): boolean {
1893
+ return platform === "web" && chatApi.startsWith("http");
1894
+ }
1895
+
1896
+ export function createAnonymousSessionFetch(
1897
+ chatApi: string,
1898
+ fetchImplementation: typeof fetch = fetch,
1899
+ ): typeof fetch {
1900
+ let tokenPromise: Promise<string | null> | null = null;
1901
+
1902
+ const getToken = () => {
1903
+ tokenPromise ??= (async () => {
1904
+ const endpoint = new URL("/api/anonymous-session", chatApi);
1905
+ const response = await fetchImplementation(endpoint, {
1906
+ credentials: "same-origin",
1907
+ });
1908
+ if (!response.ok) {
1909
+ throw new Error("Unable to start an anonymous session");
1910
+ }
1911
+ if (response.status === 204) return null;
1912
+ const payload = (await response.json()) as { token?: unknown };
1913
+ if (typeof payload.token !== "string" || !payload.token) {
1914
+ throw new Error("Anonymous session token is missing");
1915
+ }
1916
+ return payload.token;
1917
+ })().catch(() => {
1918
+ tokenPromise = null;
1919
+ return null;
1920
+ });
1921
+ return tokenPromise;
1922
+ };
1923
+
1924
+ return async (input, init) => {
1925
+ const requestTemplate =
1926
+ input instanceof Request ? new Request(input, init) : null;
1927
+
1928
+ const send = async () => {
1929
+ const headers = new Headers(requestTemplate?.headers ?? init?.headers);
1930
+ const token = await getToken();
1931
+ if (token) headers.set(ANONYMOUS_SESSION_HEADER, token);
1932
+ if (requestTemplate) {
1933
+ return fetchImplementation(requestTemplate.clone(), { headers });
1934
+ }
1935
+ return fetchImplementation(input, { ...init, headers });
1936
+ };
1937
+
1938
+ const response = await send();
1939
+ if (response.status !== 401) return response;
1940
+ tokenPromise = null;
1941
+ return send();
1942
+ };
1943
+ }
1944
+
1945
+ ```
1946
+
1780
1947
  ## hooks/use-app-runtime.ts
1781
1948
 
1782
1949
  ```typescript
1783
1950
  import { useMemo } from "react";
1784
- import {
1785
- useChatRuntime,
1786
- AssistantChatTransport,
1787
- } from "@assistant-ui/react-ai-sdk";
1951
+ import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";
1788
1952
  import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
1953
+ import { Platform } from "react-native";
1954
+ import {
1955
+ createAnonymousSessionFetch,
1956
+ shouldUseAnonymousSessionFetch,
1957
+ } from "./anonymous-session-fetch";
1789
1958
 
1790
1959
  const CHAT_API = process.env.EXPO_PUBLIC_CHAT_ENDPOINT_URL ?? "/api/chat";
1791
1960
 
1792
1961
  export function useAppRuntime() {
1793
1962
  const transport = useMemo(
1794
- () => new AssistantChatTransport({ api: CHAT_API }),
1963
+ () =>
1964
+ new AssistantChatTransport({
1965
+ api: CHAT_API,
1966
+ ...(shouldUseAnonymousSessionFetch(CHAT_API, Platform.OS)
1967
+ ? { fetch: createAnonymousSessionFetch(CHAT_API) }
1968
+ : {}),
1969
+ }),
1795
1970
  [],
1796
1971
  );
1797
1972
  return useChatRuntime({
@@ -1933,28 +2108,29 @@ module.exports = withAui(config);
1933
2108
  "android": "expo run:android",
1934
2109
  "ios": "expo run:ios",
1935
2110
  "web": "expo start --web",
1936
- "export:web": "expo export --platform web && node scripts/flatten-assets.mjs"
2111
+ "export:web": "expo export --platform web && node scripts/flatten-assets.mjs",
2112
+ "test": "vitest run"
1937
2113
  },
1938
2114
  "dependencies": {
1939
- "@ai-sdk/openai": "^4.0.34",
1940
- "@ai-sdk/react": "^4.0.59",
1941
- "@assistant-ui/react-ai-sdk": "workspace:*",
2115
+ "@ai-sdk/openai": "^4.0.42",
2116
+ "@ai-sdk/react": "^4.0.69",
2117
+ "@assistant-ui/ai-sdk": "workspace:*",
1942
2118
  "@assistant-ui/react-native": "workspace:*",
1943
2119
  "@expo/vector-icons": "^15.1.1",
1944
2120
  "@react-navigation/drawer": "7.9.4",
1945
2121
  "@react-navigation/native": "7.1.33",
1946
- "ai": "^7.0.56",
1947
- "expo": "~57.0.11",
2122
+ "ai": "^7.0.66",
2123
+ "expo": "~57.0.16",
1948
2124
  "expo-clipboard": "~57.0.1",
1949
- "expo-constants": "~57.0.9",
2125
+ "expo-constants": "~57.0.14",
1950
2126
  "expo-font": "~57.0.1",
1951
2127
  "expo-haptics": "~57.0.1",
1952
- "expo-image": "~57.0.2",
1953
- "expo-image-picker": "~57.0.8",
1954
- "expo-linking": "~57.0.5",
1955
- "expo-router": "~57.0.11",
1956
- "expo-server": "~57.0.1",
1957
- "expo-splash-screen": "~57.0.5",
2128
+ "expo-image": "~57.0.3",
2129
+ "expo-image-picker": "~57.0.13",
2130
+ "expo-linking": "~57.0.6",
2131
+ "expo-router": "~57.0.16",
2132
+ "expo-server": "~57.0.3",
2133
+ "expo-splash-screen": "~57.0.8",
1958
2134
  "expo-status-bar": "~57.0.1",
1959
2135
  "expo-symbols": "^57.0.2",
1960
2136
  "expo-system-ui": "~57.0.2",
@@ -1974,7 +2150,8 @@ module.exports = withAui(config);
1974
2150
  "@babel/core": "^7.29.7",
1975
2151
  "@types/react": "~19.2.18",
1976
2152
  "typescript": "npm:@typescript/typescript6@^6.0.2",
1977
- "typescript-7": "npm:typescript@~7.0.2"
2153
+ "typescript-7": "npm:typescript@~7.0.2",
2154
+ "vitest": "^4.1.10"
1978
2155
  },
1979
2156
  "private": true
1980
2157
  }
@@ -1988,7 +2165,7 @@ module.exports = withAui(config);
1988
2165
 
1989
2166
  A native chat app built with [assistant-ui](https://www.assistant-ui.com) and [Expo](https://expo.dev). It runs on iOS, Android, and the web from a single codebase, and is styled to match the assistant-ui web kit: a clean, neutral, ChatGPT-grade look with subtle hairline borders.
1990
2167
 
1991
- The chat is powered by `@assistant-ui/react-native` with the AI SDK runtime (`@assistant-ui/react-ai-sdk`). The example leans on native Expo APIs throughout:
2168
+ The chat is powered by `@assistant-ui/react-native` with the AI SDK runtime (`@assistant-ui/ai-sdk`). The example leans on native Expo APIs throughout:
1992
2169
 
1993
2170
  - **SF Symbols** (`expo-symbols`) for native iconography on iOS, with a Material Icons fallback on Android and the web.
1994
2171
  - **Haptics** (`expo-haptics`) for tactile feedback on send, stop, and selection.
@@ -2012,7 +2189,7 @@ It follows the assistant-ui component conventions: `MessagePrimitive.Parts` for
2012
2189
  cp .env.example .env
2013
2190
  ```
2014
2191
 
2015
- The bundled API route (`app/api/chat+api.ts`) needs `OPENAI_API_KEY`. To point the app at a separately hosted backend instead, set `EXPO_PUBLIC_CHAT_ENDPOINT_URL`.
2192
+ The bundled API route (`app/api/chat+api.ts`) needs `OPENAI_API_KEY`. To point the app at a separately hosted backend instead, set `EXPO_PUBLIC_CHAT_ENDPOINT_URL`. Browser deployments use `/api/anonymous-session` when the hosted backend supports it and otherwise send the request normally. Native deployments should use a backend intended for their app.
2016
2193
 
2017
2194
  3. Start the app:
2018
2195
 
@@ -2060,7 +2237,7 @@ It follows the assistant-ui component conventions: `MessagePrimitive.Parts` for
2060
2237
  {
2061
2238
  "$schema": "https://openapi.vercel.sh/vercel.json",
2062
2239
  "ignoreCommand": "bash ../../scripts/vercel-ignore-changeset-release.sh",
2063
- "buildCommand": "cd ../.. && pnpm turbo build --filter=@assistant-ui/react-native --filter=@assistant-ui/react-ai-sdk --filter=@assistant-ui/metro && cd examples/with-expo && pnpm run export:web",
2240
+ "buildCommand": "cd ../.. && pnpm turbo build --filter=@assistant-ui/react-native --filter=@assistant-ui/ai-sdk --filter=@assistant-ui/metro && cd examples/with-expo && pnpm run export:web",
2064
2241
  "outputDirectory": "dist",
2065
2242
  "framework": null
2066
2243
  }
@@ -324,8 +324,8 @@ export default withAui(nextConfig);
324
324
  "@assistant-ui/ui": "workspace:*",
325
325
  "class-variance-authority": "^0.7.1",
326
326
  "clsx": "^2.1.1",
327
- "lucide-react": "^1.29.0",
328
- "next": "^16.3.0",
327
+ "lucide-react": "^1.33.0",
328
+ "next": "^16.3.2",
329
329
  "react": "^19.2.8",
330
330
  "react-dom": "^19.2.8",
331
331
  "tailwind-merge": "^3.6.0"
@@ -334,9 +334,9 @@ export default withAui(nextConfig);
334
334
  "@assistant-ui/next": "workspace:*",
335
335
  "@assistant-ui/x-buildutils": "workspace:*",
336
336
  "@tailwindcss/postcss": "^4.3.3",
337
- "@types/node": "^26.1.2",
337
+ "@types/node": "^26.2.0",
338
338
  "@types/react": "^19.2.18",
339
- "@types/react-dom": "^19.2.4",
339
+ "@types/react-dom": "^19.2.5",
340
340
  "postcss": "^8.5.26",
341
341
  "tailwindcss": "^4.3.3",
342
342
  "tw-animate-css": "^1.4.0",
@@ -386,7 +386,7 @@ npm run dev
386
386
  ## Related Documentation
387
387
 
388
388
  - [assistant-ui Documentation](https://www.assistant-ui.com/docs)
389
- - [External Store Runtime Guide](https://www.assistant-ui.com/docs/runtimes/external-store)
389
+ - [External Store Runtime Guide](https://www.assistant-ui.com/docs/runtimes/custom/external-store)
390
390
 
391
391
  ```
392
392
 
@@ -401,6 +401,7 @@ npm run dev
401
401
  "@/components/assistant-ui/*": [
402
402
  "../../packages/ui/src/components/assistant-ui/*"
403
403
  ],
404
+ "@/hooks/*": ["../../packages/ui/src/hooks/*"],
404
405
  "@/components/ui/*": [
405
406
  "../../packages/ui/src/components/ui/base/*",
406
407
  "../../packages/ui/src/components/ui/radix/*"