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

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 (155) hide show
  1. package/.docs/organized/code-examples/waterfall.md +12 -13
  2. package/.docs/organized/code-examples/with-a2a.md +16 -11
  3. package/.docs/organized/code-examples/with-ag-ui.md +15 -13
  4. package/.docs/organized/code-examples/with-ai-sdk-v7.md +14 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +14 -13
  6. package/.docs/organized/code-examples/with-assistant-transport.md +20 -28
  7. package/.docs/organized/code-examples/with-browser-extension.md +18 -11
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +17 -15
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +10 -11
  10. package/.docs/organized/code-examples/with-cloud.md +19 -14
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +15 -14
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +14 -14
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +19 -17
  14. package/.docs/organized/code-examples/with-eve.md +66 -12
  15. package/.docs/organized/code-examples/with-expo.md +26 -31
  16. package/.docs/organized/code-examples/with-external-store.md +17 -12
  17. package/.docs/organized/code-examples/with-ffmpeg.md +21 -15
  18. package/.docs/organized/code-examples/with-generative-ui.md +271 -36
  19. package/.docs/organized/code-examples/with-google-adk.md +17 -12
  20. package/.docs/organized/code-examples/with-heat-graph.md +6 -7
  21. package/.docs/organized/code-examples/with-image-generation.md +9 -10
  22. package/.docs/organized/code-examples/with-interactables.md +14 -13
  23. package/.docs/organized/code-examples/with-langchain.md +12 -13
  24. package/.docs/organized/code-examples/with-langgraph.md +19 -13
  25. package/.docs/organized/code-examples/with-livekit.md +13 -13
  26. package/.docs/organized/code-examples/with-mcp.md +14 -15
  27. package/.docs/organized/code-examples/with-nuxt.md +2428 -0
  28. package/.docs/organized/code-examples/with-opencode.md +23 -14
  29. package/.docs/organized/code-examples/with-openui.md +449 -0
  30. package/.docs/organized/code-examples/with-pi.md +59 -57
  31. package/.docs/organized/code-examples/with-react-hook-form.md +16 -15
  32. package/.docs/organized/code-examples/with-react-ink-web.md +7 -8
  33. package/.docs/organized/code-examples/with-react-ink.md +6 -6
  34. package/.docs/organized/code-examples/with-react-router.md +17 -11
  35. package/.docs/organized/code-examples/with-resumable-stream.md +12 -13
  36. package/.docs/organized/code-examples/with-store.md +27 -16
  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 +19 -13
  40. package/.docs/organized/code-examples/with-tap-runtime.md +15 -15
  41. package/.docs/organized/code-examples/with-virtualized-thread.md +8 -9
  42. package/.docs/organized/code-examples/with-vue.md +408 -0
  43. package/.docs/raw/docs/(docs)/cli.mdx +7 -2
  44. package/.docs/raw/docs/(docs)/index.mdx +9 -76
  45. package/.docs/raw/docs/(docs)/installation.mdx +6 -20
  46. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +24 -4
  47. package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +5 -1
  48. package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +9 -2
  49. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +2 -2
  50. package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +47 -1
  51. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +29 -4
  52. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +1 -1
  53. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +52 -1
  54. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +1 -1
  55. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +2 -2
  56. package/.docs/raw/docs/cloud/ai-sdk.mdx +4 -4
  57. package/.docs/raw/docs/cloud/index.mdx +1 -1
  58. package/.docs/raw/docs/copilots/model-context.mdx +4 -3
  59. package/.docs/raw/docs/copilots/motivation.mdx +4 -4
  60. package/.docs/raw/docs/guides/attachments.mdx +2 -2
  61. package/.docs/raw/docs/guides/chain-of-thought.mdx +1 -1
  62. package/.docs/raw/docs/guides/context-api.mdx +15 -17
  63. package/.docs/raw/docs/guides/dictation.mdx +1 -1
  64. package/.docs/raw/docs/guides/electron.mdx +1 -1
  65. package/.docs/raw/docs/guides/mentions.mdx +2 -0
  66. package/.docs/raw/docs/guides/resumable-streams.mdx +74 -3
  67. package/.docs/raw/docs/guides/suggestions.mdx +15 -12
  68. package/.docs/raw/docs/ink/hooks.mdx +9 -4
  69. package/.docs/raw/docs/ink/primitives.mdx +5 -4
  70. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +16 -0
  71. package/.docs/raw/docs/integrations/auth/better-auth.mdx +1 -1
  72. package/.docs/raw/docs/integrations/auth/clerk.mdx +1 -1
  73. package/.docs/raw/docs/integrations/auth/next-auth.mdx +1 -1
  74. package/.docs/raw/docs/integrations/frameworks/cloudflare-agents/overview.mdx +1 -1
  75. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +2 -2
  76. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  77. package/.docs/raw/docs/integrations/gateways/index.mdx +2 -2
  78. package/.docs/raw/docs/integrations/observability/helicone.mdx +2 -2
  79. package/.docs/raw/docs/integrations/observability/langfuse.mdx +1 -1
  80. package/.docs/raw/docs/integrations/observability/langsmith.mdx +2 -2
  81. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +146 -128
  82. package/.docs/raw/docs/migrations/toolkit-tools.mdx +15 -13
  83. package/.docs/raw/docs/migrations/v0-15.mdx +118 -4
  84. package/.docs/raw/docs/primitives/attachment.mdx +2 -2
  85. package/.docs/raw/docs/primitives/composer.mdx +2 -2
  86. package/.docs/raw/docs/primitives/message.mdx +33 -1
  87. package/.docs/raw/docs/primitives/suggestion.mdx +4 -2
  88. package/.docs/raw/docs/primitives/thread.mdx +1 -1
  89. package/.docs/raw/docs/react-native/hooks.mdx +14 -4
  90. package/.docs/raw/docs/react-native/index.mdx +1 -1
  91. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  92. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +35 -5
  93. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +1 -1
  94. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +1 -1
  95. package/.docs/raw/docs/runtimes/ai-sdk/v6-legacy.mdx +9 -10
  96. package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +9 -10
  97. package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +118 -0
  98. package/.docs/raw/docs/runtimes/concepts/stability.mdx +2 -1
  99. package/.docs/raw/docs/runtimes/concepts/threads.mdx +106 -27
  100. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +19 -1
  101. package/.docs/raw/docs/runtimes/custom/external-store.mdx +34 -1
  102. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +36 -9
  103. package/.docs/raw/docs/runtimes/eve/overview.mdx +51 -0
  104. package/.docs/raw/docs/runtimes/eve/quickstart.mdx +51 -2
  105. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +9 -12
  106. package/.docs/raw/docs/runtimes/langchain.mdx +1 -1
  107. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +5 -1
  108. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -7
  109. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +4 -4
  110. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +1 -0
  111. package/.docs/raw/docs/runtimes/opencode/overview.mdx +10 -0
  112. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +8 -1
  113. package/.docs/raw/docs/tools/backend.mdx +2 -2
  114. package/.docs/raw/docs/tools/defining-tools.mdx +28 -7
  115. package/.docs/raw/docs/tools/dynamic-tools.mdx +6 -4
  116. package/.docs/raw/docs/tools/generative-ui-primitive.mdx +180 -0
  117. package/.docs/raw/docs/tools/generative-ui-slack.mdx +167 -0
  118. package/.docs/raw/docs/tools/generative-ui-teams.mdx +160 -0
  119. package/.docs/raw/docs/tools/generative-ui.mdx +224 -211
  120. package/.docs/raw/docs/tools/index.mdx +2 -1
  121. package/.docs/raw/docs/tools/interactables.mdx +29 -17
  122. package/.docs/raw/docs/tools/mcp-apps.mdx +35 -6
  123. package/.docs/raw/docs/tools/mcp.mdx +9 -7
  124. package/.docs/raw/docs/tools/openui.mdx +175 -0
  125. package/.docs/raw/docs/tools/tool-ui.mdx +27 -24
  126. package/.docs/raw/docs/tools/user-managed-mcp.mdx +17 -8
  127. package/.docs/raw/docs/ui/attachment.mdx +27 -0
  128. package/.docs/raw/docs/ui/file.mdx +7 -2
  129. package/.docs/raw/docs/ui/image.mdx +1 -1
  130. package/.docs/raw/docs/ui/mcp-config.mdx +8 -3
  131. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  132. package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
  133. package/.docs/raw/docs/ui/thread.mdx +24 -5
  134. package/.docs/raw/docs/utilities/react-o11y.mdx +7 -9
  135. package/dist/constants.js +2 -2
  136. package/dist/constants.js.map +1 -1
  137. package/dist/index.js.map +1 -1
  138. package/dist/prepare-docs/prepare.js.map +1 -1
  139. package/dist/tools/docs.js +4 -2
  140. package/dist/tools/docs.js.map +1 -1
  141. package/dist/tools/examples.js +2 -1
  142. package/dist/tools/examples.js.map +1 -1
  143. package/dist/tools/resources.js +2 -1
  144. package/dist/tools/resources.js.map +1 -1
  145. package/dist/tools/tests/test-setup.js +2 -1
  146. package/dist/tools/tests/test-setup.js.map +1 -1
  147. package/dist/tools/xulux-templates.js +4 -2
  148. package/dist/tools/xulux-templates.js.map +1 -1
  149. package/dist/utils/mdx.js +2 -1
  150. package/dist/utils/mdx.js.map +1 -1
  151. package/dist/xulux/catalog-client.js +1 -1
  152. package/dist/xulux/catalog-client.js.map +1 -1
  153. package/package.json +4 -4
  154. package/src/tools/tests/docs.test.ts +2 -2
  155. package/.docs/raw/docs/tools/interactables-legacy.mdx +0 -410
@@ -65,13 +65,13 @@
65
65
  "@assistant-ui/react": "workspace:*",
66
66
  "@assistant-ui/react-markdown": "workspace:*",
67
67
  "@tailwindcss/vite": "^4.3.3",
68
- "@tanstack/react-router": "^1.170.18",
69
- "@tanstack/react-start": "^1.168.32",
68
+ "@tanstack/react-router": "^1.170.27",
69
+ "@tanstack/react-start": "^1.168.44",
70
70
  "class-variance-authority": "^0.7.1",
71
71
  "clsx": "^2.1.1",
72
- "lucide-react": "^1.26.0",
72
+ "lucide-react": "^1.31.0",
73
73
  "nitro": "^3.0.260311-beta",
74
- "openai": "^6.49.0",
74
+ "openai": "^7.4.0",
75
75
  "react": "^19.2.8",
76
76
  "react-dom": "^19.2.8",
77
77
  "remark-gfm": "^4.0.1",
@@ -81,12 +81,12 @@
81
81
  },
82
82
  "devDependencies": {
83
83
  "@assistant-ui/x-buildutils": "workspace:*",
84
- "@types/node": "^26.1.1",
85
- "@types/react": "^19.2.17",
86
- "@types/react-dom": "^19.2.3",
87
- "@vitejs/plugin-react": "^6.0.4",
84
+ "@types/node": "^26.2.0",
85
+ "@types/react": "^19.2.18",
86
+ "@types/react-dom": "^19.2.4",
87
+ "@vitejs/plugin-react": "^6.0.5",
88
88
  "typescript": "^7.0.2",
89
- "vite": "^8.1.5"
89
+ "vite": "^8.2.1"
90
90
  }
91
91
  }
92
92
 
@@ -321,13 +321,19 @@ function RootDocument({ children }: { children: React.ReactNode }) {
321
321
  ```tsx
322
322
  import { createFileRoute } from "@tanstack/react-router";
323
323
  import { Thread } from "@/components/assistant-ui/thread";
324
- import { useAui, AuiProvider, Suggestions } from "@assistant-ui/react";
324
+ import {
325
+ useAui,
326
+ AuiProvider,
327
+ AuiConfig,
328
+ Suggestions,
329
+ } from "@assistant-ui/react";
325
330
  import { MyRuntimeProvider } from "@/components/MyRuntimeProvider";
326
331
 
327
332
  export const Route = createFileRoute("/")({ component: App });
328
333
 
329
334
  function ThreadWithSuggestions() {
330
- const aui = useAui({
335
+ const aui = useAui();
336
+ const config = AuiConfig({
331
337
  suggestions: Suggestions([
332
338
  {
333
339
  title: "Hello!",
@@ -342,7 +348,7 @@ function ThreadWithSuggestions() {
342
348
  ]),
343
349
  });
344
350
  return (
345
- <AuiProvider value={aui}>
351
+ <AuiProvider extends={aui} config={config}>
346
352
  <Thread />
347
353
  </AuiProvider>
348
354
  );
@@ -457,7 +463,7 @@ export const chatStream = createServerFn({ method: "POST" })
457
463
  });
458
464
 
459
465
  const stream = await openai.chat.completions.create({
460
- model: "gpt-5.4-nano",
466
+ model: "gpt-5.6-luna",
461
467
  messages: data.messages,
462
468
  stream: true,
463
469
  });
@@ -165,8 +165,8 @@ export default function RootLayout({
165
165
 
166
166
  import { useState } from "react";
167
167
  import {
168
- useAui,
169
168
  AuiProvider,
169
+ AuiConfig,
170
170
  useAuiState,
171
171
  ExternalThread,
172
172
  InMemoryThreadList,
@@ -214,7 +214,7 @@ const SIMPLE_MESSAGES: SimpleMessage[] = [
214
214
  id: "4",
215
215
  role: "assistant",
216
216
  content:
217
- 'Sure! Here\'s how to use the tap-native runtime:\n\n```typescript\nconst messages = [\n { id: "1", role: "user", content: [{ type: "text", text: "Hello!" }] }\n];\n\nconst aui = useAui({\n threads: InMemoryThreadList({\n thread: (threadId) => ExternalThread({ messages, isRunning: false })\n }),\n onSwitchToThread: (threadId) => console.log("Switched to", threadId)\n});\n```\n\nTry using the thread list on the left to create and switch between threads!',
217
+ 'Sure! Here\'s how to use the tap-native runtime:\n\n```typescript\nconst messages = [\n { id: "1", role: "user", content: [{ type: "text", text: "Hello!" }] }\n];\n\nconst config = AuiConfig({\n threads: InMemoryThreadList({\n thread: (threadId) => ExternalThread({ messages, isRunning: false })\n })\n});\n\n<AuiProvider config={config}>{children}</AuiProvider>\n```\n\nTry using the thread list on the left to create and switch between threads!',
218
218
  status: { type: "complete", reason: "stop" },
219
219
  },
220
220
  ];
@@ -255,7 +255,7 @@ export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
255
255
  isRunning,
256
256
  }) as ExternalThreadMessage[];
257
257
 
258
- const aui = useAui({
258
+ const config = AuiConfig({
259
259
  threads: InMemoryThreadList({
260
260
  thread: (threadId) =>
261
261
  ExternalThread({
@@ -353,7 +353,7 @@ export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
353
353
  });
354
354
 
355
355
  return (
356
- <AuiProvider value={aui}>
356
+ <AuiProvider config={config}>
357
357
  <div className="flex h-full">
358
358
  {/* Thread List Sidebar */}
359
359
  <ThreadListSidebar />
@@ -600,8 +600,8 @@ export default withAui(nextConfig);
600
600
  "@assistant-ui/ui": "workspace:*",
601
601
  "class-variance-authority": "^0.7.1",
602
602
  "clsx": "^2.1.1",
603
- "lucide-react": "^1.26.0",
604
- "next": "^16.2.11",
603
+ "lucide-react": "^1.31.0",
604
+ "next": "^16.3.0",
605
605
  "react": "^19.2.8",
606
606
  "react-dom": "^19.2.8",
607
607
  "tailwind-merge": "^3.6.0"
@@ -610,14 +610,13 @@ export default withAui(nextConfig);
610
610
  "@assistant-ui/next": "workspace:*",
611
611
  "@assistant-ui/x-buildutils": "workspace:*",
612
612
  "@tailwindcss/postcss": "^4.3.3",
613
- "@types/node": "^26.1.1",
614
- "@types/react": "^19.2.17",
615
- "@types/react-dom": "^19.2.3",
616
- "postcss": "^8.5.23",
613
+ "@types/node": "^26.2.0",
614
+ "@types/react": "^19.2.18",
615
+ "@types/react-dom": "^19.2.4",
616
+ "postcss": "^8.5.26",
617
617
  "tailwindcss": "^4.3.3",
618
618
  "tw-animate-css": "^1.4.0",
619
- "typescript": "npm:@typescript/typescript6@^6.0.2",
620
- "typescript-7": "npm:typescript@^7.0.2"
619
+ "typescript": "^7.0.2"
621
620
  }
622
621
  }
623
622
 
@@ -672,10 +671,10 @@ const messages: ExternalThreadMessage[] = [
672
671
  ];
673
672
  ```
674
673
 
675
- ### 2. Create Runtime
674
+ ### 2. Create Config
676
675
 
677
676
  ```typescript
678
- const aui = useAui({
677
+ const config = AuiConfig({
679
678
  threads: InMemoryThreadList({
680
679
  thread: () => ExternalThread({ messages, isRunning: false }),
681
680
  }),
@@ -685,7 +684,7 @@ const aui = useAui({
685
684
  ### 3. Provide to App
686
685
 
687
686
  ```typescript
688
- <AuiProvider value={aui}>
687
+ <AuiProvider config={config}>
689
688
  <Thread.Root>
690
689
  <Thread.Messages />
691
690
  </Thread.Root>
@@ -795,6 +794,7 @@ You can extend this example to:
795
794
  ],
796
795
  "@/lib/utils": ["../../packages/ui/src/lib/utils"],
797
796
  "@assistant-ui/ui/*": ["../../packages/ui/src/*"],
797
+ "@assistant-ui/store/client": ["../../packages/store/src/client"],
798
798
  "@assistant-ui/*": ["../../packages/*/src"],
799
799
  "@assistant-ui/core/*": ["../../packages/core/src/*"],
800
800
  "@assistant-ui/react/*": ["../../packages/react/src/*"],
@@ -597,11 +597,11 @@ export default withAui(nextConfig);
597
597
  "@assistant-ui/react": "workspace:*",
598
598
  "@assistant-ui/react-markdown": "workspace:*",
599
599
  "@assistant-ui/ui": "workspace:*",
600
- "@tanstack/react-virtual": "^3.14.8",
600
+ "@tanstack/react-virtual": "^3.14.9",
601
601
  "class-variance-authority": "^0.7.1",
602
602
  "clsx": "^2.1.1",
603
- "lucide-react": "^1.26.0",
604
- "next": "^16.2.11",
603
+ "lucide-react": "^1.31.0",
604
+ "next": "^16.3.0",
605
605
  "react": "^19.2.8",
606
606
  "react-dom": "^19.2.8",
607
607
  "tailwind-merge": "^3.6.0"
@@ -610,14 +610,13 @@ export default withAui(nextConfig);
610
610
  "@assistant-ui/next": "workspace:*",
611
611
  "@assistant-ui/x-buildutils": "workspace:*",
612
612
  "@tailwindcss/postcss": "^4.3.3",
613
- "@types/node": "^26.1.1",
614
- "@types/react": "^19.2.17",
615
- "@types/react-dom": "^19.2.3",
616
- "postcss": "^8.5.23",
613
+ "@types/node": "^26.2.0",
614
+ "@types/react": "^19.2.18",
615
+ "@types/react-dom": "^19.2.4",
616
+ "postcss": "^8.5.26",
617
617
  "tailwindcss": "^4.3.3",
618
618
  "tw-animate-css": "^1.4.0",
619
- "typescript": "npm:@typescript/typescript6@^6.0.2",
620
- "typescript-7": "npm:typescript@^7.0.2"
619
+ "typescript": "^7.0.2"
621
620
  }
622
621
  }
623
622
 
@@ -0,0 +1,408 @@
1
+ # Example: with-vue
2
+
3
+ ## package.json
4
+
5
+ ```json
6
+ {
7
+ "name": "with-vue",
8
+ "version": "0.0.0",
9
+ "private": true,
10
+ "type": "module",
11
+ "scripts": {
12
+ "dev": "vite dev --port 3000",
13
+ "build": "vite build",
14
+ "serve": "vite preview"
15
+ },
16
+ "dependencies": {
17
+ "@assistant-ui/core": "workspace:*",
18
+ "@assistant-ui/store": "workspace:*",
19
+ "@assistant-ui/tap": "workspace:*",
20
+ "@assistant-ui/vue": "workspace:*",
21
+ "@lucide/vue": "^1.31.0",
22
+ "vue": "^3.5.41"
23
+ },
24
+ "devDependencies": {
25
+ "@tailwindcss/vite": "^4.3.3",
26
+ "@types/react": "^19.2.18",
27
+ "@vitejs/plugin-vue": "^6.0.8",
28
+ "tailwindcss": "^4.3.3",
29
+ "typescript": "^7.0.2",
30
+ "vite": "^8.2.1"
31
+ }
32
+ }
33
+
34
+ ```
35
+
36
+ ## src/env.d.ts
37
+
38
+ ```typescript
39
+ declare module "*.vue" {
40
+ import type { DefineComponent } from "vue";
41
+ const component: DefineComponent<
42
+ Record<string, never>,
43
+ Record<string, never>,
44
+ unknown
45
+ >;
46
+ export default component;
47
+ }
48
+
49
+ ```
50
+
51
+ ## src/main.ts
52
+
53
+ ```typescript
54
+ import { createApp } from "vue";
55
+ import "./styles.css";
56
+ import Root from "./Root.vue";
57
+
58
+ createApp(Root).mount("#app");
59
+
60
+ ```
61
+
62
+ ## src/runtime.ts
63
+
64
+ ```typescript
65
+ import type { AppendMessage, ExternalStoreAdapter } from "@assistant-ui/core";
66
+ import {
67
+ AssistantRuntimeImpl,
68
+ ExternalStoreRuntimeCore,
69
+ } from "@assistant-ui/core/internal";
70
+
71
+ export type EchoMessage = {
72
+ id: string;
73
+ role: "user" | "assistant";
74
+ text: string;
75
+ };
76
+
77
+ type EchoThread = {
78
+ id: string;
79
+ title: string;
80
+ messages: EchoMessage[];
81
+ };
82
+
83
+ let nextId = 0;
84
+ const freshId = (prefix: string) => `${prefix}-${nextId++}`;
85
+
86
+ const messageText = (message: AppendMessage) =>
87
+ message.content
88
+ .map((part) => (part.type === "text" ? part.text : ""))
89
+ .join("");
90
+
91
+ const convertEchoMessage = (message: EchoMessage) => ({
92
+ id: message.id,
93
+ role: message.role,
94
+ content: [{ type: "text" as const, text: message.text }],
95
+ });
96
+
97
+ export const createEchoRuntime = () => {
98
+ let threads: EchoThread[] = [
99
+ { id: freshId("thread"), title: "", messages: [] },
100
+ ];
101
+ let currentId = threads[0]!.id;
102
+ let isRunning = false;
103
+ let replyTimer: ReturnType<typeof setTimeout> | undefined;
104
+
105
+ const current = () => threads.find((thread) => thread.id === currentId)!;
106
+ const updateCurrent = (updater: (thread: EchoThread) => EchoThread) => {
107
+ threads = threads.map((thread) =>
108
+ thread.id === currentId ? updater(thread) : thread,
109
+ );
110
+ };
111
+
112
+ const reply = (text: string) => {
113
+ const replyTo = currentId;
114
+ isRunning = true;
115
+ sync();
116
+ replyTimer = setTimeout(() => {
117
+ if (currentId !== replyTo) return;
118
+ updateCurrent((thread) => ({
119
+ ...thread,
120
+ messages: [
121
+ ...thread.messages,
122
+ {
123
+ id: freshId("assistant"),
124
+ role: "assistant",
125
+ text: `Echo: ${text}`,
126
+ },
127
+ ],
128
+ }));
129
+ isRunning = false;
130
+ sync();
131
+ }, 600);
132
+ };
133
+
134
+ const appendUser = (text: string) => {
135
+ updateCurrent((thread) => ({
136
+ ...thread,
137
+ title: thread.title || text.slice(0, 40),
138
+ messages: [
139
+ ...thread.messages,
140
+ { id: freshId("user"), role: "user", text },
141
+ ],
142
+ }));
143
+ };
144
+
145
+ const makeAdapter = (): ExternalStoreAdapter<EchoMessage> => ({
146
+ messages: current().messages,
147
+ isRunning,
148
+ convertMessage: convertEchoMessage,
149
+ setMessages: (next) => {
150
+ updateCurrent((thread) => ({ ...thread, messages: next }));
151
+ sync();
152
+ },
153
+ onNew: async (message) => {
154
+ const text = messageText(message);
155
+ appendUser(text);
156
+ reply(text);
157
+ },
158
+ onEdit: async (message) => {
159
+ const text = messageText(message);
160
+ const parentIndex = message.parentId
161
+ ? current().messages.findIndex(
162
+ (entry) => entry.id === message.parentId,
163
+ ) + 1
164
+ : 0;
165
+ updateCurrent((thread) => ({
166
+ ...thread,
167
+ messages: thread.messages.slice(0, parentIndex),
168
+ }));
169
+ appendUser(text);
170
+ reply(text);
171
+ },
172
+ onReload: async (parentId) => {
173
+ let parentIndex = 0;
174
+ if (parentId) {
175
+ const index = current().messages.findIndex(
176
+ (entry) => entry.id === parentId,
177
+ );
178
+ if (index === -1) return;
179
+ parentIndex = index + 1;
180
+ }
181
+ const sliced = current().messages.slice(0, parentIndex);
182
+ const lastUser = [...sliced]
183
+ .reverse()
184
+ .find((entry) => entry.role === "user");
185
+ updateCurrent((thread) => ({ ...thread, messages: sliced }));
186
+ reply(`${lastUser?.text ?? ""} (again)`);
187
+ },
188
+ onCancel: async () => {
189
+ clearTimeout(replyTimer);
190
+ if (isRunning && current().messages.at(-1)?.role === "user") {
191
+ updateCurrent((thread) => ({
192
+ ...thread,
193
+ messages: thread.messages.slice(0, -1),
194
+ }));
195
+ }
196
+ isRunning = false;
197
+ // cancelRun restores the trailing user message into the composer
198
+ // synchronously after onCancel returns; an eager sync would delete it
199
+ // before that restore reads it.
200
+ queueMicrotask(sync);
201
+ },
202
+ adapters: {
203
+ threadList: {
204
+ threadId: currentId,
205
+ threads: threads.map((thread) => ({
206
+ status: "regular" as const,
207
+ id: thread.id,
208
+ title: thread.title,
209
+ })),
210
+ onSwitchToThread: (threadId) => {
211
+ clearTimeout(replyTimer);
212
+ isRunning = false;
213
+ currentId = threadId;
214
+ sync();
215
+ },
216
+ onSwitchToNewThread: () => {
217
+ clearTimeout(replyTimer);
218
+ isRunning = false;
219
+ const id = freshId("thread");
220
+ threads = [...threads, { id, title: "", messages: [] }];
221
+ currentId = id;
222
+ sync();
223
+ },
224
+ },
225
+ },
226
+ });
227
+
228
+ const core = new ExternalStoreRuntimeCore(makeAdapter());
229
+ const sync = () => core.setAdapter(makeAdapter());
230
+ return new AssistantRuntimeImpl(core);
231
+ };
232
+
233
+ ```
234
+
235
+ ## src/styles.css
236
+
237
+ ```css
238
+ @import "tailwindcss";
239
+
240
+ @custom-variant dark (&:is(.dark *));
241
+
242
+ @theme inline {
243
+ --radius-sm: calc(var(--radius) - 4px);
244
+ --radius-md: calc(var(--radius) - 2px);
245
+ --radius-lg: var(--radius);
246
+ --radius-xl: calc(var(--radius) + 4px);
247
+ --color-background: var(--background);
248
+ --color-foreground: var(--foreground);
249
+ --color-card: var(--card);
250
+ --color-card-foreground: var(--card-foreground);
251
+ --color-popover: var(--popover);
252
+ --color-popover-foreground: var(--popover-foreground);
253
+ --color-primary: var(--primary);
254
+ --color-primary-foreground: var(--primary-foreground);
255
+ --color-secondary: var(--secondary);
256
+ --color-secondary-foreground: var(--secondary-foreground);
257
+ --color-muted: var(--muted);
258
+ --color-muted-foreground: var(--muted-foreground);
259
+ --color-accent: var(--accent);
260
+ --color-accent-foreground: var(--accent-foreground);
261
+ --color-destructive: var(--destructive);
262
+ --color-border: var(--border);
263
+ --color-input: var(--input);
264
+ --color-ring: var(--ring);
265
+ --color-chart-1: var(--chart-1);
266
+ --color-chart-2: var(--chart-2);
267
+ --color-chart-3: var(--chart-3);
268
+ --color-chart-4: var(--chart-4);
269
+ --color-chart-5: var(--chart-5);
270
+ --color-sidebar: var(--sidebar);
271
+ --color-sidebar-foreground: var(--sidebar-foreground);
272
+ --color-sidebar-primary: var(--sidebar-primary);
273
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
274
+ --color-sidebar-accent: var(--sidebar-accent);
275
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
276
+ --color-sidebar-border: var(--sidebar-border);
277
+ --color-sidebar-ring: var(--sidebar-ring);
278
+ }
279
+
280
+ :root {
281
+ --radius: 0.625rem;
282
+ --background: oklch(1 0 0);
283
+ --foreground: oklch(0.141 0.005 285.823);
284
+ --card: oklch(1 0 0);
285
+ --card-foreground: oklch(0.141 0.005 285.823);
286
+ --popover: oklch(1 0 0);
287
+ --popover-foreground: oklch(0.141 0.005 285.823);
288
+ --primary: oklch(0.21 0.006 285.885);
289
+ --primary-foreground: oklch(0.985 0 0);
290
+ --secondary: oklch(0.967 0.001 286.375);
291
+ --secondary-foreground: oklch(0.21 0.006 285.885);
292
+ --muted: oklch(0.967 0.001 286.375);
293
+ --muted-foreground: oklch(0.552 0.016 285.938);
294
+ --accent: oklch(0.967 0.001 286.375);
295
+ --accent-foreground: oklch(0.21 0.006 285.885);
296
+ --destructive: oklch(0.577 0.245 27.325);
297
+ --border: oklch(0.92 0.004 286.32);
298
+ --input: oklch(0.92 0.004 286.32);
299
+ --ring: oklch(0.705 0.015 286.067);
300
+ --chart-1: oklch(0.646 0.222 41.116);
301
+ --chart-2: oklch(0.6 0.118 184.704);
302
+ --chart-3: oklch(0.398 0.07 227.392);
303
+ --chart-4: oklch(0.828 0.189 84.429);
304
+ --chart-5: oklch(0.769 0.188 70.08);
305
+ --sidebar: oklch(0.985 0 0);
306
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
307
+ --sidebar-primary: oklch(0.21 0.006 285.885);
308
+ --sidebar-primary-foreground: oklch(0.985 0 0);
309
+ --sidebar-accent: oklch(0.967 0.001 286.375);
310
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
311
+ --sidebar-border: oklch(0.92 0.004 286.32);
312
+ --sidebar-ring: oklch(0.705 0.015 286.067);
313
+ }
314
+
315
+ .dark {
316
+ --background: oklch(0.141 0.005 285.823);
317
+ --foreground: oklch(0.985 0 0);
318
+ --card: oklch(0.21 0.006 285.885);
319
+ --card-foreground: oklch(0.985 0 0);
320
+ --popover: oklch(0.21 0.006 285.885);
321
+ --popover-foreground: oklch(0.985 0 0);
322
+ --primary: oklch(0.92 0.004 286.32);
323
+ --primary-foreground: oklch(0.21 0.006 285.885);
324
+ --secondary: oklch(0.274 0.006 286.033);
325
+ --secondary-foreground: oklch(0.985 0 0);
326
+ --muted: oklch(0.274 0.006 286.033);
327
+ --muted-foreground: oklch(0.705 0.015 286.067);
328
+ --accent: oklch(0.274 0.006 286.033);
329
+ --accent-foreground: oklch(0.985 0 0);
330
+ --destructive: oklch(0.704 0.191 22.216);
331
+ --border: oklch(1 0 0 / 10%);
332
+ --input: oklch(1 0 0 / 15%);
333
+ --ring: oklch(0.552 0.016 285.938);
334
+ --chart-1: oklch(0.488 0.243 264.376);
335
+ --chart-2: oklch(0.696 0.17 162.48);
336
+ --chart-3: oklch(0.769 0.188 70.08);
337
+ --chart-4: oklch(0.627 0.265 303.9);
338
+ --chart-5: oklch(0.645 0.246 16.439);
339
+ --sidebar: oklch(0.21 0.006 285.885);
340
+ --sidebar-foreground: oklch(0.985 0 0);
341
+ --sidebar-primary: oklch(0.488 0.243 264.376);
342
+ --sidebar-primary-foreground: oklch(0.985 0 0);
343
+ --sidebar-accent: oklch(0.274 0.006 286.033);
344
+ --sidebar-accent-foreground: oklch(0.985 0 0);
345
+ --sidebar-border: oklch(1 0 0 / 10%);
346
+ --sidebar-ring: oklch(0.552 0.016 285.938);
347
+ }
348
+
349
+ @layer base {
350
+ * {
351
+ @apply border-border outline-ring/50;
352
+ }
353
+ body {
354
+ @apply bg-background text-foreground;
355
+ }
356
+ }
357
+
358
+ html,
359
+ body,
360
+ #app {
361
+ height: 100%;
362
+ }
363
+
364
+ ```
365
+
366
+ ## tsconfig.json
367
+
368
+ ```json
369
+ {
370
+ "compilerOptions": {
371
+ "target": "ES2022",
372
+ "module": "ESNext",
373
+ "moduleResolution": "bundler",
374
+ "strict": true,
375
+ "noEmit": true,
376
+ "skipLibCheck": true,
377
+ "types": ["vite/client"]
378
+ },
379
+ "include": ["src", "vite.config.ts"]
380
+ }
381
+
382
+ ```
383
+
384
+ ## vite.config.ts
385
+
386
+ ```typescript
387
+ import { defineConfig } from "vite";
388
+ import vue from "@vitejs/plugin-vue";
389
+ import tailwindcss from "@tailwindcss/vite";
390
+
391
+ // The assistant-ui runtime is written against react hook imports but runs on
392
+ // @assistant-ui/tap; aliasing react to the standalone shim resolves it with
393
+ // no React installed.
394
+ export default defineConfig({
395
+ plugins: [vue(), tailwindcss()],
396
+ resolve: {
397
+ alias: [
398
+ {
399
+ find: /^react\/compiler-runtime$/,
400
+ replacement: "@assistant-ui/tap/standalone-shim/compiler-runtime",
401
+ },
402
+ { find: /^react$/, replacement: "@assistant-ui/tap/standalone-shim" },
403
+ ],
404
+ },
405
+ });
406
+
407
+ ```
408
+
@@ -57,7 +57,7 @@ This command scaffolds a project from assistant-ui starter templates or examples
57
57
  | `cloud` | Cloud-backed persistence starter | `npx assistant-ui create -t cloud` |
58
58
  | `cloud-clerk` | Cloud-backed starter with Clerk auth | `npx assistant-ui create -t cloud-clerk` |
59
59
  | `langchain` | LangGraph starter with the react-langchain adapter | `npx assistant-ui create -t langchain` |
60
- | `mcp` | MCP starter template | `npx assistant-ui create -t mcp` |
60
+ | `mcp` | MCP tools + MCP Apps renderer starter | `npx assistant-ui create -t mcp` |
61
61
  | `eve` | Eve agent + Next.js starter | `npx assistant-ui create -t eve` |
62
62
 
63
63
  **Available Examples**
@@ -78,6 +78,7 @@ Use `--example` to create a project from one of the monorepo examples with full
78
78
  | `with-chain-of-thought` | Chain-of-thought reasoning, tool calls, and source citations | `npx assistant-ui create my-app -e with-chain-of-thought` |
79
79
  | `with-external-store` | External message store | `npx assistant-ui create my-app -e with-external-store` |
80
80
  | `with-interactables` | AI-driven interactive UI components | `npx assistant-ui create my-app -e with-interactables` |
81
+ | `with-openui` | [OpenUI](/docs/tools/openui) generative UI integration | `npx assistant-ui create my-app -e with-openui` |
81
82
  | `with-custom-thread-list` | Custom thread list UI | `npx assistant-ui create my-app -e with-custom-thread-list` |
82
83
  | `with-react-hook-form` | React Hook Form integration | `npx assistant-ui create my-app -e with-react-hook-form` |
83
84
  | `with-ffmpeg` | FFmpeg video processing tool | `npx assistant-ui create my-app -e with-ffmpeg` |
@@ -233,11 +234,15 @@ This command:
233
234
  - Prompts to install new packages
234
235
 
235
236
  **What it does:**
236
- - Applies all available codemods sequentially
237
+ - Applies the current bundled codemods sequentially
237
238
  - Shows progress bar with file count
238
239
  - Reports any transformation errors
239
240
  - Automatically detects and offers to install new dependencies
240
241
 
242
+ The latest upgrade excludes the historical v0.8 UI package split because its
243
+ `@assistant-ui/react-ui` destination is incompatible with current runtime versions.
244
+ Do not run `codemod v0-8/ui-package-split` as part of a v0.15 upgrade.
245
+
241
246
  **Example output:**
242
247
 
243
248
  ```bash