@assistant-ui/mcp-docs-server 0.1.19 → 0.1.21
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/with-ag-ui.md +172 -1633
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +42 -1640
- package/.docs/organized/code-examples/with-assistant-transport.md +40 -1743
- package/.docs/organized/code-examples/with-cloud.md +71 -1745
- package/.docs/organized/code-examples/with-custom-thread-list.md +87 -1723
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +70 -1637
- package/.docs/organized/code-examples/with-external-store.md +67 -1624
- package/.docs/organized/code-examples/with-ffmpeg.md +71 -1629
- package/.docs/organized/code-examples/with-langgraph.md +95 -1893
- package/.docs/organized/code-examples/with-parent-id-grouping.md +57 -1654
- package/.docs/organized/code-examples/with-react-hook-form.md +220 -2163
- package/.docs/organized/code-examples/with-react-router.md +66 -1318
- package/.docs/organized/code-examples/with-store.md +31 -31
- package/.docs/organized/code-examples/with-tanstack.md +77 -861
- package/.docs/organized/code-examples/with-tap-runtime.md +812 -0
- package/.docs/raw/docs/(docs)/cli.mdx +66 -0
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -1
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -1
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +4 -4
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +3 -3
- package/.docs/raw/docs/(docs)/devtools.mdx +0 -1
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +2 -3
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +117 -117
- package/.docs/raw/docs/(docs)/guides/suggestions.mdx +296 -0
- package/.docs/raw/docs/(docs)/guides/tools.mdx +336 -513
- package/.docs/raw/docs/(docs)/index.mdx +33 -410
- package/.docs/raw/docs/(docs)/installation.mdx +450 -0
- package/.docs/raw/docs/(docs)/llm.mdx +209 -0
- package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +48 -3
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +9 -3
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +20 -52
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +16 -39
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +49 -50
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +3 -11
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +0 -3
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +5 -16
- package/.docs/raw/docs/(reference)/api-reference/primitives/composition.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/error.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +152 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +28 -40
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +2 -3
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +1 -2
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +0 -1
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +1 -2
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -1
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +5 -5
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -1
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -1
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +207 -33
- package/.docs/raw/docs/(reference)/react-compatibility.mdx +0 -1
- package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +0 -1
- package/.docs/raw/docs/cloud/persistence/langgraph.mdx +0 -1
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +0 -1
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +118 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +198 -0
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +3 -3
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +5 -6
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +9 -11
- package/.docs/raw/docs/runtimes/custom/local.mdx +43 -36
- package/.docs/raw/docs/runtimes/data-stream.mdx +35 -3
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +1 -2
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +0 -1
- package/.docs/raw/docs/runtimes/langserve.mdx +0 -1
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -1
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -1
- package/.docs/raw/docs/ui/accordion.mdx +259 -0
- package/.docs/raw/docs/ui/assistant-modal.mdx +1 -3
- package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -3
- package/.docs/raw/docs/ui/attachment.mdx +0 -2
- package/.docs/raw/docs/ui/badge.mdx +138 -0
- package/.docs/raw/docs/ui/diff-viewer.mdx +279 -0
- package/.docs/raw/docs/ui/file.mdx +152 -0
- package/.docs/raw/docs/ui/image.mdx +100 -0
- package/.docs/raw/docs/ui/markdown.mdx +0 -1
- package/.docs/raw/docs/ui/mermaid.mdx +0 -1
- package/.docs/raw/docs/ui/model-selector.mdx +224 -0
- package/.docs/raw/docs/ui/part-grouping.mdx +4 -5
- package/.docs/raw/docs/ui/reasoning.mdx +6 -5
- package/.docs/raw/docs/ui/scrollbar.mdx +26 -9
- package/.docs/raw/docs/ui/select.mdx +245 -0
- package/.docs/raw/docs/ui/sources.mdx +6 -5
- package/.docs/raw/docs/ui/streamdown.mdx +348 -0
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +8 -63
- package/.docs/raw/docs/ui/tabs.mdx +259 -0
- package/.docs/raw/docs/ui/thread-list.mdx +98 -16
- package/.docs/raw/docs/ui/thread.mdx +57 -73
- package/.docs/raw/docs/ui/tool-fallback.mdx +0 -1
- package/.docs/raw/docs/ui/tool-group.mdx +1 -3
- package/README.md +3 -3
- package/package.json +4 -4
- package/src/tools/tests/examples.test.ts +1 -1
- package/.docs/raw/docs/(docs)/about-assistantui.mdx +0 -54
- package/.docs/raw/docs/(docs)/mcp-docs-server.mdx +0 -321
- package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +0 -219
|
@@ -18,6 +18,36 @@
|
|
|
18
18
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
## components.json
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
26
|
+
"style": "new-york",
|
|
27
|
+
"rsc": false,
|
|
28
|
+
"tsx": true,
|
|
29
|
+
"tailwind": {
|
|
30
|
+
"config": "",
|
|
31
|
+
"css": "src/styles.css",
|
|
32
|
+
"baseColor": "zinc",
|
|
33
|
+
"cssVariables": true,
|
|
34
|
+
"prefix": ""
|
|
35
|
+
},
|
|
36
|
+
"aliases": {
|
|
37
|
+
"components": "@/components",
|
|
38
|
+
"utils": "@/lib/utils",
|
|
39
|
+
"ui": "@/components/ui",
|
|
40
|
+
"lib": "@/lib",
|
|
41
|
+
"hooks": "@/hooks"
|
|
42
|
+
},
|
|
43
|
+
"iconLibrary": "lucide",
|
|
44
|
+
"registries": {
|
|
45
|
+
"@assistant-ui": "https://r.assistant-ui.com/{name}.json"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
|
|
21
51
|
## package.json
|
|
22
52
|
|
|
23
53
|
```json
|
|
@@ -37,26 +67,26 @@
|
|
|
37
67
|
"@radix-ui/react-slot": "^1.2.4",
|
|
38
68
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
39
69
|
"@tailwindcss/vite": "^4.1.18",
|
|
40
|
-
"@tanstack/react-router": "^1.
|
|
41
|
-
"@tanstack/react-start": "^1.
|
|
70
|
+
"@tanstack/react-router": "^1.158.0",
|
|
71
|
+
"@tanstack/react-start": "^1.158.0",
|
|
42
72
|
"class-variance-authority": "^0.7.1",
|
|
43
73
|
"clsx": "^2.1.1",
|
|
44
|
-
"lucide-react": "^0.
|
|
45
|
-
"nitro": "^3.0.1-alpha.
|
|
46
|
-
"openai": "^6.
|
|
47
|
-
"react": "^19.2.
|
|
48
|
-
"react-dom": "^19.2.
|
|
74
|
+
"lucide-react": "^0.563.0",
|
|
75
|
+
"nitro": "^3.0.1-alpha.2",
|
|
76
|
+
"openai": "^6.17.0",
|
|
77
|
+
"react": "^19.2.4",
|
|
78
|
+
"react-dom": "^19.2.4",
|
|
49
79
|
"remark-gfm": "^4.0.1",
|
|
50
80
|
"tailwind-merge": "^3.4.0",
|
|
51
81
|
"tailwindcss": "^4.1.18",
|
|
52
|
-
"vite-tsconfig-paths": "^6.0.
|
|
82
|
+
"vite-tsconfig-paths": "^6.0.5"
|
|
53
83
|
},
|
|
54
84
|
"devDependencies": {
|
|
55
85
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
56
|
-
"@types/node": "^25.0
|
|
57
|
-
"@types/react": "^19.2.
|
|
86
|
+
"@types/node": "^25.2.0",
|
|
87
|
+
"@types/react": "^19.2.10",
|
|
58
88
|
"@types/react-dom": "^19.2.3",
|
|
59
|
-
"@vitejs/plugin-react": "^5.1.
|
|
89
|
+
"@vitejs/plugin-react": "^5.1.3",
|
|
60
90
|
"typescript": "^5.9.3",
|
|
61
91
|
"vite": "^7.3.1"
|
|
62
92
|
}
|
|
@@ -64,741 +94,48 @@
|
|
|
64
94
|
|
|
65
95
|
```
|
|
66
96
|
|
|
67
|
-
##
|
|
97
|
+
## README.md
|
|
68
98
|
|
|
69
|
-
```
|
|
70
|
-
|
|
99
|
+
```markdown
|
|
100
|
+
# TanStack Start Integration
|
|
71
101
|
|
|
72
|
-
|
|
73
|
-
type CodeHeaderProps,
|
|
74
|
-
MarkdownTextPrimitive,
|
|
75
|
-
unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
|
|
76
|
-
useIsMarkdownCodeBlock,
|
|
77
|
-
} from "@assistant-ui/react-markdown";
|
|
78
|
-
import remarkGfm from "remark-gfm";
|
|
79
|
-
import { type FC, memo, useState } from "react";
|
|
80
|
-
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
81
|
-
|
|
82
|
-
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
83
|
-
import { cn } from "@/lib/utils";
|
|
84
|
-
|
|
85
|
-
const MarkdownTextImpl = () => {
|
|
86
|
-
return (
|
|
87
|
-
<MarkdownTextPrimitive
|
|
88
|
-
remarkPlugins={[remarkGfm]}
|
|
89
|
-
className="aui-md"
|
|
90
|
-
components={defaultComponents}
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
93
|
-
};
|
|
102
|
+
This example demonstrates how to use assistant-ui with TanStack Start (TanStack Router + Vite).
|
|
94
103
|
|
|
95
|
-
|
|
104
|
+
## Quick Start
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
const { isCopied, copyToClipboard } = useCopyToClipboard();
|
|
99
|
-
const onCopy = () => {
|
|
100
|
-
if (!code || isCopied) return;
|
|
101
|
-
copyToClipboard(code);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<div className="aui-code-header-root mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-muted-foreground/15 px-4 py-2 font-semibold text-foreground text-sm dark:bg-muted-foreground/20">
|
|
106
|
-
<span className="aui-code-header-language lowercase [&>span]:text-xs">
|
|
107
|
-
{language}
|
|
108
|
-
</span>
|
|
109
|
-
<TooltipIconButton tooltip="Copy" onClick={onCopy}>
|
|
110
|
-
{!isCopied && <CopyIcon />}
|
|
111
|
-
{isCopied && <CheckIcon />}
|
|
112
|
-
</TooltipIconButton>
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const useCopyToClipboard = ({
|
|
118
|
-
copiedDuration = 3000,
|
|
119
|
-
}: {
|
|
120
|
-
copiedDuration?: number;
|
|
121
|
-
} = {}) => {
|
|
122
|
-
const [isCopied, setIsCopied] = useState<boolean>(false);
|
|
123
|
-
|
|
124
|
-
const copyToClipboard = (value: string) => {
|
|
125
|
-
if (!value) return;
|
|
126
|
-
|
|
127
|
-
navigator.clipboard.writeText(value).then(() => {
|
|
128
|
-
setIsCopied(true);
|
|
129
|
-
setTimeout(() => setIsCopied(false), copiedDuration);
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
return { isCopied, copyToClipboard };
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const defaultComponents = memoizeMarkdownComponents({
|
|
137
|
-
h1: ({ className, ...props }) => (
|
|
138
|
-
<h1
|
|
139
|
-
className={cn(
|
|
140
|
-
"aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0",
|
|
141
|
-
className,
|
|
142
|
-
)}
|
|
143
|
-
{...props}
|
|
144
|
-
/>
|
|
145
|
-
),
|
|
146
|
-
h2: ({ className, ...props }) => (
|
|
147
|
-
<h2
|
|
148
|
-
className={cn(
|
|
149
|
-
"aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0",
|
|
150
|
-
className,
|
|
151
|
-
)}
|
|
152
|
-
{...props}
|
|
153
|
-
/>
|
|
154
|
-
),
|
|
155
|
-
h3: ({ className, ...props }) => (
|
|
156
|
-
<h3
|
|
157
|
-
className={cn(
|
|
158
|
-
"aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0",
|
|
159
|
-
className,
|
|
160
|
-
)}
|
|
161
|
-
{...props}
|
|
162
|
-
/>
|
|
163
|
-
),
|
|
164
|
-
h4: ({ className, ...props }) => (
|
|
165
|
-
<h4
|
|
166
|
-
className={cn(
|
|
167
|
-
"aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0",
|
|
168
|
-
className,
|
|
169
|
-
)}
|
|
170
|
-
{...props}
|
|
171
|
-
/>
|
|
172
|
-
),
|
|
173
|
-
h5: ({ className, ...props }) => (
|
|
174
|
-
<h5
|
|
175
|
-
className={cn(
|
|
176
|
-
"aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0",
|
|
177
|
-
className,
|
|
178
|
-
)}
|
|
179
|
-
{...props}
|
|
180
|
-
/>
|
|
181
|
-
),
|
|
182
|
-
h6: ({ className, ...props }) => (
|
|
183
|
-
<h6
|
|
184
|
-
className={cn(
|
|
185
|
-
"aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0",
|
|
186
|
-
className,
|
|
187
|
-
)}
|
|
188
|
-
{...props}
|
|
189
|
-
/>
|
|
190
|
-
),
|
|
191
|
-
p: ({ className, ...props }) => (
|
|
192
|
-
<p
|
|
193
|
-
className={cn(
|
|
194
|
-
"aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0",
|
|
195
|
-
className,
|
|
196
|
-
)}
|
|
197
|
-
{...props}
|
|
198
|
-
/>
|
|
199
|
-
),
|
|
200
|
-
a: ({ className, ...props }) => (
|
|
201
|
-
<a
|
|
202
|
-
className={cn(
|
|
203
|
-
"aui-md-a font-medium text-primary underline underline-offset-4",
|
|
204
|
-
className,
|
|
205
|
-
)}
|
|
206
|
-
{...props}
|
|
207
|
-
/>
|
|
208
|
-
),
|
|
209
|
-
blockquote: ({ className, ...props }) => (
|
|
210
|
-
<blockquote
|
|
211
|
-
className={cn("aui-md-blockquote border-l-2 pl-6 italic", className)}
|
|
212
|
-
{...props}
|
|
213
|
-
/>
|
|
214
|
-
),
|
|
215
|
-
ul: ({ className, ...props }) => (
|
|
216
|
-
<ul
|
|
217
|
-
className={cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className)}
|
|
218
|
-
{...props}
|
|
219
|
-
/>
|
|
220
|
-
),
|
|
221
|
-
ol: ({ className, ...props }) => (
|
|
222
|
-
<ol
|
|
223
|
-
className={cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className)}
|
|
224
|
-
{...props}
|
|
225
|
-
/>
|
|
226
|
-
),
|
|
227
|
-
hr: ({ className, ...props }) => (
|
|
228
|
-
<hr className={cn("aui-md-hr my-5 border-b", className)} {...props} />
|
|
229
|
-
),
|
|
230
|
-
table: ({ className, ...props }) => (
|
|
231
|
-
<table
|
|
232
|
-
className={cn(
|
|
233
|
-
"aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto",
|
|
234
|
-
className,
|
|
235
|
-
)}
|
|
236
|
-
{...props}
|
|
237
|
-
/>
|
|
238
|
-
),
|
|
239
|
-
th: ({ className, ...props }) => (
|
|
240
|
-
<th
|
|
241
|
-
className={cn(
|
|
242
|
-
"aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [[align=center]]:text-center [[align=right]]:text-right",
|
|
243
|
-
className,
|
|
244
|
-
)}
|
|
245
|
-
{...props}
|
|
246
|
-
/>
|
|
247
|
-
),
|
|
248
|
-
td: ({ className, ...props }) => (
|
|
249
|
-
<td
|
|
250
|
-
className={cn(
|
|
251
|
-
"aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right",
|
|
252
|
-
className,
|
|
253
|
-
)}
|
|
254
|
-
{...props}
|
|
255
|
-
/>
|
|
256
|
-
),
|
|
257
|
-
tr: ({ className, ...props }) => (
|
|
258
|
-
<tr
|
|
259
|
-
className={cn(
|
|
260
|
-
"aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
|
|
261
|
-
className,
|
|
262
|
-
)}
|
|
263
|
-
{...props}
|
|
264
|
-
/>
|
|
265
|
-
),
|
|
266
|
-
sup: ({ className, ...props }) => (
|
|
267
|
-
<sup
|
|
268
|
-
className={cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className)}
|
|
269
|
-
{...props}
|
|
270
|
-
/>
|
|
271
|
-
),
|
|
272
|
-
pre: ({ className, ...props }) => (
|
|
273
|
-
<pre
|
|
274
|
-
className={cn(
|
|
275
|
-
"aui-md-pre overflow-x-auto rounded-t-none! rounded-b-lg bg-black p-4 text-white",
|
|
276
|
-
className,
|
|
277
|
-
)}
|
|
278
|
-
{...props}
|
|
279
|
-
/>
|
|
280
|
-
),
|
|
281
|
-
code: function Code({ className, ...props }) {
|
|
282
|
-
const isCodeBlock = useIsMarkdownCodeBlock();
|
|
283
|
-
return (
|
|
284
|
-
<code
|
|
285
|
-
className={cn(
|
|
286
|
-
!isCodeBlock &&
|
|
287
|
-
"aui-md-inline-code rounded border bg-muted font-semibold",
|
|
288
|
-
className,
|
|
289
|
-
)}
|
|
290
|
-
{...props}
|
|
291
|
-
/>
|
|
292
|
-
);
|
|
293
|
-
},
|
|
294
|
-
CodeHeader,
|
|
295
|
-
});
|
|
106
|
+
### Using CLI (Recommended)
|
|
296
107
|
|
|
108
|
+
```bash
|
|
109
|
+
npx assistant-ui@latest create my-app --example with-tanstack
|
|
110
|
+
cd my-app
|
|
297
111
|
```
|
|
298
112
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
```tsx
|
|
302
|
-
import {
|
|
303
|
-
ArrowDownIcon,
|
|
304
|
-
ArrowUpIcon,
|
|
305
|
-
CheckIcon,
|
|
306
|
-
ChevronLeftIcon,
|
|
307
|
-
ChevronRightIcon,
|
|
308
|
-
CopyIcon,
|
|
309
|
-
PencilIcon,
|
|
310
|
-
RefreshCwIcon,
|
|
311
|
-
Square,
|
|
312
|
-
} from "lucide-react";
|
|
313
|
-
|
|
314
|
-
import {
|
|
315
|
-
ActionBarPrimitive,
|
|
316
|
-
AssistantIf,
|
|
317
|
-
BranchPickerPrimitive,
|
|
318
|
-
ComposerPrimitive,
|
|
319
|
-
ErrorPrimitive,
|
|
320
|
-
MessagePrimitive,
|
|
321
|
-
ThreadPrimitive,
|
|
322
|
-
} from "@assistant-ui/react";
|
|
323
|
-
|
|
324
|
-
import type { FC } from "react";
|
|
113
|
+
### Environment Variables
|
|
325
114
|
|
|
326
|
-
|
|
327
|
-
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
328
|
-
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
|
|
329
|
-
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
330
|
-
|
|
331
|
-
import { cn } from "@/lib/utils";
|
|
332
|
-
|
|
333
|
-
export const Thread: FC = () => {
|
|
334
|
-
return (
|
|
335
|
-
<ThreadPrimitive.Root
|
|
336
|
-
className="aui-root aui-thread-root @container flex h-full flex-col bg-background"
|
|
337
|
-
style={{
|
|
338
|
-
["--thread-max-width" as string]: "44rem",
|
|
339
|
-
}}
|
|
340
|
-
>
|
|
341
|
-
<ThreadPrimitive.Viewport
|
|
342
|
-
turnAnchor="top"
|
|
343
|
-
className="aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4"
|
|
344
|
-
>
|
|
345
|
-
<AssistantIf condition={({ thread }) => thread.isEmpty}>
|
|
346
|
-
<ThreadWelcome />
|
|
347
|
-
</AssistantIf>
|
|
348
|
-
|
|
349
|
-
<ThreadPrimitive.Messages
|
|
350
|
-
components={{
|
|
351
|
-
UserMessage,
|
|
352
|
-
EditComposer,
|
|
353
|
-
AssistantMessage,
|
|
354
|
-
}}
|
|
355
|
-
/>
|
|
356
|
-
|
|
357
|
-
<ThreadPrimitive.ViewportFooter className="aui-thread-viewport-footer sticky bottom-0 mx-auto mt-4 flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6">
|
|
358
|
-
<ThreadScrollToBottom />
|
|
359
|
-
<Composer />
|
|
360
|
-
</ThreadPrimitive.ViewportFooter>
|
|
361
|
-
</ThreadPrimitive.Viewport>
|
|
362
|
-
</ThreadPrimitive.Root>
|
|
363
|
-
);
|
|
364
|
-
};
|
|
365
|
-
|
|
366
|
-
const ThreadScrollToBottom: FC = () => {
|
|
367
|
-
return (
|
|
368
|
-
<ThreadPrimitive.ScrollToBottom asChild>
|
|
369
|
-
<TooltipIconButton
|
|
370
|
-
tooltip="Scroll to bottom"
|
|
371
|
-
variant="outline"
|
|
372
|
-
className="aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
|
|
373
|
-
>
|
|
374
|
-
<ArrowDownIcon />
|
|
375
|
-
</TooltipIconButton>
|
|
376
|
-
</ThreadPrimitive.ScrollToBottom>
|
|
377
|
-
);
|
|
378
|
-
};
|
|
379
|
-
|
|
380
|
-
const ThreadWelcome: FC = () => {
|
|
381
|
-
return (
|
|
382
|
-
<div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col">
|
|
383
|
-
<div className="aui-thread-welcome-center flex w-full grow flex-col items-center justify-center">
|
|
384
|
-
<div className="aui-thread-welcome-message flex size-full flex-col justify-center px-8">
|
|
385
|
-
<div className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-2 animate-in font-semibold text-2xl duration-300 ease-out">
|
|
386
|
-
Hello there!
|
|
387
|
-
</div>
|
|
388
|
-
<div className="aui-thread-welcome-message-inner fade-in slide-in-from-bottom-2 animate-in text-2xl text-muted-foreground/65 delay-100 duration-300 ease-out">
|
|
389
|
-
How can I help you today?
|
|
390
|
-
</div>
|
|
391
|
-
</div>
|
|
392
|
-
</div>
|
|
393
|
-
<ThreadSuggestions />
|
|
394
|
-
</div>
|
|
395
|
-
);
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
const ThreadSuggestions: FC = () => {
|
|
399
|
-
return (
|
|
400
|
-
<div className="aui-thread-welcome-suggestions grid w-full @md:grid-cols-2 gap-2 pb-4">
|
|
401
|
-
{[
|
|
402
|
-
{
|
|
403
|
-
title: "What's the weather",
|
|
404
|
-
label: "in San Francisco?",
|
|
405
|
-
action: "What's the weather in San Francisco?",
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
title: "Explain React hooks",
|
|
409
|
-
label: "like useState and useEffect",
|
|
410
|
-
action: "Explain React hooks like useState and useEffect",
|
|
411
|
-
},
|
|
412
|
-
{
|
|
413
|
-
title: "Write a SQL query",
|
|
414
|
-
label: "to find top customers",
|
|
415
|
-
action: "Write a SQL query to find top customers",
|
|
416
|
-
},
|
|
417
|
-
{
|
|
418
|
-
title: "Create a meal plan",
|
|
419
|
-
label: "for healthy weight loss",
|
|
420
|
-
action: "Create a meal plan for healthy weight loss",
|
|
421
|
-
},
|
|
422
|
-
].map((suggestedAction, index) => (
|
|
423
|
-
<div
|
|
424
|
-
key={`suggested-action-${suggestedAction.title}-${index}`}
|
|
425
|
-
className="aui-thread-welcome-suggestion-display fade-in slide-in-from-bottom-4 @md:nth-[n+3]:block nth-[n+3]:hidden animate-in fill-mode-both duration-300 ease-out"
|
|
426
|
-
style={{ animationDelay: `${index * 50}ms` }}
|
|
427
|
-
>
|
|
428
|
-
<ThreadPrimitive.Suggestion
|
|
429
|
-
prompt={suggestedAction.action}
|
|
430
|
-
send
|
|
431
|
-
asChild
|
|
432
|
-
>
|
|
433
|
-
<Button
|
|
434
|
-
variant="ghost"
|
|
435
|
-
className="aui-thread-welcome-suggestion h-auto w-full flex-1 @md:flex-col flex-wrap items-start justify-start gap-1 rounded-3xl border px-5 py-4 text-left text-sm dark:hover:bg-accent/60"
|
|
436
|
-
aria-label={suggestedAction.action}
|
|
437
|
-
>
|
|
438
|
-
<span className="aui-thread-welcome-suggestion-text-1 font-medium">
|
|
439
|
-
{suggestedAction.title}
|
|
440
|
-
</span>
|
|
441
|
-
<span className="aui-thread-welcome-suggestion-text-2 text-muted-foreground">
|
|
442
|
-
{suggestedAction.label}
|
|
443
|
-
</span>
|
|
444
|
-
</Button>
|
|
445
|
-
</ThreadPrimitive.Suggestion>
|
|
446
|
-
</div>
|
|
447
|
-
))}
|
|
448
|
-
</div>
|
|
449
|
-
);
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
const Composer: FC = () => {
|
|
453
|
-
return (
|
|
454
|
-
<ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
|
|
455
|
-
<div className="flex w-full flex-col rounded-3xl border border-input bg-background px-1 pt-2 shadow-xs outline-none transition-[color,box-shadow] has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-[3px] has-[textarea:focus-visible]:ring-ring/50 dark:bg-background">
|
|
456
|
-
<ComposerPrimitive.Input
|
|
457
|
-
placeholder="Send a message..."
|
|
458
|
-
className="aui-composer-input mb-1 max-h-32 min-h-16 w-full resize-none bg-transparent px-3.5 pt-1.5 pb-3 text-base outline-none placeholder:text-muted-foreground focus-visible:ring-0"
|
|
459
|
-
rows={1}
|
|
460
|
-
autoFocus
|
|
461
|
-
aria-label="Message input"
|
|
462
|
-
/>
|
|
463
|
-
<ComposerAction />
|
|
464
|
-
</div>
|
|
465
|
-
</ComposerPrimitive.Root>
|
|
466
|
-
);
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
const ComposerAction: FC = () => {
|
|
470
|
-
return (
|
|
471
|
-
<div className="aui-composer-action-wrapper relative mx-1 mt-2 mb-2 flex items-center justify-end">
|
|
472
|
-
<AssistantIf condition={({ thread }) => !thread.isRunning}>
|
|
473
|
-
<ComposerPrimitive.Send asChild>
|
|
474
|
-
<TooltipIconButton
|
|
475
|
-
tooltip="Send message"
|
|
476
|
-
side="bottom"
|
|
477
|
-
type="submit"
|
|
478
|
-
variant="default"
|
|
479
|
-
size="icon"
|
|
480
|
-
className="aui-composer-send size-[34px] rounded-full p-1"
|
|
481
|
-
aria-label="Send message"
|
|
482
|
-
>
|
|
483
|
-
<ArrowUpIcon className="aui-composer-send-icon size-5" />
|
|
484
|
-
</TooltipIconButton>
|
|
485
|
-
</ComposerPrimitive.Send>
|
|
486
|
-
</AssistantIf>
|
|
487
|
-
|
|
488
|
-
<AssistantIf condition={({ thread }) => thread.isRunning}>
|
|
489
|
-
<ComposerPrimitive.Cancel asChild>
|
|
490
|
-
<Button
|
|
491
|
-
type="button"
|
|
492
|
-
variant="default"
|
|
493
|
-
size="icon"
|
|
494
|
-
className="aui-composer-cancel size-[34px] rounded-full border border-muted-foreground/60 hover:bg-primary/75 dark:border-muted-foreground/90"
|
|
495
|
-
aria-label="Stop generating"
|
|
496
|
-
>
|
|
497
|
-
<Square className="aui-composer-cancel-icon size-3.5 fill-white dark:fill-black" />
|
|
498
|
-
</Button>
|
|
499
|
-
</ComposerPrimitive.Cancel>
|
|
500
|
-
</AssistantIf>
|
|
501
|
-
</div>
|
|
502
|
-
);
|
|
503
|
-
};
|
|
504
|
-
|
|
505
|
-
const MessageError: FC = () => {
|
|
506
|
-
return (
|
|
507
|
-
<MessagePrimitive.Error>
|
|
508
|
-
<ErrorPrimitive.Root className="aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200">
|
|
509
|
-
<ErrorPrimitive.Message className="aui-message-error-message line-clamp-2" />
|
|
510
|
-
</ErrorPrimitive.Root>
|
|
511
|
-
</MessagePrimitive.Error>
|
|
512
|
-
);
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
const AssistantMessage: FC = () => {
|
|
516
|
-
return (
|
|
517
|
-
<MessagePrimitive.Root
|
|
518
|
-
className="aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-4 duration-150 ease-out"
|
|
519
|
-
data-role="assistant"
|
|
520
|
-
>
|
|
521
|
-
<div className="aui-assistant-message-content wrap-break-word mx-2 text-foreground leading-7">
|
|
522
|
-
<MessagePrimitive.Parts
|
|
523
|
-
components={{
|
|
524
|
-
Text: MarkdownText,
|
|
525
|
-
tools: { Fallback: ToolFallback },
|
|
526
|
-
}}
|
|
527
|
-
/>
|
|
528
|
-
<MessageError />
|
|
529
|
-
</div>
|
|
530
|
-
|
|
531
|
-
<div className="aui-assistant-message-footer mt-2 ml-2 flex">
|
|
532
|
-
<BranchPicker />
|
|
533
|
-
<AssistantActionBar />
|
|
534
|
-
</div>
|
|
535
|
-
</MessagePrimitive.Root>
|
|
536
|
-
);
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
const AssistantActionBar: FC = () => {
|
|
540
|
-
return (
|
|
541
|
-
<ActionBarPrimitive.Root
|
|
542
|
-
hideWhenRunning
|
|
543
|
-
autohide="not-last"
|
|
544
|
-
autohideFloat="single-branch"
|
|
545
|
-
className="aui-assistant-action-bar-root col-start-3 row-start-2 -ml-1 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm"
|
|
546
|
-
>
|
|
547
|
-
<ActionBarPrimitive.Copy asChild>
|
|
548
|
-
<TooltipIconButton tooltip="Copy">
|
|
549
|
-
<AssistantIf condition={({ message }) => message.isCopied}>
|
|
550
|
-
<CheckIcon />
|
|
551
|
-
</AssistantIf>
|
|
552
|
-
<AssistantIf condition={({ message }) => !message.isCopied}>
|
|
553
|
-
<CopyIcon />
|
|
554
|
-
</AssistantIf>
|
|
555
|
-
</TooltipIconButton>
|
|
556
|
-
</ActionBarPrimitive.Copy>
|
|
557
|
-
<ActionBarPrimitive.Reload asChild>
|
|
558
|
-
<TooltipIconButton tooltip="Refresh">
|
|
559
|
-
<RefreshCwIcon />
|
|
560
|
-
</TooltipIconButton>
|
|
561
|
-
</ActionBarPrimitive.Reload>
|
|
562
|
-
</ActionBarPrimitive.Root>
|
|
563
|
-
);
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
const UserMessage: FC = () => {
|
|
567
|
-
return (
|
|
568
|
-
<MessagePrimitive.Root
|
|
569
|
-
className="aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto grid w-full max-w-(--thread-max-width) animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-4 duration-150 ease-out [&:where(>*)]:col-start-2"
|
|
570
|
-
data-role="user"
|
|
571
|
-
>
|
|
572
|
-
<div className="aui-user-message-content-wrapper relative col-start-2 min-w-0">
|
|
573
|
-
<div className="aui-user-message-content wrap-break-word rounded-3xl bg-muted px-5 py-2.5 text-foreground">
|
|
574
|
-
<MessagePrimitive.Parts />
|
|
575
|
-
</div>
|
|
576
|
-
<div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
|
|
577
|
-
<UserActionBar />
|
|
578
|
-
</div>
|
|
579
|
-
</div>
|
|
580
|
-
|
|
581
|
-
<BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
|
|
582
|
-
</MessagePrimitive.Root>
|
|
583
|
-
);
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
const UserActionBar: FC = () => {
|
|
587
|
-
return (
|
|
588
|
-
<ActionBarPrimitive.Root
|
|
589
|
-
hideWhenRunning
|
|
590
|
-
autohide="not-last"
|
|
591
|
-
className="aui-user-action-bar-root flex flex-col items-end"
|
|
592
|
-
>
|
|
593
|
-
<ActionBarPrimitive.Edit asChild>
|
|
594
|
-
<TooltipIconButton tooltip="Edit" className="aui-user-action-edit p-4">
|
|
595
|
-
<PencilIcon />
|
|
596
|
-
</TooltipIconButton>
|
|
597
|
-
</ActionBarPrimitive.Edit>
|
|
598
|
-
</ActionBarPrimitive.Root>
|
|
599
|
-
);
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
const EditComposer: FC = () => {
|
|
603
|
-
return (
|
|
604
|
-
<MessagePrimitive.Root className="aui-edit-composer-wrapper mx-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 px-2">
|
|
605
|
-
<ComposerPrimitive.Root className="aui-edit-composer-root ml-auto flex w-full max-w-7/8 flex-col rounded-xl bg-muted">
|
|
606
|
-
<ComposerPrimitive.Input
|
|
607
|
-
className="aui-edit-composer-input flex min-h-[60px] w-full resize-none bg-transparent p-4 text-foreground outline-none"
|
|
608
|
-
autoFocus
|
|
609
|
-
/>
|
|
610
|
-
|
|
611
|
-
<div className="aui-edit-composer-footer mx-3 mb-3 flex items-center justify-center gap-2 self-end">
|
|
612
|
-
<ComposerPrimitive.Cancel asChild>
|
|
613
|
-
<Button variant="ghost" size="sm" aria-label="Cancel edit">
|
|
614
|
-
Cancel
|
|
615
|
-
</Button>
|
|
616
|
-
</ComposerPrimitive.Cancel>
|
|
617
|
-
<ComposerPrimitive.Send asChild>
|
|
618
|
-
<Button size="sm" aria-label="Update message">
|
|
619
|
-
Update
|
|
620
|
-
</Button>
|
|
621
|
-
</ComposerPrimitive.Send>
|
|
622
|
-
</div>
|
|
623
|
-
</ComposerPrimitive.Root>
|
|
624
|
-
</MessagePrimitive.Root>
|
|
625
|
-
);
|
|
626
|
-
};
|
|
627
|
-
|
|
628
|
-
const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
|
629
|
-
className,
|
|
630
|
-
...rest
|
|
631
|
-
}) => {
|
|
632
|
-
return (
|
|
633
|
-
<BranchPickerPrimitive.Root
|
|
634
|
-
hideWhenSingleBranch
|
|
635
|
-
className={cn(
|
|
636
|
-
"aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
|
|
637
|
-
className,
|
|
638
|
-
)}
|
|
639
|
-
{...rest}
|
|
640
|
-
>
|
|
641
|
-
<BranchPickerPrimitive.Previous asChild>
|
|
642
|
-
<TooltipIconButton tooltip="Previous">
|
|
643
|
-
<ChevronLeftIcon />
|
|
644
|
-
</TooltipIconButton>
|
|
645
|
-
</BranchPickerPrimitive.Previous>
|
|
646
|
-
<span className="aui-branch-picker-state font-medium">
|
|
647
|
-
<BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
|
|
648
|
-
</span>
|
|
649
|
-
<BranchPickerPrimitive.Next asChild>
|
|
650
|
-
<TooltipIconButton tooltip="Next">
|
|
651
|
-
<ChevronRightIcon />
|
|
652
|
-
</TooltipIconButton>
|
|
653
|
-
</BranchPickerPrimitive.Next>
|
|
654
|
-
</BranchPickerPrimitive.Root>
|
|
655
|
-
);
|
|
656
|
-
};
|
|
115
|
+
Create `.env`:
|
|
657
116
|
|
|
117
|
+
```
|
|
118
|
+
OPENAI_API_KEY=sk-...
|
|
658
119
|
```
|
|
659
120
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
```tsx
|
|
663
|
-
import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
|
|
664
|
-
import {
|
|
665
|
-
CheckIcon,
|
|
666
|
-
ChevronDownIcon,
|
|
667
|
-
ChevronUpIcon,
|
|
668
|
-
XCircleIcon,
|
|
669
|
-
} from "lucide-react";
|
|
670
|
-
import { useState } from "react";
|
|
671
|
-
import { Button } from "@/components/ui/button";
|
|
672
|
-
import { cn } from "@/lib/utils";
|
|
673
|
-
|
|
674
|
-
export const ToolFallback: ToolCallMessagePartComponent = ({
|
|
675
|
-
toolName,
|
|
676
|
-
argsText,
|
|
677
|
-
result,
|
|
678
|
-
status,
|
|
679
|
-
}) => {
|
|
680
|
-
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
681
|
-
|
|
682
|
-
const isCancelled =
|
|
683
|
-
status?.type === "incomplete" && status.reason === "cancelled";
|
|
684
|
-
const cancelledReason =
|
|
685
|
-
isCancelled && status.error
|
|
686
|
-
? typeof status.error === "string"
|
|
687
|
-
? status.error
|
|
688
|
-
: JSON.stringify(status.error)
|
|
689
|
-
: null;
|
|
690
|
-
|
|
691
|
-
return (
|
|
692
|
-
<div
|
|
693
|
-
className={cn(
|
|
694
|
-
"aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
|
|
695
|
-
isCancelled && "border-muted-foreground/30 bg-muted/30",
|
|
696
|
-
)}
|
|
697
|
-
>
|
|
698
|
-
<div className="aui-tool-fallback-header flex items-center gap-2 px-4">
|
|
699
|
-
{isCancelled ? (
|
|
700
|
-
<XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
|
|
701
|
-
) : (
|
|
702
|
-
<CheckIcon className="aui-tool-fallback-icon size-4" />
|
|
703
|
-
)}
|
|
704
|
-
<p
|
|
705
|
-
className={cn(
|
|
706
|
-
"aui-tool-fallback-title grow",
|
|
707
|
-
isCancelled && "text-muted-foreground line-through",
|
|
708
|
-
)}
|
|
709
|
-
>
|
|
710
|
-
{isCancelled ? "Cancelled tool: " : "Used tool: "}
|
|
711
|
-
<b>{toolName}</b>
|
|
712
|
-
</p>
|
|
713
|
-
<Button onClick={() => setIsCollapsed(!isCollapsed)}>
|
|
714
|
-
{isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
|
715
|
-
</Button>
|
|
716
|
-
</div>
|
|
717
|
-
{!isCollapsed && (
|
|
718
|
-
<div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
|
|
719
|
-
{cancelledReason && (
|
|
720
|
-
<div className="aui-tool-fallback-cancelled-root px-4">
|
|
721
|
-
<p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
|
|
722
|
-
Cancelled reason:
|
|
723
|
-
</p>
|
|
724
|
-
<p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
|
|
725
|
-
{cancelledReason}
|
|
726
|
-
</p>
|
|
727
|
-
</div>
|
|
728
|
-
)}
|
|
729
|
-
<div
|
|
730
|
-
className={cn(
|
|
731
|
-
"aui-tool-fallback-args-root px-4",
|
|
732
|
-
isCancelled && "opacity-60",
|
|
733
|
-
)}
|
|
734
|
-
>
|
|
735
|
-
<pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
|
|
736
|
-
{argsText}
|
|
737
|
-
</pre>
|
|
738
|
-
</div>
|
|
739
|
-
{!isCancelled && result !== undefined && (
|
|
740
|
-
<div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
|
|
741
|
-
<p className="aui-tool-fallback-result-header font-semibold">
|
|
742
|
-
Result:
|
|
743
|
-
</p>
|
|
744
|
-
<pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
|
|
745
|
-
{typeof result === "string"
|
|
746
|
-
? result
|
|
747
|
-
: JSON.stringify(result, null, 2)}
|
|
748
|
-
</pre>
|
|
749
|
-
</div>
|
|
750
|
-
)}
|
|
751
|
-
</div>
|
|
752
|
-
)}
|
|
753
|
-
</div>
|
|
754
|
-
);
|
|
755
|
-
};
|
|
121
|
+
### Run
|
|
756
122
|
|
|
123
|
+
```bash
|
|
124
|
+
npm install
|
|
125
|
+
npm run dev
|
|
757
126
|
```
|
|
758
127
|
|
|
759
|
-
##
|
|
128
|
+
## Features
|
|
760
129
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
130
|
+
- TanStack Start (TanStack Router + Vite)
|
|
131
|
+
- Full-stack React with server functions
|
|
132
|
+
- OpenAI streaming chat
|
|
133
|
+
- Markdown message rendering
|
|
764
134
|
|
|
765
|
-
|
|
766
|
-
Tooltip,
|
|
767
|
-
TooltipContent,
|
|
768
|
-
TooltipTrigger,
|
|
769
|
-
} from "@/components/ui/tooltip";
|
|
770
|
-
import { Button } from "@/components/ui/button";
|
|
771
|
-
import { cn } from "@/lib/utils";
|
|
772
|
-
|
|
773
|
-
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
774
|
-
tooltip: string;
|
|
775
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
776
|
-
};
|
|
135
|
+
## Related Documentation
|
|
777
136
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
TooltipIconButtonProps
|
|
781
|
-
>(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
|
|
782
|
-
return (
|
|
783
|
-
<Tooltip>
|
|
784
|
-
<TooltipTrigger asChild>
|
|
785
|
-
<Button
|
|
786
|
-
variant="ghost"
|
|
787
|
-
size="icon"
|
|
788
|
-
{...rest}
|
|
789
|
-
className={cn("aui-button-icon size-6 p-1", className)}
|
|
790
|
-
ref={ref}
|
|
791
|
-
>
|
|
792
|
-
<Slottable>{children}</Slottable>
|
|
793
|
-
<span className="aui-sr-only sr-only">{tooltip}</span>
|
|
794
|
-
</Button>
|
|
795
|
-
</TooltipTrigger>
|
|
796
|
-
<TooltipContent side={side}>{tooltip}</TooltipContent>
|
|
797
|
-
</Tooltip>
|
|
798
|
-
);
|
|
799
|
-
});
|
|
800
|
-
|
|
801
|
-
TooltipIconButton.displayName = "TooltipIconButton";
|
|
137
|
+
- [assistant-ui Documentation](https://www.assistant-ui.com/docs)
|
|
138
|
+
- [TanStack Start Documentation](https://tanstack.com/start)
|
|
802
139
|
|
|
803
140
|
```
|
|
804
141
|
|
|
@@ -912,136 +249,6 @@ export function MyRuntimeProvider({
|
|
|
912
249
|
|
|
913
250
|
```
|
|
914
251
|
|
|
915
|
-
## src/components/ui/button.tsx
|
|
916
|
-
|
|
917
|
-
```tsx
|
|
918
|
-
import * as React from "react";
|
|
919
|
-
import { Slot } from "@radix-ui/react-slot";
|
|
920
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
921
|
-
|
|
922
|
-
import { cn } from "@/lib/utils";
|
|
923
|
-
|
|
924
|
-
const buttonVariants = cva(
|
|
925
|
-
"inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
926
|
-
{
|
|
927
|
-
variants: {
|
|
928
|
-
variant: {
|
|
929
|
-
default:
|
|
930
|
-
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
931
|
-
destructive:
|
|
932
|
-
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
|
933
|
-
outline:
|
|
934
|
-
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
935
|
-
secondary:
|
|
936
|
-
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
937
|
-
ghost:
|
|
938
|
-
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
939
|
-
link: "text-primary underline-offset-4 hover:underline",
|
|
940
|
-
},
|
|
941
|
-
size: {
|
|
942
|
-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
943
|
-
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
|
944
|
-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
945
|
-
icon: "size-9",
|
|
946
|
-
},
|
|
947
|
-
},
|
|
948
|
-
defaultVariants: {
|
|
949
|
-
variant: "default",
|
|
950
|
-
size: "default",
|
|
951
|
-
},
|
|
952
|
-
},
|
|
953
|
-
);
|
|
954
|
-
|
|
955
|
-
function Button({
|
|
956
|
-
className,
|
|
957
|
-
variant,
|
|
958
|
-
size,
|
|
959
|
-
asChild = false,
|
|
960
|
-
...props
|
|
961
|
-
}: React.ComponentProps<"button"> &
|
|
962
|
-
VariantProps<typeof buttonVariants> & {
|
|
963
|
-
asChild?: boolean;
|
|
964
|
-
}) {
|
|
965
|
-
const Comp = asChild ? Slot : "button";
|
|
966
|
-
|
|
967
|
-
return (
|
|
968
|
-
<Comp
|
|
969
|
-
data-slot="button"
|
|
970
|
-
className={cn(buttonVariants({ variant, size, className }))}
|
|
971
|
-
{...props}
|
|
972
|
-
/>
|
|
973
|
-
);
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
export { Button, buttonVariants };
|
|
977
|
-
|
|
978
|
-
```
|
|
979
|
-
|
|
980
|
-
## src/components/ui/tooltip.tsx
|
|
981
|
-
|
|
982
|
-
```tsx
|
|
983
|
-
import * as React from "react";
|
|
984
|
-
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
985
|
-
|
|
986
|
-
import { cn } from "@/lib/utils";
|
|
987
|
-
|
|
988
|
-
function TooltipProvider({
|
|
989
|
-
delayDuration = 0,
|
|
990
|
-
...props
|
|
991
|
-
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
992
|
-
return (
|
|
993
|
-
<TooltipPrimitive.Provider
|
|
994
|
-
data-slot="tooltip-provider"
|
|
995
|
-
delayDuration={delayDuration}
|
|
996
|
-
{...props}
|
|
997
|
-
/>
|
|
998
|
-
);
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
function Tooltip({
|
|
1002
|
-
...props
|
|
1003
|
-
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
1004
|
-
return (
|
|
1005
|
-
<TooltipProvider>
|
|
1006
|
-
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
1007
|
-
</TooltipProvider>
|
|
1008
|
-
);
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
function TooltipTrigger({
|
|
1012
|
-
...props
|
|
1013
|
-
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
1014
|
-
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
function TooltipContent({
|
|
1018
|
-
className,
|
|
1019
|
-
sideOffset = 0,
|
|
1020
|
-
children,
|
|
1021
|
-
...props
|
|
1022
|
-
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
|
1023
|
-
return (
|
|
1024
|
-
<TooltipPrimitive.Portal>
|
|
1025
|
-
<TooltipPrimitive.Content
|
|
1026
|
-
data-slot="tooltip-content"
|
|
1027
|
-
sideOffset={sideOffset}
|
|
1028
|
-
className={cn(
|
|
1029
|
-
"fade-in-0 zoom-in-95 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in text-balance rounded-md bg-primary px-3 py-1.5 text-primary-foreground text-xs data-[state=closed]:animate-out",
|
|
1030
|
-
className,
|
|
1031
|
-
)}
|
|
1032
|
-
{...props}
|
|
1033
|
-
>
|
|
1034
|
-
{children}
|
|
1035
|
-
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
|
|
1036
|
-
</TooltipPrimitive.Content>
|
|
1037
|
-
</TooltipPrimitive.Portal>
|
|
1038
|
-
);
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
1042
|
-
|
|
1043
|
-
```
|
|
1044
|
-
|
|
1045
252
|
## src/lib/utils.ts
|
|
1046
253
|
|
|
1047
254
|
```typescript
|
|
@@ -1262,6 +469,8 @@ export const chatStream = createServerFn({ method: "POST" })
|
|
|
1262
469
|
```css
|
|
1263
470
|
@import "tailwindcss";
|
|
1264
471
|
|
|
472
|
+
@source "../../../packages/ui/src";
|
|
473
|
+
|
|
1265
474
|
@custom-variant dark (&:is(.dark *));
|
|
1266
475
|
|
|
1267
476
|
@theme inline {
|
|
@@ -1520,7 +729,14 @@ export const chatStream = createServerFn({ method: "POST" })
|
|
|
1520
729
|
"extends": "@assistant-ui/x-buildutils/ts/base",
|
|
1521
730
|
"compilerOptions": {
|
|
1522
731
|
"types": ["vite/client"],
|
|
1523
|
-
"paths": {
|
|
732
|
+
"paths": {
|
|
733
|
+
"@/*": ["./src/*"],
|
|
734
|
+
"@/components/assistant-ui/*": [
|
|
735
|
+
"../../packages/ui/src/components/assistant-ui/*"
|
|
736
|
+
],
|
|
737
|
+
"@/components/ui/*": ["../../packages/ui/src/components/ui/*"],
|
|
738
|
+
"@assistant-ui/ui/*": ["../../packages/ui/src/*"]
|
|
739
|
+
}
|
|
1524
740
|
},
|
|
1525
741
|
"include": ["**/*.ts", "**/*.tsx"],
|
|
1526
742
|
"exclude": ["node_modules"]
|
|
@@ -1546,7 +762,7 @@ const config = defineConfig({
|
|
|
1546
762
|
},
|
|
1547
763
|
}),
|
|
1548
764
|
viteTsConfigPaths({
|
|
1549
|
-
projects: ["./tsconfig.json"],
|
|
765
|
+
projects: ["./tsconfig.json", "../../packages/ui/tsconfig.json"],
|
|
1550
766
|
}),
|
|
1551
767
|
tailwindcss(),
|
|
1552
768
|
tanstackStart(),
|