@assistant-ui/mcp-docs-server 0.1.9 → 0.1.11
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-ai-sdk-v5.md +26 -26
- package/.docs/organized/code-examples/with-assistant-transport.md +29 -29
- package/.docs/organized/code-examples/with-cloud.md +21 -21
- package/.docs/organized/code-examples/with-external-store.md +18 -18
- package/.docs/organized/code-examples/with-ffmpeg.md +22 -22
- package/.docs/organized/code-examples/with-langgraph.md +35 -120
- package/.docs/organized/code-examples/with-parent-id-grouping.md +18 -18
- package/.docs/organized/code-examples/with-react-hook-form.md +27 -27
- package/.docs/raw/docs/api-reference/primitives/Thread.mdx +40 -8
- package/.docs/raw/docs/cloud/persistence/langgraph.mdx +64 -68
- package/.docs/raw/docs/getting-started.mdx +541 -152
- package/.docs/raw/docs/guides/Attachments.mdx +21 -0
- package/.docs/raw/docs/guides/ToolUI.mdx +112 -37
- package/.docs/raw/docs/guides/Tools.mdx +170 -6
- package/.docs/raw/docs/migrations/react-langgraph-v0-7.mdx +324 -0
- package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +2 -2
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +218 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +31 -24
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +55 -20
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +8 -3
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +1 -1
- package/.docs/raw/docs/ui/AssistantModal.mdx +21 -0
- package/.docs/raw/docs/ui/AssistantSidebar.mdx +21 -0
- package/.docs/raw/docs/ui/Attachment.mdx +21 -0
- package/.docs/raw/docs/ui/Markdown.mdx +22 -1
- package/.docs/raw/docs/ui/Mermaid.mdx +22 -1
- package/.docs/raw/docs/ui/SyntaxHighlighting.mdx +43 -2
- package/.docs/raw/docs/ui/Thread.mdx +374 -5
- package/.docs/raw/docs/ui/ThreadList.mdx +48 -2
- package/.docs/raw/docs/ui/ToolFallback.mdx +21 -0
- package/package.json +7 -7
- package/.docs/raw/docs/migrations/v0-7.mdx +0 -188
- package/.docs/raw/docs/migrations/v0-8.mdx +0 -160
- package/.docs/raw/docs/migrations/v0-9.mdx +0 -75
- package/.docs/raw/docs/ui/primitives/Thread.mdx +0 -197
|
@@ -444,7 +444,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
444
444
|
h2: ({ className, ...props }) => (
|
|
445
445
|
<h2
|
|
446
446
|
className={cn(
|
|
447
|
-
"mb-4
|
|
447
|
+
"mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
448
448
|
className,
|
|
449
449
|
)}
|
|
450
450
|
{...props}
|
|
@@ -453,7 +453,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
453
453
|
h3: ({ className, ...props }) => (
|
|
454
454
|
<h3
|
|
455
455
|
className={cn(
|
|
456
|
-
"mb-4
|
|
456
|
+
"mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
457
457
|
className,
|
|
458
458
|
)}
|
|
459
459
|
{...props}
|
|
@@ -462,7 +462,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
462
462
|
h4: ({ className, ...props }) => (
|
|
463
463
|
<h4
|
|
464
464
|
className={cn(
|
|
465
|
-
"mb-4
|
|
465
|
+
"mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
|
|
466
466
|
className,
|
|
467
467
|
)}
|
|
468
468
|
{...props}
|
|
@@ -485,7 +485,7 @@ const defaultComponents = memoizeMarkdownComponents({
|
|
|
485
485
|
),
|
|
486
486
|
p: ({ className, ...props }) => (
|
|
487
487
|
<p
|
|
488
|
-
className={cn("
|
|
488
|
+
className={cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className)}
|
|
489
489
|
{...props}
|
|
490
490
|
/>
|
|
491
491
|
),
|
|
@@ -682,7 +682,7 @@ const ThreadWelcomeSuggestions: FC = () => {
|
|
|
682
682
|
method="replace"
|
|
683
683
|
autoSend
|
|
684
684
|
>
|
|
685
|
-
<span className="line-clamp-2 text-
|
|
685
|
+
<span className="line-clamp-2 text-sm font-semibold text-ellipsis">
|
|
686
686
|
What is the weather in Tokyo?
|
|
687
687
|
</span>
|
|
688
688
|
</ThreadPrimitive.Suggestion>
|
|
@@ -692,7 +692,7 @@ const ThreadWelcomeSuggestions: FC = () => {
|
|
|
692
692
|
method="replace"
|
|
693
693
|
autoSend
|
|
694
694
|
>
|
|
695
|
-
<span className="line-clamp-2 text-
|
|
695
|
+
<span className="line-clamp-2 text-sm font-semibold text-ellipsis">
|
|
696
696
|
What is assistant-ui?
|
|
697
697
|
</span>
|
|
698
698
|
</ThreadPrimitive.Suggestion>
|
|
@@ -748,7 +748,7 @@ const UserMessage: FC = () => {
|
|
|
748
748
|
<MessagePrimitive.Root className="grid w-full max-w-[var(--thread-max-width)] auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 py-4 [&:where(>*)]:col-start-2">
|
|
749
749
|
<UserActionBar />
|
|
750
750
|
|
|
751
|
-
<div className="bg-muted text-foreground col-start-2 row-start-2 max-w-[calc(var(--thread-max-width)*0.8)]
|
|
751
|
+
<div className="bg-muted text-foreground col-start-2 row-start-2 max-w-[calc(var(--thread-max-width)*0.8)] rounded-3xl px-5 py-2.5 break-words">
|
|
752
752
|
<MessagePrimitive.Parts />
|
|
753
753
|
</div>
|
|
754
754
|
|
|
@@ -762,7 +762,7 @@ const UserActionBar: FC = () => {
|
|
|
762
762
|
<ActionBarPrimitive.Root
|
|
763
763
|
hideWhenRunning
|
|
764
764
|
autohide="not-last"
|
|
765
|
-
className="col-start-1 row-start-2
|
|
765
|
+
className="col-start-1 row-start-2 mt-2.5 mr-3 flex flex-col items-end"
|
|
766
766
|
>
|
|
767
767
|
<ActionBarPrimitive.Edit asChild>
|
|
768
768
|
<TooltipIconButton tooltip="Edit">
|
|
@@ -793,13 +793,13 @@ const EditComposer: FC = () => {
|
|
|
793
793
|
const AssistantMessage: FC = () => {
|
|
794
794
|
return (
|
|
795
795
|
<MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
|
|
796
|
-
<div className="text-foreground col-span-2 col-start-2 row-start-1 my-1.5 max-w-[calc(var(--thread-max-width)*0.8)] break-words
|
|
796
|
+
<div className="text-foreground col-span-2 col-start-2 row-start-1 my-1.5 max-w-[calc(var(--thread-max-width)*0.8)] leading-7 break-words">
|
|
797
797
|
<MessagePrimitive.Parts components={{ Text: MarkdownText }} />
|
|
798
798
|
</div>
|
|
799
799
|
|
|
800
800
|
<AssistantActionBar />
|
|
801
801
|
|
|
802
|
-
<BranchPicker className="col-start-2 row-start-2 -
|
|
802
|
+
<BranchPicker className="col-start-2 row-start-2 mr-2 -ml-2" />
|
|
803
803
|
</MessagePrimitive.Root>
|
|
804
804
|
);
|
|
805
805
|
};
|
|
@@ -1326,7 +1326,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
|
1326
1326
|
type={type}
|
|
1327
1327
|
data-slot="input"
|
|
1328
1328
|
className={cn(
|
|
1329
|
-
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input
|
|
1329
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1330
1330
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
1331
1331
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
1332
1332
|
className,
|
|
@@ -1358,7 +1358,7 @@ function Label({
|
|
|
1358
1358
|
<LabelPrimitive.Root
|
|
1359
1359
|
data-slot="label"
|
|
1360
1360
|
className={cn(
|
|
1361
|
-
"flex
|
|
1361
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
1362
1362
|
className,
|
|
1363
1363
|
)}
|
|
1364
1364
|
{...props}
|
|
@@ -1414,13 +1414,13 @@ function ResizableHandle({
|
|
|
1414
1414
|
<ResizablePrimitive.PanelResizeHandle
|
|
1415
1415
|
data-slot="resizable-handle"
|
|
1416
1416
|
className={cn(
|
|
1417
|
-
"bg-border focus-visible:ring-ring
|
|
1417
|
+
"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
|
1418
1418
|
className,
|
|
1419
1419
|
)}
|
|
1420
1420
|
{...props}
|
|
1421
1421
|
>
|
|
1422
1422
|
{withHandle && (
|
|
1423
|
-
<div className="bg-border
|
|
1423
|
+
<div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
|
|
1424
1424
|
<GripVerticalIcon className="size-2.5" />
|
|
1425
1425
|
</div>
|
|
1426
1426
|
)}
|
|
@@ -1479,7 +1479,7 @@ function TabsTrigger({
|
|
|
1479
1479
|
<TabsPrimitive.Trigger
|
|
1480
1480
|
data-slot="tabs-trigger"
|
|
1481
1481
|
className={cn(
|
|
1482
|
-
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5
|
|
1482
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1483
1483
|
className,
|
|
1484
1484
|
)}
|
|
1485
1485
|
{...props}
|
|
@@ -1555,7 +1555,7 @@ function TooltipContent({
|
|
|
1555
1555
|
data-slot="tooltip-content"
|
|
1556
1556
|
sideOffset={sideOffset}
|
|
1557
1557
|
className={cn(
|
|
1558
|
-
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out 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]
|
|
1558
|
+
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out 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] rounded-md px-3 py-1.5 text-xs text-balance",
|
|
1559
1559
|
className,
|
|
1560
1560
|
)}
|
|
1561
1561
|
{...props}
|
|
@@ -1647,7 +1647,7 @@ export default nextConfig;
|
|
|
1647
1647
|
"lint": "eslint ."
|
|
1648
1648
|
},
|
|
1649
1649
|
"dependencies": {
|
|
1650
|
-
"@ai-sdk/openai": "^2.0.
|
|
1650
|
+
"@ai-sdk/openai": "^2.0.52",
|
|
1651
1651
|
"@assistant-ui/react": "workspace:*",
|
|
1652
1652
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1653
1653
|
"@assistant-ui/react-hook-form": "workspace:*",
|
|
@@ -1660,20 +1660,20 @@ export default nextConfig;
|
|
|
1660
1660
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
1661
1661
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1662
1662
|
"@react-hook/media-query": "^1.1.1",
|
|
1663
|
-
"ai": "^5.0.
|
|
1663
|
+
"ai": "^5.0.76",
|
|
1664
1664
|
"class-variance-authority": "^0.7.1",
|
|
1665
1665
|
"clsx": "^2.1.1",
|
|
1666
1666
|
"json-schema-to-zod": "^2.6.1",
|
|
1667
|
-
"lucide-react": "^0.
|
|
1668
|
-
"next": "15.5.
|
|
1669
|
-
"react": "19.
|
|
1670
|
-
"react-dom": "19.
|
|
1671
|
-
"react-hook-form": "^7.
|
|
1667
|
+
"lucide-react": "^0.546.0",
|
|
1668
|
+
"next": "15.5.6",
|
|
1669
|
+
"react": "19.2.0",
|
|
1670
|
+
"react-dom": "19.2.0",
|
|
1671
|
+
"react-hook-form": "^7.65.0",
|
|
1672
1672
|
"react-resizable-panels": "^3.0.6",
|
|
1673
1673
|
"remark-gfm": "^4.0.1",
|
|
1674
1674
|
"tailwind-merge": "^3.3.1",
|
|
1675
1675
|
"tw-animate-css": "^1.4.0",
|
|
1676
|
-
"zod": "^4.1.
|
|
1676
|
+
"zod": "^4.1.12",
|
|
1677
1677
|
"zustand": "^5.0.8"
|
|
1678
1678
|
},
|
|
1679
1679
|
"devDependencies": {
|
|
@@ -1682,10 +1682,10 @@ export default nextConfig;
|
|
|
1682
1682
|
"@types/react": "^19",
|
|
1683
1683
|
"@types/react-dom": "^19",
|
|
1684
1684
|
"eslint": "^9",
|
|
1685
|
-
"eslint-config-next": "15.5.
|
|
1685
|
+
"eslint-config-next": "15.5.6",
|
|
1686
1686
|
"postcss": "^8",
|
|
1687
|
-
"tailwindcss": "^4.1.
|
|
1688
|
-
"typescript": "^5.9.
|
|
1687
|
+
"tailwindcss": "^4.1.14",
|
|
1688
|
+
"typescript": "^5.9.3"
|
|
1689
1689
|
}
|
|
1690
1690
|
}
|
|
1691
1691
|
|
|
@@ -195,8 +195,7 @@ const Suggestion = () => {
|
|
|
195
195
|
return (
|
|
196
196
|
<ThreadPrimitive.Suggestion
|
|
197
197
|
prompt="I need help with product search"
|
|
198
|
-
|
|
199
|
-
autoSend
|
|
198
|
+
send
|
|
200
199
|
/>
|
|
201
200
|
);
|
|
202
201
|
};
|
|
@@ -211,17 +210,29 @@ const Suggestion = () => {
|
|
|
211
210
|
description: "The suggestion's prompt.",
|
|
212
211
|
},
|
|
213
212
|
{
|
|
214
|
-
name: "
|
|
215
|
-
type: "
|
|
213
|
+
name: "send",
|
|
214
|
+
type: "boolean",
|
|
216
215
|
description:
|
|
217
|
-
"
|
|
216
|
+
"When true, automatically sends the message. When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`",
|
|
218
217
|
},
|
|
219
218
|
{
|
|
220
|
-
name: "
|
|
219
|
+
name: "clearComposer",
|
|
221
220
|
type: "boolean",
|
|
221
|
+
default: "true",
|
|
222
222
|
description:
|
|
223
|
-
"Whether to
|
|
224
|
-
|
|
223
|
+
"Whether to clear the composer after sending. When send is set to false, determines if composer text is replaced with suggestion (true, default), or if the suggestion's prompt is appended to the composer text (false).",
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: "autoSend",
|
|
227
|
+
type: "boolean",
|
|
228
|
+
deprecated: true,
|
|
229
|
+
description: "Deprecated. Use 'send' instead.",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "method",
|
|
233
|
+
type: "'replace'",
|
|
234
|
+
deprecated: true,
|
|
235
|
+
description: "Deprecated. This parameter is no longer used.",
|
|
225
236
|
},
|
|
226
237
|
]}
|
|
227
238
|
/>
|
|
@@ -243,6 +254,21 @@ Renders children if a condition is met.
|
|
|
243
254
|
type: "boolean | undefined",
|
|
244
255
|
description: "Render children if the thread is running.",
|
|
245
256
|
},
|
|
257
|
+
{
|
|
258
|
+
name: "disabled",
|
|
259
|
+
type: "boolean | undefined",
|
|
260
|
+
description: "Render children if the thread is disabled.",
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "loading",
|
|
264
|
+
type: "boolean | undefined",
|
|
265
|
+
description: "Render children if the thread is loading.",
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "new",
|
|
269
|
+
type: "boolean | undefined",
|
|
270
|
+
description: "Render children if the thread is new.",
|
|
271
|
+
},
|
|
246
272
|
]}
|
|
247
273
|
/>
|
|
248
274
|
|
|
@@ -253,4 +279,10 @@ Renders children if a condition is met.
|
|
|
253
279
|
<Thread.If empty={false}>
|
|
254
280
|
{/* rendered if thread is not empty */}
|
|
255
281
|
</Thread.If>
|
|
282
|
+
<Thread.If loading>
|
|
283
|
+
{/* rendered if thread is loading */}
|
|
284
|
+
</Thread.If>
|
|
285
|
+
<Thread.If new>
|
|
286
|
+
{/* rendered if thread is new */}
|
|
287
|
+
</Thread.If>
|
|
256
288
|
```
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
title: Chat History for LangGraph Cloud
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
import { Steps, Step } from
|
|
6
|
-
import { Callout } from
|
|
7
|
-
import { Tab, Tabs } from
|
|
5
|
+
import { Steps, Step } from "fumadocs-ui/components/steps";
|
|
6
|
+
import { Callout } from "fumadocs-ui/components/callout";
|
|
7
|
+
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
10
10
|
|
|
@@ -13,7 +13,8 @@ assistant-cloud provides thread management and persistent chat history for appli
|
|
|
13
13
|
## Prerequisites
|
|
14
14
|
|
|
15
15
|
<Callout type="info">
|
|
16
|
-
You need an assistant-cloud account to follow this guide. [Sign up
|
|
16
|
+
You need an assistant-cloud account to follow this guide. [Sign up
|
|
17
|
+
here](https://cloud.assistant-ui.com/) to get started.
|
|
17
18
|
</Callout>
|
|
18
19
|
|
|
19
20
|
## Setup Guide
|
|
@@ -75,40 +76,12 @@ Create a runtime provider that integrates LangGraph with assistant-cloud. Choose
|
|
|
75
76
|
import {
|
|
76
77
|
AssistantCloud,
|
|
77
78
|
AssistantRuntimeProvider,
|
|
78
|
-
useCloudThreadListRuntime,
|
|
79
|
-
useThreadListItemRuntime,
|
|
80
79
|
} from "@assistant-ui/react";
|
|
81
80
|
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
|
|
82
81
|
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
|
|
83
82
|
import { LangChainMessage } from "@assistant-ui/react-langgraph";
|
|
84
83
|
import { useMemo } from "react";
|
|
85
84
|
|
|
86
|
-
const useMyLangGraphRuntime = () => {
|
|
87
|
-
const threadListItemRuntime = useThreadListItemRuntime();
|
|
88
|
-
|
|
89
|
-
const runtime = useLangGraphRuntime({
|
|
90
|
-
stream: async function* (messages) {
|
|
91
|
-
const { externalId } = await threadListItemRuntime.initialize();
|
|
92
|
-
if (!externalId) throw new Error("Thread not found");
|
|
93
|
-
|
|
94
|
-
return sendMessage({
|
|
95
|
-
threadId: externalId,
|
|
96
|
-
messages,
|
|
97
|
-
});
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
onSwitchToThread: async (externalId) => {
|
|
101
|
-
const state = await getThreadState(externalId);
|
|
102
|
-
return {
|
|
103
|
-
messages:
|
|
104
|
-
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return runtime;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
85
|
export function MyRuntimeProvider({
|
|
113
86
|
children,
|
|
114
87
|
}: Readonly<{
|
|
@@ -123,13 +96,28 @@ export function MyRuntimeProvider({
|
|
|
123
96
|
[],
|
|
124
97
|
);
|
|
125
98
|
|
|
126
|
-
const runtime =
|
|
99
|
+
const runtime = useLangGraphRuntime({
|
|
127
100
|
cloud,
|
|
128
|
-
|
|
101
|
+
stream: async function* (messages, { initialize }) {
|
|
102
|
+
const { externalId } = await initialize();
|
|
103
|
+
if (!externalId) throw new Error("Thread not found");
|
|
104
|
+
|
|
105
|
+
return sendMessage({
|
|
106
|
+
threadId: externalId,
|
|
107
|
+
messages,
|
|
108
|
+
});
|
|
109
|
+
},
|
|
129
110
|
create: async () => {
|
|
130
111
|
const { thread_id } = await createThread();
|
|
131
112
|
return { externalId: thread_id };
|
|
132
113
|
},
|
|
114
|
+
load: async (externalId) => {
|
|
115
|
+
const state = await getThreadState(externalId);
|
|
116
|
+
return {
|
|
117
|
+
messages:
|
|
118
|
+
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
|
|
119
|
+
};
|
|
120
|
+
},
|
|
133
121
|
});
|
|
134
122
|
|
|
135
123
|
return (
|
|
@@ -150,8 +138,6 @@ export function MyRuntimeProvider({
|
|
|
150
138
|
import {
|
|
151
139
|
AssistantCloud,
|
|
152
140
|
AssistantRuntimeProvider,
|
|
153
|
-
useCloudThreadListRuntime,
|
|
154
|
-
useThreadListItemRuntime,
|
|
155
141
|
} from "@assistant-ui/react";
|
|
156
142
|
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
|
|
157
143
|
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
|
|
@@ -159,32 +145,6 @@ import { LangChainMessage } from "@assistant-ui/react-langgraph";
|
|
|
159
145
|
import { useAuth } from "@clerk/nextjs";
|
|
160
146
|
import { useMemo } from "react";
|
|
161
147
|
|
|
162
|
-
const useMyLangGraphRuntime = () => {
|
|
163
|
-
const threadListItemRuntime = useThreadListItemRuntime();
|
|
164
|
-
|
|
165
|
-
const runtime = useLangGraphRuntime({
|
|
166
|
-
stream: async function* (messages) {
|
|
167
|
-
const { externalId } = await threadListItemRuntime.initialize();
|
|
168
|
-
if (!externalId) throw new Error("Thread not found");
|
|
169
|
-
|
|
170
|
-
return sendMessage({
|
|
171
|
-
threadId: externalId,
|
|
172
|
-
messages,
|
|
173
|
-
});
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
onSwitchToThread: async (externalId) => {
|
|
177
|
-
const state = await getThreadState(externalId);
|
|
178
|
-
return {
|
|
179
|
-
messages:
|
|
180
|
-
(state.values as { messages?: LangChainMessage[] }).messages ?? []
|
|
181
|
-
};
|
|
182
|
-
},
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return runtime;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
148
|
export function MyRuntimeProvider({
|
|
189
149
|
children,
|
|
190
150
|
}: Readonly<{
|
|
@@ -201,13 +161,28 @@ export function MyRuntimeProvider({
|
|
|
201
161
|
[getToken],
|
|
202
162
|
);
|
|
203
163
|
|
|
204
|
-
const runtime =
|
|
164
|
+
const runtime = useLangGraphRuntime({
|
|
205
165
|
cloud,
|
|
206
|
-
|
|
166
|
+
stream: async function* (messages, { initialize }) {
|
|
167
|
+
const { externalId } = await initialize();
|
|
168
|
+
if (!externalId) throw new Error("Thread not found");
|
|
169
|
+
|
|
170
|
+
return sendMessage({
|
|
171
|
+
threadId: externalId,
|
|
172
|
+
messages,
|
|
173
|
+
});
|
|
174
|
+
},
|
|
207
175
|
create: async () => {
|
|
208
176
|
const { thread_id } = await createThread();
|
|
209
177
|
return { externalId: thread_id };
|
|
210
178
|
},
|
|
179
|
+
load: async (externalId) => {
|
|
180
|
+
const state = await getThreadState(externalId);
|
|
181
|
+
return {
|
|
182
|
+
messages:
|
|
183
|
+
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
|
|
184
|
+
};
|
|
185
|
+
},
|
|
211
186
|
});
|
|
212
187
|
|
|
213
188
|
return (
|
|
@@ -219,7 +194,8 @@ export function MyRuntimeProvider({
|
|
|
219
194
|
```
|
|
220
195
|
|
|
221
196
|
<Callout type="info">
|
|
222
|
-
For Clerk authentication, configure the `"assistant-ui"` token template in
|
|
197
|
+
For Clerk authentication, configure the `"assistant-ui"` token template in
|
|
198
|
+
your Clerk dashboard.
|
|
223
199
|
</Callout>
|
|
224
200
|
|
|
225
201
|
</Tab>
|
|
@@ -227,7 +203,7 @@ export function MyRuntimeProvider({
|
|
|
227
203
|
</Tabs>
|
|
228
204
|
|
|
229
205
|
<Callout type="info">
|
|
230
|
-
The `
|
|
206
|
+
The `useLangGraphRuntime` hook now directly accepts `cloud`, `create`, and `load` parameters for simplified thread management. The runtime handles thread lifecycle internally.
|
|
231
207
|
</Callout>
|
|
232
208
|
|
|
233
209
|
</Step>
|
|
@@ -238,10 +214,30 @@ export function MyRuntimeProvider({
|
|
|
238
214
|
|
|
239
215
|
Install the thread list component:
|
|
240
216
|
|
|
241
|
-
|
|
242
|
-
|
|
217
|
+
<Tabs items={["assistant-ui", "shadcn (namespace)", "shadcn"]}>
|
|
218
|
+
<Tab>
|
|
219
|
+
|
|
220
|
+
```sh
|
|
221
|
+
npx assistant-ui@latest add thread-list
|
|
243
222
|
```
|
|
244
223
|
|
|
224
|
+
</Tab>
|
|
225
|
+
<Tab>
|
|
226
|
+
|
|
227
|
+
```sh
|
|
228
|
+
npx shadcn@latest add @assistant-ui/thread-list
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
</Tab>
|
|
232
|
+
<Tab>
|
|
233
|
+
|
|
234
|
+
```sh
|
|
235
|
+
npx shadcn@latest add "https://r.assistant-ui.com/thread-list"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
</Tab>
|
|
239
|
+
</Tabs>
|
|
240
|
+
|
|
245
241
|
Then add it to your application layout:
|
|
246
242
|
|
|
247
243
|
```tsx title="app/chat/page.tsx"
|