@assistant-ui/mcp-docs-server 0.1.23 → 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.
- package/.docs/organized/code-examples/waterfall.md +5 -3
- package/.docs/organized/code-examples/with-a2a.md +676 -0
- package/.docs/organized/code-examples/with-ag-ui.md +7 -8
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +28 -16
- package/.docs/organized/code-examples/with-artifacts.md +5 -5
- package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
- package/.docs/organized/code-examples/with-chain-of-thought.md +34 -26
- package/.docs/organized/code-examples/with-cloud-standalone.md +10 -8
- package/.docs/organized/code-examples/with-cloud.md +5 -5
- package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +8 -8
- package/.docs/organized/code-examples/with-expo.md +571 -539
- package/.docs/organized/code-examples/with-external-store.md +3 -4
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
- package/.docs/organized/code-examples/with-google-adk.md +353 -0
- package/.docs/organized/code-examples/with-heat-graph.md +304 -0
- package/.docs/organized/code-examples/with-langgraph.md +25 -23
- package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
- package/.docs/organized/code-examples/with-react-hook-form.md +6 -9
- package/.docs/organized/code-examples/with-react-ink.md +265 -0
- package/.docs/organized/code-examples/with-react-router.md +10 -11
- package/.docs/organized/code-examples/with-store.md +29 -18
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +6 -4
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
- package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
- package/.docs/raw/docs/(docs)/cli.mdx +14 -9
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
- package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
- package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
- package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
- package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
- package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
- package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
- package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
- package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
- package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
- package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
- package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
- package/.docs/raw/docs/(docs)/index.mdx +3 -3
- package/.docs/raw/docs/(docs)/installation.mdx +69 -46
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
- package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
- package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
- package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
- package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +89 -7
- package/.docs/raw/docs/cloud/ai-sdk.mdx +19 -5
- package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
- package/.docs/raw/docs/ink/adapters.mdx +41 -0
- package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
- package/.docs/raw/docs/ink/hooks.mdx +448 -0
- package/.docs/raw/docs/ink/index.mdx +239 -0
- package/.docs/raw/docs/ink/migration.mdx +140 -0
- package/.docs/raw/docs/ink/primitives.mdx +699 -0
- package/.docs/raw/docs/react-native/adapters.mdx +63 -87
- package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
- package/.docs/raw/docs/react-native/hooks.mdx +214 -232
- package/.docs/raw/docs/react-native/index.mdx +118 -159
- package/.docs/raw/docs/react-native/migration.mdx +144 -0
- package/.docs/raw/docs/react-native/primitives.mdx +431 -302
- package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +53 -0
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
- package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
- package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
- package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
- package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
- package/.docs/raw/docs/ui/context-display.mdx +147 -0
- package/.docs/raw/docs/ui/file.mdx +5 -4
- package/.docs/raw/docs/ui/image.mdx +5 -4
- package/.docs/raw/docs/ui/markdown.mdx +3 -1
- package/.docs/raw/docs/ui/model-selector.mdx +8 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
- package/.docs/raw/docs/ui/quote.mdx +210 -0
- package/.docs/raw/docs/ui/reasoning.mdx +12 -11
- package/.docs/raw/docs/ui/sources.mdx +88 -17
- package/.docs/raw/docs/ui/streamdown.mdx +16 -7
- package/.docs/raw/docs/ui/thread-list.mdx +11 -13
- package/.docs/raw/docs/ui/thread.mdx +28 -33
- package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
- package/.docs/raw/docs/ui/tool-group.mdx +9 -8
- package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
- package/package.json +4 -4
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
- package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
- /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
|
|
691
|
+
<SpanPrimitive.Children>
|
|
692
|
+
{() => <WaterfallRow />}
|
|
693
|
+
</SpanPrimitive.Children>
|
|
692
694
|
</div>
|
|
693
695
|
</WaterfallLayoutContext.Provider>
|
|
694
696
|
</div>
|
|
@@ -774,10 +776,10 @@ export default nextConfig;
|
|
|
774
776
|
"devDependencies": {
|
|
775
777
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
776
778
|
"@tailwindcss/postcss": "^4.2.1",
|
|
777
|
-
"@types/node": "^25.
|
|
779
|
+
"@types/node": "^25.5.0",
|
|
778
780
|
"@types/react": "^19.2.14",
|
|
779
781
|
"@types/react-dom": "^19.2.3",
|
|
780
|
-
"postcss": "^8.5.
|
|
782
|
+
"postcss": "^8.5.8",
|
|
781
783
|
"tailwindcss": "^4.2.1",
|
|
782
784
|
"typescript": "^5.9.3"
|
|
783
785
|
}
|
|
@@ -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
|
+
|