@assistant-ui/mcp-docs-server 0.1.24 → 0.1.25

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 (135) hide show
  1. package/.docs/organized/code-examples/waterfall.md +4 -2
  2. package/.docs/organized/code-examples/with-a2a.md +676 -0
  3. package/.docs/organized/code-examples/with-ag-ui.md +5 -6
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +27 -15
  5. package/.docs/organized/code-examples/with-artifacts.md +4 -4
  6. package/.docs/organized/code-examples/with-assistant-transport.md +2 -2
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +33 -25
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +9 -6
  9. package/.docs/organized/code-examples/with-cloud.md +4 -4
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +6 -6
  11. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
  12. package/.docs/organized/code-examples/with-expo.md +565 -514
  13. package/.docs/organized/code-examples/with-external-store.md +2 -2
  14. package/.docs/organized/code-examples/with-ffmpeg.md +4 -4
  15. package/.docs/organized/code-examples/with-google-adk.md +353 -0
  16. package/.docs/organized/code-examples/with-heat-graph.md +304 -0
  17. package/.docs/organized/code-examples/with-langgraph.md +24 -22
  18. package/.docs/organized/code-examples/with-parent-id-grouping.md +3 -3
  19. package/.docs/organized/code-examples/with-react-hook-form.md +4 -4
  20. package/.docs/organized/code-examples/with-react-ink.md +265 -0
  21. package/.docs/organized/code-examples/with-react-router.md +5 -5
  22. package/.docs/organized/code-examples/with-store.md +28 -17
  23. package/.docs/organized/code-examples/with-tanstack.md +7 -7
  24. package/.docs/organized/code-examples/with-tap-runtime.md +5 -3
  25. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
  26. package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
  27. package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
  28. package/.docs/raw/docs/(docs)/cli.mdx +14 -9
  29. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
  30. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
  31. package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
  32. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
  33. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
  34. package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
  35. package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
  36. package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
  37. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
  38. package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
  39. package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
  40. package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
  41. package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
  42. package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
  43. package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
  44. package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
  45. package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
  46. package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
  47. package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
  48. package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
  49. package/.docs/raw/docs/(docs)/index.mdx +3 -3
  50. package/.docs/raw/docs/(docs)/installation.mdx +69 -46
  51. package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
  52. package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
  53. package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
  55. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
  56. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
  61. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
  62. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
  63. package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
  64. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
  65. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
  66. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
  67. package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
  68. package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
  69. package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
  70. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
  71. package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
  72. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
  73. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
  74. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
  75. package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
  76. package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
  77. package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
  78. package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
  79. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
  80. package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
  81. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +84 -6
  82. package/.docs/raw/docs/cloud/ai-sdk.mdx +14 -4
  83. package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
  84. package/.docs/raw/docs/ink/adapters.mdx +41 -0
  85. package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
  86. package/.docs/raw/docs/ink/hooks.mdx +448 -0
  87. package/.docs/raw/docs/ink/index.mdx +239 -0
  88. package/.docs/raw/docs/ink/migration.mdx +140 -0
  89. package/.docs/raw/docs/ink/primitives.mdx +699 -0
  90. package/.docs/raw/docs/react-native/adapters.mdx +63 -87
  91. package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
  92. package/.docs/raw/docs/react-native/hooks.mdx +214 -232
  93. package/.docs/raw/docs/react-native/index.mdx +118 -159
  94. package/.docs/raw/docs/react-native/migration.mdx +144 -0
  95. package/.docs/raw/docs/react-native/primitives.mdx +431 -302
  96. package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
  97. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
  98. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
  99. package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
  100. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
  101. package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
  102. package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
  103. package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
  104. package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
  105. package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
  106. package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
  107. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
  108. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
  109. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
  110. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
  111. package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
  112. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
  113. package/.docs/raw/docs/ui/file.mdx +5 -4
  114. package/.docs/raw/docs/ui/image.mdx +5 -4
  115. package/.docs/raw/docs/ui/markdown.mdx +3 -1
  116. package/.docs/raw/docs/ui/model-selector.mdx +8 -8
  117. package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
  118. package/.docs/raw/docs/ui/quote.mdx +210 -0
  119. package/.docs/raw/docs/ui/reasoning.mdx +12 -11
  120. package/.docs/raw/docs/ui/sources.mdx +88 -17
  121. package/.docs/raw/docs/ui/streamdown.mdx +16 -7
  122. package/.docs/raw/docs/ui/thread-list.mdx +11 -13
  123. package/.docs/raw/docs/ui/thread.mdx +28 -33
  124. package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
  125. package/.docs/raw/docs/ui/tool-group.mdx +9 -8
  126. package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
  127. package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
  128. package/package.json +4 -4
  129. package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
  130. package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
  131. package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
  132. package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
  133. package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
  134. package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
  135. /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
@@ -688,7 +688,9 @@ export function WaterfallTimeline() {
688
688
  }
689
689
  }}
690
690
  >
691
- <SpanPrimitive.Children components={{ Span: WaterfallRow }} />
691
+ <SpanPrimitive.Children>
692
+ {() => <WaterfallRow />}
693
+ </SpanPrimitive.Children>
692
694
  </div>
693
695
  </WaterfallLayoutContext.Provider>
694
696
  </div>
@@ -774,7 +776,7 @@ export default nextConfig;
774
776
  "devDependencies": {
775
777
  "@assistant-ui/x-buildutils": "workspace:*",
776
778
  "@tailwindcss/postcss": "^4.2.1",
777
- "@types/node": "^25.3.3",
779
+ "@types/node": "^25.5.0",
778
780
  "@types/react": "^19.2.14",
779
781
  "@types/react-dom": "^19.2.3",
780
782
  "postcss": "^8.5.8",
@@ -0,0 +1,676 @@
1
+ # Example: with-a2a
2
+
3
+ ## app/globals.css
4
+
5
+ ```css
6
+ @import "tailwindcss";
7
+ @import "tw-animate-css";
8
+
9
+ @source "../../../packages/ui/src";
10
+
11
+ @custom-variant dark (&:is(.dark *));
12
+
13
+ @theme inline {
14
+ --radius-sm: calc(var(--radius) - 4px);
15
+ --radius-md: calc(var(--radius) - 2px);
16
+ --radius-lg: var(--radius);
17
+ --radius-xl: calc(var(--radius) + 4px);
18
+ --color-background: var(--background);
19
+ --color-foreground: var(--foreground);
20
+ --color-card: var(--card);
21
+ --color-card-foreground: var(--card-foreground);
22
+ --color-popover: var(--popover);
23
+ --color-popover-foreground: var(--popover-foreground);
24
+ --color-primary: var(--primary);
25
+ --color-primary-foreground: var(--primary-foreground);
26
+ --color-secondary: var(--secondary);
27
+ --color-secondary-foreground: var(--secondary-foreground);
28
+ --color-muted: var(--muted);
29
+ --color-muted-foreground: var(--muted-foreground);
30
+ --color-accent: var(--accent);
31
+ --color-accent-foreground: var(--accent-foreground);
32
+ --color-destructive: var(--destructive);
33
+ --color-border: var(--border);
34
+ --color-input: var(--input);
35
+ --color-ring: var(--ring);
36
+ --color-chart-1: var(--chart-1);
37
+ --color-chart-2: var(--chart-2);
38
+ --color-chart-3: var(--chart-3);
39
+ --color-chart-4: var(--chart-4);
40
+ --color-chart-5: var(--chart-5);
41
+ --color-sidebar: var(--sidebar);
42
+ --color-sidebar-foreground: var(--sidebar-foreground);
43
+ --color-sidebar-primary: var(--sidebar-primary);
44
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
45
+ --color-sidebar-accent: var(--sidebar-accent);
46
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
47
+ --color-sidebar-border: var(--sidebar-border);
48
+ --color-sidebar-ring: var(--sidebar-ring);
49
+ }
50
+
51
+ :root {
52
+ --radius: 0.625rem;
53
+ --background: oklch(1 0 0);
54
+ --foreground: oklch(0.141 0.005 285.823);
55
+ --card: oklch(1 0 0);
56
+ --card-foreground: oklch(0.141 0.005 285.823);
57
+ --popover: oklch(1 0 0);
58
+ --popover-foreground: oklch(0.141 0.005 285.823);
59
+ --primary: oklch(0.21 0.006 285.885);
60
+ --primary-foreground: oklch(0.985 0 0);
61
+ --secondary: oklch(0.967 0.001 286.375);
62
+ --secondary-foreground: oklch(0.21 0.006 285.885);
63
+ --muted: oklch(0.967 0.001 286.375);
64
+ --muted-foreground: oklch(0.552 0.016 285.938);
65
+ --accent: oklch(0.967 0.001 286.375);
66
+ --accent-foreground: oklch(0.21 0.006 285.885);
67
+ --destructive: oklch(0.577 0.245 27.325);
68
+ --border: oklch(0.92 0.004 286.32);
69
+ --input: oklch(0.92 0.004 286.32);
70
+ --ring: oklch(0.705 0.015 286.067);
71
+ --chart-1: oklch(0.646 0.222 41.116);
72
+ --chart-2: oklch(0.6 0.118 184.704);
73
+ --chart-3: oklch(0.398 0.07 227.392);
74
+ --chart-4: oklch(0.828 0.189 84.429);
75
+ --chart-5: oklch(0.769 0.188 70.08);
76
+ --sidebar: oklch(0.985 0 0);
77
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
78
+ --sidebar-primary: oklch(0.21 0.006 285.885);
79
+ --sidebar-primary-foreground: oklch(0.985 0 0);
80
+ --sidebar-accent: oklch(0.967 0.001 286.375);
81
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
82
+ --sidebar-border: oklch(0.92 0.004 286.32);
83
+ --sidebar-ring: oklch(0.705 0.015 286.067);
84
+ }
85
+
86
+ .dark {
87
+ --background: oklch(0.141 0.005 285.823);
88
+ --foreground: oklch(0.985 0 0);
89
+ --card: oklch(0.21 0.006 285.885);
90
+ --card-foreground: oklch(0.985 0 0);
91
+ --popover: oklch(0.21 0.006 285.885);
92
+ --popover-foreground: oklch(0.985 0 0);
93
+ --primary: oklch(0.92 0.004 286.32);
94
+ --primary-foreground: oklch(0.21 0.006 285.885);
95
+ --secondary: oklch(0.274 0.006 286.033);
96
+ --secondary-foreground: oklch(0.985 0 0);
97
+ --muted: oklch(0.274 0.006 286.033);
98
+ --muted-foreground: oklch(0.705 0.015 286.067);
99
+ --accent: oklch(0.274 0.006 286.033);
100
+ --accent-foreground: oklch(0.985 0 0);
101
+ --destructive: oklch(0.704 0.191 22.216);
102
+ --border: oklch(1 0 0 / 10%);
103
+ --input: oklch(1 0 0 / 15%);
104
+ --ring: oklch(0.552 0.016 285.938);
105
+ --chart-1: oklch(0.488 0.243 264.376);
106
+ --chart-2: oklch(0.696 0.17 162.48);
107
+ --chart-3: oklch(0.769 0.188 70.08);
108
+ --chart-4: oklch(0.627 0.265 303.9);
109
+ --chart-5: oklch(0.645 0.246 16.439);
110
+ --sidebar: oklch(0.21 0.006 285.885);
111
+ --sidebar-foreground: oklch(0.985 0 0);
112
+ --sidebar-primary: oklch(0.488 0.243 264.376);
113
+ --sidebar-primary-foreground: oklch(0.985 0 0);
114
+ --sidebar-accent: oklch(0.274 0.006 286.033);
115
+ --sidebar-accent-foreground: oklch(0.985 0 0);
116
+ --sidebar-border: oklch(1 0 0 / 10%);
117
+ --sidebar-ring: oklch(0.552 0.016 285.938);
118
+ }
119
+
120
+ @layer base {
121
+ * {
122
+ @apply border-border outline-ring/50;
123
+ }
124
+ body {
125
+ @apply bg-background text-foreground;
126
+ }
127
+ }
128
+
129
+ ```
130
+
131
+ ## app/layout.tsx
132
+
133
+ ```tsx
134
+ import type { Metadata } from "next";
135
+ import { MyRuntimeProvider } from "@/app/MyRuntimeProvider";
136
+
137
+ import "./globals.css";
138
+
139
+ export const metadata: Metadata = {
140
+ title: "assistant-ui + A2A",
141
+ description: "A2A protocol integration with assistant-ui",
142
+ };
143
+
144
+ export default function RootLayout({
145
+ children,
146
+ }: Readonly<{
147
+ children: React.ReactNode;
148
+ }>) {
149
+ return (
150
+ <html lang="en" className="h-dvh">
151
+ <body className="h-dvh font-sans">
152
+ <MyRuntimeProvider>{children}</MyRuntimeProvider>
153
+ </body>
154
+ </html>
155
+ );
156
+ }
157
+
158
+ ```
159
+
160
+ ## app/MyRuntimeProvider.tsx
161
+
162
+ ```tsx
163
+ "use client";
164
+
165
+ import type { ReactNode } from "react";
166
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
167
+ import { useA2ARuntime } from "@assistant-ui/react-a2a";
168
+
169
+ export function MyRuntimeProvider({
170
+ children,
171
+ }: Readonly<{ children: ReactNode }>) {
172
+ const serverUrl =
173
+ (process.env["NEXT_PUBLIC_A2A_SERVER_URL"] as string | undefined) ??
174
+ "http://localhost:9999";
175
+
176
+ const runtime = useA2ARuntime({
177
+ baseUrl: serverUrl,
178
+ });
179
+
180
+ return (
181
+ <AssistantRuntimeProvider runtime={runtime}>
182
+ {children}
183
+ </AssistantRuntimeProvider>
184
+ );
185
+ }
186
+
187
+ ```
188
+
189
+ ## app/page.tsx
190
+
191
+ ```tsx
192
+ "use client";
193
+
194
+ import { useAui, AuiProvider, Suggestions } from "@assistant-ui/react";
195
+ import {
196
+ useA2ATask,
197
+ useA2AArtifacts,
198
+ useA2AAgentCard,
199
+ type A2ATaskState,
200
+ type A2APart,
201
+ } from "@assistant-ui/react-a2a";
202
+ import { Thread } from "@/components/assistant-ui/thread";
203
+
204
+ // === State Badge ===
205
+
206
+ const STATE_CONFIG: Record<
207
+ string,
208
+ { label: string; color: string; bg: string }
209
+ > = {
210
+ submitted: {
211
+ label: "Submitted",
212
+ color: "text-blue-600",
213
+ bg: "bg-blue-100 dark:bg-blue-900/30",
214
+ },
215
+ working: {
216
+ label: "Working",
217
+ color: "text-amber-600",
218
+ bg: "bg-amber-100 dark:bg-amber-900/30",
219
+ },
220
+ completed: {
221
+ label: "Completed",
222
+ color: "text-green-600",
223
+ bg: "bg-green-100 dark:bg-green-900/30",
224
+ },
225
+ failed: {
226
+ label: "Failed",
227
+ color: "text-red-600",
228
+ bg: "bg-red-100 dark:bg-red-900/30",
229
+ },
230
+ canceled: {
231
+ label: "Canceled",
232
+ color: "text-gray-600",
233
+ bg: "bg-gray-100 dark:bg-gray-900/30",
234
+ },
235
+ rejected: {
236
+ label: "Rejected",
237
+ color: "text-red-600",
238
+ bg: "bg-red-100 dark:bg-red-900/30",
239
+ },
240
+ input_required: {
241
+ label: "Input Required",
242
+ color: "text-purple-600",
243
+ bg: "bg-purple-100 dark:bg-purple-900/30",
244
+ },
245
+ auth_required: {
246
+ label: "Auth Required",
247
+ color: "text-orange-600",
248
+ bg: "bg-orange-100 dark:bg-orange-900/30",
249
+ },
250
+ };
251
+
252
+ function StateBadge({ state }: { state: A2ATaskState }) {
253
+ const config = STATE_CONFIG[state] ?? {
254
+ label: state,
255
+ color: "text-gray-600",
256
+ bg: "bg-gray-100",
257
+ };
258
+ const isActive = state === "working" || state === "submitted";
259
+
260
+ return (
261
+ <span
262
+ className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 font-medium text-xs ${config.color} ${config.bg}`}
263
+ >
264
+ {isActive ? (
265
+ <span className="relative flex size-1.5">
266
+ <span className="absolute inline-flex size-full animate-ping rounded-full bg-current opacity-75" />
267
+ <span className="relative inline-flex size-1.5 rounded-full bg-current" />
268
+ </span>
269
+ ) : (
270
+ <span className="inline-flex size-1.5 rounded-full bg-current" />
271
+ )}
272
+ {config.label}
273
+ </span>
274
+ );
275
+ }
276
+
277
+ // === Task Status Bar ===
278
+
279
+ function TaskStatusBar() {
280
+ const task = useA2ATask();
281
+
282
+ if (!task) return null;
283
+
284
+ const { state } = task.status;
285
+ const isError = state === "failed" || state === "rejected";
286
+ const errorText = isError ? task.status.message?.parts?.[0]?.text : undefined;
287
+
288
+ return (
289
+ <div className="flex items-center gap-2 border-b px-4 py-2 text-sm">
290
+ <StateBadge state={state} />
291
+ <span className="text-muted-foreground">Task {task.id.slice(0, 8)}</span>
292
+ {errorText && (
293
+ <span className="ml-auto text-red-600 text-xs">{errorText}</span>
294
+ )}
295
+ </div>
296
+ );
297
+ }
298
+
299
+ // === Artifact Part Renderer ===
300
+
301
+ function ArtifactPartView({ part }: { part: A2APart }) {
302
+ if (part.text !== undefined) {
303
+ return (
304
+ <pre className="overflow-x-auto whitespace-pre-wrap rounded border bg-background p-2 font-mono text-xs">
305
+ {part.text}
306
+ </pre>
307
+ );
308
+ }
309
+ if (part.data !== undefined) {
310
+ return (
311
+ <div className="rounded border bg-background p-2">
312
+ <div className="mb-1 font-medium text-muted-foreground text-xs">
313
+ Data
314
+ </div>
315
+ <pre className="overflow-x-auto whitespace-pre-wrap font-mono text-xs">
316
+ {JSON.stringify(part.data, null, 2)}
317
+ </pre>
318
+ </div>
319
+ );
320
+ }
321
+ if (part.url !== undefined) {
322
+ const isImage = part.mediaType?.startsWith("image/");
323
+ if (isImage) {
324
+ return (
325
+ <img
326
+ src={part.url}
327
+ alt={part.filename ?? "image"}
328
+ className="max-h-64 rounded border"
329
+ />
330
+ );
331
+ }
332
+ return (
333
+ <a
334
+ href={part.url}
335
+ target="_blank"
336
+ rel="noopener noreferrer"
337
+ className="inline-flex items-center gap-2 rounded border bg-background p-2 text-sm hover:bg-muted"
338
+ >
339
+ <span>📄</span>
340
+ <span>{part.filename ?? "Download"}</span>
341
+ {part.mediaType && (
342
+ <span className="text-muted-foreground text-xs">
343
+ {part.mediaType}
344
+ </span>
345
+ )}
346
+ </a>
347
+ );
348
+ }
349
+ if (part.raw !== undefined) {
350
+ const isImage = part.mediaType?.startsWith("image/");
351
+ if (isImage) {
352
+ return (
353
+ <img
354
+ src={`data:${part.mediaType};base64,${part.raw}`}
355
+ alt={part.filename ?? "image"}
356
+ className="max-h-64 rounded border"
357
+ />
358
+ );
359
+ }
360
+ const dataUri = `data:${part.mediaType ?? "application/octet-stream"};base64,${part.raw}`;
361
+ return (
362
+ <a
363
+ href={dataUri}
364
+ download={part.filename ?? "download"}
365
+ className="inline-flex items-center gap-2 rounded border bg-background p-2 text-sm hover:bg-muted"
366
+ >
367
+ <span>📎</span>
368
+ <span>{part.filename ?? "File"}</span>
369
+ {part.mediaType && (
370
+ <span className="text-muted-foreground text-xs">
371
+ {part.mediaType}
372
+ </span>
373
+ )}
374
+ </a>
375
+ );
376
+ }
377
+ return null;
378
+ }
379
+
380
+ // === Artifact Panel ===
381
+
382
+ function ArtifactPanel() {
383
+ const artifacts = useA2AArtifacts();
384
+
385
+ if (artifacts.length === 0) return null;
386
+
387
+ return (
388
+ <div className="max-h-80 overflow-y-auto border-t px-4 py-3">
389
+ <h3 className="mb-2 font-medium text-muted-foreground text-xs">
390
+ Artifacts ({artifacts.length})
391
+ </h3>
392
+ <div className="space-y-2">
393
+ {artifacts.map((artifact) => (
394
+ <div
395
+ key={artifact.artifactId}
396
+ className="overflow-hidden rounded-md border bg-muted/30"
397
+ >
398
+ <div className="flex items-center gap-2 border-b bg-muted/50 px-3 py-1.5">
399
+ <span className="font-medium text-xs">
400
+ {artifact.name ?? artifact.artifactId}
401
+ </span>
402
+ {artifact.description && (
403
+ <span className="text-muted-foreground text-xs">
404
+ {artifact.description}
405
+ </span>
406
+ )}
407
+ </div>
408
+ <div className="space-y-2 p-3">
409
+ {artifact.parts.map((part, i) => (
410
+ <ArtifactPartView key={i} part={part} />
411
+ ))}
412
+ </div>
413
+ </div>
414
+ ))}
415
+ </div>
416
+ </div>
417
+ );
418
+ }
419
+
420
+ // === Agent Card Banner ===
421
+
422
+ function AgentCardBanner() {
423
+ const card = useA2AAgentCard();
424
+
425
+ if (!card) return null;
426
+
427
+ return (
428
+ <div className="flex items-center gap-3 border-b bg-muted/30 px-4 py-2">
429
+ <div className="flex-1">
430
+ <div className="font-medium text-sm">{card.name}</div>
431
+ <div className="text-muted-foreground text-xs">{card.description}</div>
432
+ </div>
433
+ <div className="flex flex-wrap gap-1">
434
+ {card.skills.map((skill) => (
435
+ <span
436
+ key={skill.id}
437
+ className="rounded-md bg-muted px-2 py-0.5 text-xs"
438
+ title={skill.description}
439
+ >
440
+ {skill.name}
441
+ </span>
442
+ ))}
443
+ </div>
444
+ <div className="text-muted-foreground text-xs">
445
+ v{card.version}
446
+ {card.capabilities.streaming && " · Streaming"}
447
+ </div>
448
+ </div>
449
+ );
450
+ }
451
+
452
+ // === Thread with Suggestions ===
453
+
454
+ function ThreadWithSuggestions() {
455
+ const aui = useAui({
456
+ suggestions: Suggestions([
457
+ {
458
+ title: "Chat",
459
+ label: "say hello",
460
+ prompt: "Hello! What can you do?",
461
+ },
462
+ {
463
+ title: "Generate artifacts",
464
+ label: "code + data + file",
465
+ prompt: "/artifacts a fibonacci function in Python",
466
+ },
467
+ {
468
+ title: "Multi-step",
469
+ label: "input-required flow",
470
+ prompt: "/multistep",
471
+ },
472
+ {
473
+ title: "Failure demo",
474
+ label: "test error handling",
475
+ prompt: "/fail",
476
+ },
477
+ {
478
+ title: "Slow task",
479
+ label: "test cancellation",
480
+ prompt: "/slow",
481
+ },
482
+ ]),
483
+ });
484
+ return (
485
+ <AuiProvider value={aui}>
486
+ <Thread />
487
+ </AuiProvider>
488
+ );
489
+ }
490
+
491
+ // === Main ===
492
+
493
+ export default function Home() {
494
+ return (
495
+ <main className="flex h-dvh flex-col">
496
+ <AgentCardBanner />
497
+ <TaskStatusBar />
498
+ <div className="min-h-0 flex-1">
499
+ <ThreadWithSuggestions />
500
+ </div>
501
+ <ArtifactPanel />
502
+ </main>
503
+ );
504
+ }
505
+
506
+ ```
507
+
508
+ ## components.json
509
+
510
+ ```json
511
+ {
512
+ "$schema": "https://ui.shadcn.com/schema.json",
513
+ "style": "new-york",
514
+ "rsc": true,
515
+ "tsx": true,
516
+ "tailwind": {
517
+ "config": "",
518
+ "css": "app/globals.css",
519
+ "baseColor": "zinc",
520
+ "cssVariables": true,
521
+ "prefix": ""
522
+ },
523
+ "aliases": {
524
+ "components": "@/components",
525
+ "utils": "@/lib/utils",
526
+ "ui": "@/components/ui",
527
+ "lib": "@/lib",
528
+ "hooks": "@/hooks"
529
+ },
530
+ "iconLibrary": "lucide",
531
+ "registries": {
532
+ "@assistant-ui": "https://r.assistant-ui.com/{name}.json"
533
+ }
534
+ }
535
+
536
+ ```
537
+
538
+ ## next.config.ts
539
+
540
+ ```typescript
541
+ import type { NextConfig } from "next";
542
+
543
+ const nextConfig: NextConfig = {
544
+ /* config options here */
545
+ };
546
+
547
+ export default nextConfig;
548
+
549
+ ```
550
+
551
+ ## package.json
552
+
553
+ ```json
554
+ {
555
+ "name": "with-a2a",
556
+ "version": "0.0.0",
557
+ "private": true,
558
+ "type": "module",
559
+ "scripts": {
560
+ "dev": "next dev",
561
+ "build": "next build",
562
+ "start": "next start"
563
+ },
564
+ "dependencies": {
565
+ "@assistant-ui/react": "workspace:*",
566
+ "@assistant-ui/react-a2a": "workspace:*",
567
+ "@assistant-ui/react-markdown": "workspace:*",
568
+ "@assistant-ui/ui": "workspace:*",
569
+ "class-variance-authority": "^0.7.1",
570
+ "clsx": "^2.1.1",
571
+ "lucide-react": "^0.577.0",
572
+ "next": "^16.1.6",
573
+ "react": "^19.2.4",
574
+ "react-dom": "^19.2.4",
575
+ "tailwind-merge": "^3.5.0"
576
+ },
577
+ "devDependencies": {
578
+ "@assistant-ui/x-buildutils": "workspace:*",
579
+ "@tailwindcss/postcss": "^4.2.1",
580
+ "@types/node": "^25.5.0",
581
+ "@types/react": "^19.2.14",
582
+ "@types/react-dom": "^19.2.3",
583
+ "postcss": "^8.5.8",
584
+ "tailwindcss": "^4.2.1",
585
+ "tw-animate-css": "^1.4.0",
586
+ "typescript": "^5.9.3"
587
+ }
588
+ }
589
+
590
+ ```
591
+
592
+ ## README.md
593
+
594
+ ```markdown
595
+ # with-a2a
596
+
597
+ An example of using [assistant-ui](https://www.assistant-ui.com/) with the [A2A (Agent-to-Agent) protocol](https://github.com/a2aproject/A2A).
598
+
599
+ ## Getting Started
600
+
601
+ ### 1. Start an A2A server
602
+
603
+ You need an A2A-compatible agent server. For example, using the [assistant-ui-a2a](https://github.com/assistant-ui/assistant-ui-a2a) kitchen sink demo:
604
+
605
+ ```bash
606
+ cd a2a-server
607
+ pip install -e .
608
+ python main.py
609
+ ```
610
+
611
+ This starts an A2A server at `http://localhost:9999` with 5 skills.
612
+
613
+ ### 2. Configure the frontend
614
+
615
+ ```bash
616
+ cp .env.example .env
617
+ # Edit .env if your A2A server is not at localhost:9999
618
+ ```
619
+
620
+ ### 3. Run the frontend
621
+
622
+ ```bash
623
+ pnpm install
624
+ pnpm dev
625
+ ```
626
+
627
+ Open [http://localhost:3000](http://localhost:3000).
628
+
629
+ ## Features Demonstrated
630
+
631
+ | Feature | Skill / Command |
632
+ |---|---|
633
+ | Streaming chat | Default chat |
634
+ | Artifacts (text, data, file) | `/artifacts <topic>` |
635
+ | Multi-step input-required flow | `/multistep` then provide topic |
636
+ | Error/failure handling | `/fail` |
637
+ | Long-running + cancellation | `/slow` |
638
+ | Agent card display | Automatic on load |
639
+ | Task state tracking (8 states) | All commands |
640
+
641
+ ## Architecture
642
+
643
+ ```
644
+ Browser (Next.js) ──A2A v1.0 SSE──▶ A2A Server
645
+ ```
646
+
647
+ No proxy backend needed. `@assistant-ui/react-a2a` handles the full A2A protocol directly:
648
+ - Agent card discovery (`/.well-known/agent-card.json`)
649
+ - Streaming via `POST /message:stream` (SSE)
650
+ - Task lifecycle management
651
+ - Artifact accumulation
652
+
653
+ ```
654
+
655
+ ## tsconfig.json
656
+
657
+ ```json
658
+ {
659
+ "extends": "@assistant-ui/x-buildutils/ts/next",
660
+ "compilerOptions": {
661
+ "paths": {
662
+ "@/*": ["./*"],
663
+ "@/components/assistant-ui/*": [
664
+ "../../packages/ui/src/components/assistant-ui/*"
665
+ ],
666
+ "@/components/ui/*": ["../../packages/ui/src/components/ui/*"],
667
+ "@/lib/utils": ["../../packages/ui/src/lib/utils"],
668
+ "@assistant-ui/ui/*": ["../../packages/ui/src/*"]
669
+ }
670
+ },
671
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
672
+ "exclude": ["node_modules"]
673
+ }
674
+
675
+ ```
676
+