@assistant-ui/mcp-docs-server 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.docs/organized/code-examples/local-ollama.md +1135 -0
  2. package/.docs/organized/code-examples/search-agent-for-e-commerce.md +1721 -0
  3. package/.docs/organized/code-examples/with-ai-sdk.md +1081 -0
  4. package/.docs/organized/code-examples/with-cloud.md +1164 -0
  5. package/.docs/organized/code-examples/with-external-store.md +1064 -0
  6. package/.docs/organized/code-examples/with-ffmpeg.md +1305 -0
  7. package/.docs/organized/code-examples/with-langgraph.md +1819 -0
  8. package/.docs/organized/code-examples/with-openai-assistants.md +1175 -0
  9. package/.docs/organized/code-examples/with-react-hook-form.md +1727 -0
  10. package/.docs/organized/code-examples/with-vercel-ai-rsc.md +1157 -0
  11. package/.docs/raw/blog/2024-07-29-hello/index.mdx +65 -0
  12. package/.docs/raw/blog/2024-09-11/index.mdx +10 -0
  13. package/.docs/raw/blog/2024-12-15/index.mdx +10 -0
  14. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +129 -0
  15. package/.docs/raw/docs/about-assistantui.mdx +44 -0
  16. package/.docs/raw/docs/api-reference/context-providers/AssistantRuntimeProvider.mdx +30 -0
  17. package/.docs/raw/docs/api-reference/context-providers/TextContentPartProvider.mdx +26 -0
  18. package/.docs/raw/docs/api-reference/integrations/react-hook-form.mdx +103 -0
  19. package/.docs/raw/docs/api-reference/integrations/vercel-ai-sdk.mdx +145 -0
  20. package/.docs/raw/docs/api-reference/overview.mdx +583 -0
  21. package/.docs/raw/docs/api-reference/primitives/ActionBar.mdx +264 -0
  22. package/.docs/raw/docs/api-reference/primitives/AssistantModal.mdx +129 -0
  23. package/.docs/raw/docs/api-reference/primitives/Attachment.mdx +96 -0
  24. package/.docs/raw/docs/api-reference/primitives/BranchPicker.mdx +87 -0
  25. package/.docs/raw/docs/api-reference/primitives/Composer.mdx +204 -0
  26. package/.docs/raw/docs/api-reference/primitives/ContentPart.mdx +173 -0
  27. package/.docs/raw/docs/api-reference/primitives/Error.mdx +70 -0
  28. package/.docs/raw/docs/api-reference/primitives/Message.mdx +181 -0
  29. package/.docs/raw/docs/api-reference/primitives/Thread.mdx +197 -0
  30. package/.docs/raw/docs/api-reference/primitives/composition.mdx +21 -0
  31. package/.docs/raw/docs/api-reference/runtimes/AssistantRuntime.mdx +33 -0
  32. package/.docs/raw/docs/api-reference/runtimes/AttachmentRuntime.mdx +46 -0
  33. package/.docs/raw/docs/api-reference/runtimes/ComposerRuntime.mdx +69 -0
  34. package/.docs/raw/docs/api-reference/runtimes/ContentPartRuntime.mdx +22 -0
  35. package/.docs/raw/docs/api-reference/runtimes/MessageRuntime.mdx +49 -0
  36. package/.docs/raw/docs/api-reference/runtimes/ThreadListItemRuntime.mdx +32 -0
  37. package/.docs/raw/docs/api-reference/runtimes/ThreadListRuntime.mdx +31 -0
  38. package/.docs/raw/docs/api-reference/runtimes/ThreadRuntime.mdx +48 -0
  39. package/.docs/raw/docs/architecture.mdx +92 -0
  40. package/.docs/raw/docs/cloud/authorization.mdx +152 -0
  41. package/.docs/raw/docs/cloud/overview.mdx +55 -0
  42. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +54 -0
  43. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +123 -0
  44. package/.docs/raw/docs/concepts/architecture.mdx +19 -0
  45. package/.docs/raw/docs/concepts/runtime-layer.mdx +163 -0
  46. package/.docs/raw/docs/concepts/why.mdx +9 -0
  47. package/.docs/raw/docs/copilots/make-assistant-readable.mdx +71 -0
  48. package/.docs/raw/docs/copilots/make-assistant-tool-ui.mdx +76 -0
  49. package/.docs/raw/docs/copilots/make-assistant-tool.mdx +117 -0
  50. package/.docs/raw/docs/copilots/model-context.mdx +135 -0
  51. package/.docs/raw/docs/copilots/motivation.mdx +191 -0
  52. package/.docs/raw/docs/copilots/use-assistant-instructions.mdx +62 -0
  53. package/.docs/raw/docs/getting-started.mdx +1133 -0
  54. package/.docs/raw/docs/guides/Attachments.mdx +640 -0
  55. package/.docs/raw/docs/guides/Branching.mdx +59 -0
  56. package/.docs/raw/docs/guides/Editing.mdx +56 -0
  57. package/.docs/raw/docs/guides/Speech.mdx +43 -0
  58. package/.docs/raw/docs/guides/ToolUI.mdx +663 -0
  59. package/.docs/raw/docs/guides/Tools.mdx +496 -0
  60. package/.docs/raw/docs/index.mdx +7 -0
  61. package/.docs/raw/docs/legacy/styled/AssistantModal.mdx +85 -0
  62. package/.docs/raw/docs/legacy/styled/Decomposition.mdx +633 -0
  63. package/.docs/raw/docs/legacy/styled/Markdown.mdx +86 -0
  64. package/.docs/raw/docs/legacy/styled/Scrollbar.mdx +71 -0
  65. package/.docs/raw/docs/legacy/styled/Thread.mdx +84 -0
  66. package/.docs/raw/docs/legacy/styled/ThreadWidth.mdx +21 -0
  67. package/.docs/raw/docs/mcp-docs-server.mdx +324 -0
  68. package/.docs/raw/docs/migrations/deprecation-policy.mdx +41 -0
  69. package/.docs/raw/docs/migrations/v0-7.mdx +188 -0
  70. package/.docs/raw/docs/migrations/v0-8.mdx +160 -0
  71. package/.docs/raw/docs/migrations/v0-9.mdx +75 -0
  72. package/.docs/raw/docs/react-compatibility.mdx +208 -0
  73. package/.docs/raw/docs/runtimes/ai-sdk/rsc.mdx +226 -0
  74. package/.docs/raw/docs/runtimes/ai-sdk/use-assistant-hook.mdx +195 -0
  75. package/.docs/raw/docs/runtimes/ai-sdk/use-chat-hook.mdx +138 -0
  76. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +136 -0
  77. package/.docs/raw/docs/runtimes/custom/external-store.mdx +1624 -0
  78. package/.docs/raw/docs/runtimes/custom/local.mdx +1185 -0
  79. package/.docs/raw/docs/runtimes/helicone.mdx +60 -0
  80. package/.docs/raw/docs/runtimes/langgraph/index.mdx +320 -0
  81. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +11 -0
  82. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +28 -0
  83. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +120 -0
  84. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +336 -0
  85. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +385 -0
  86. package/.docs/raw/docs/runtimes/langserve.mdx +126 -0
  87. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +218 -0
  88. package/.docs/raw/docs/runtimes/mastra/overview.mdx +17 -0
  89. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +196 -0
  90. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +222 -0
  91. package/.docs/raw/docs/ui/AssistantModal.mdx +46 -0
  92. package/.docs/raw/docs/ui/AssistantSidebar.mdx +42 -0
  93. package/.docs/raw/docs/ui/Attachment.mdx +82 -0
  94. package/.docs/raw/docs/ui/Markdown.mdx +72 -0
  95. package/.docs/raw/docs/ui/Mermaid.mdx +79 -0
  96. package/.docs/raw/docs/ui/Scrollbar.mdx +59 -0
  97. package/.docs/raw/docs/ui/SyntaxHighlighting.mdx +253 -0
  98. package/.docs/raw/docs/ui/Thread.mdx +47 -0
  99. package/.docs/raw/docs/ui/ThreadList.mdx +49 -0
  100. package/.docs/raw/docs/ui/ToolFallback.mdx +64 -0
  101. package/.docs/raw/docs/ui/primitives/Thread.mdx +197 -0
  102. package/LICENSE +21 -0
  103. package/README.md +128 -0
  104. package/dist/chunk-C7O7EFKU.js +38 -0
  105. package/dist/chunk-CZCDQ3YH.js +420 -0
  106. package/dist/index.js +1 -0
  107. package/dist/prepare-docs/prepare.js +199 -0
  108. package/dist/stdio.js +8 -0
  109. package/package.json +43 -0
@@ -0,0 +1,385 @@
1
+ ---
2
+ title: "Part 3: Approval UI"
3
+ ---
4
+
5
+ ## Background: LangGraph implementation details
6
+
7
+ import Image from "next/image";
8
+ import approval from "./images/stockbroker-langgraph.png";
9
+
10
+ <Image
11
+ src={approval}
12
+ alt="LangChain LangGraph"
13
+ width={600}
14
+ className="mx-auto rounded-lg border shadow"
15
+ />
16
+
17
+ Our LangGraph backend interrupts the `purchase_stock` tool execution in order to ensure the user confirms the purchase. The user confirms the purchase by submitting a tool message with the `approve` field set to `true`.
18
+
19
+ ```ts title="assistant-ui-stockbroker/backend/src/index.ts" {6,18-19,32-35}
20
+ const purchaseApproval = async (state: typeof GraphAnnotation.State) => {
21
+ const { messages } = state;
22
+ const lastMessage = messages[messages.length - 1];
23
+ if (!(lastMessage instanceof ToolMessage)) {
24
+ // Interrupt the node to request permission to execute the purchase.
25
+ throw new NodeInterrupt("Please confirm the purchase before executing.");
26
+ }
27
+ };
28
+
29
+ const shouldExecutePurchase = (state: typeof GraphAnnotation.State) => {
30
+ const { messages } = state;
31
+ const lastMessage = messages[messages.length - 1];
32
+ if (!(lastMessage instanceof ToolMessage)) {
33
+ // Interrupt the node to request permission to execute the purchase.
34
+ throw new NodeInterrupt("Please confirm the purchase before executing.");
35
+ }
36
+
37
+ const { approve } = JSON.parse(lastMessage.content as string);
38
+ return approve ? "execute_purchase" : "agent";
39
+ };
40
+
41
+ const workflow = new StateGraph(GraphAnnotation)
42
+ .addNode("agent", callModel)
43
+ .addEdge(START, "agent")
44
+ .addNode("tools", toolNode)
45
+ .addNode("prepare_purchase_details", preparePurchaseDetails)
46
+ .addNode("purchase_approval", purchaseApproval)
47
+ .addNode("execute_purchase", executePurchase)
48
+ .addEdge("prepare_purchase_details", "purchase_approval")
49
+ .addEdge("execute_purchase", END)
50
+ .addEdge("tools", "agent")
51
+ .addConditionalEdges("purchase_approval", shouldExecutePurchase, [
52
+ "agent",
53
+ "execute_purchase",
54
+ ])
55
+ .addConditionalEdges("agent", shouldContinue, [
56
+ "tools",
57
+ END,
58
+ "prepare_purchase_details",
59
+ ]);
60
+ ```
61
+
62
+ ## Add approval UI
63
+
64
+ We create a new file under `/components/tools/purchase-stock/PurchaseStockTool.tsx` to define the tool.
65
+
66
+ First, we define the tool arguments and result types:
67
+
68
+ ```ts title="@/components/tools/purchase-stock/PurchaseStockTool.tsx"
69
+ type PurchaseStockArgs = {
70
+ ticker: string;
71
+ companyName: string;
72
+ quantity: number;
73
+ maxPurchasePrice: number;
74
+ };
75
+
76
+ type PurchaseStockResult = {
77
+ approve?: boolean;
78
+ cancelled?: boolean;
79
+ error?: string;
80
+ };
81
+ ```
82
+
83
+ Then we use `makeAssistantToolUI` to define the tool UI:
84
+
85
+ ```tsx title="@/components/tools/purchase-stock/PurchaseStockTool.tsx"
86
+ "use client";
87
+
88
+ import { TransactionConfirmationPending } from "./transaction-confirmation-pending";
89
+ import { TransactionConfirmationFinal } from "./transaction-confirmation-final";
90
+ import { makeAssistantToolUI } from "@assistant-ui/react";
91
+ import { updateState } from "@/lib/chatApi";
92
+
93
+ export const PurchaseStockTool = makeAssistantToolUI<PurchaseStockArgs, string>(
94
+ {
95
+ toolName: "purchase_stock",
96
+ render: function PurchaseStockUI({ args, result, status, addResult }) {
97
+ const handleReject = async () => {
98
+ addResult({ approve: false });
99
+ };
100
+
101
+ const handleConfirm = async () => {
102
+ addResult({ approve: true });
103
+ };
104
+
105
+ return (
106
+ <div className="mb-4 flex flex-col items-center gap-2">
107
+ <div>
108
+ <pre className="whitespace-pre-wrap break-all text-center">
109
+ purchase_stock({JSON.stringify(args)})
110
+ </pre>
111
+ </div>
112
+ {!result && status.type !== "running" && (
113
+ <TransactionConfirmationPending
114
+ {...args}
115
+ onConfirm={handleConfirm}
116
+ onReject={handleReject}
117
+ />
118
+ )}
119
+ </div>
120
+ );
121
+ },
122
+ },
123
+ );
124
+ ```
125
+
126
+ Finally, we add a `TransactionConfirmationPending` component to ask for approval.
127
+
128
+ This requires shadcn/ui's `Card` and `Button` components. We will install them as a dependency.
129
+
130
+ ```sh
131
+ npx shadcn@latest add card button
132
+ ```
133
+
134
+ Then create a new file under `/components/tools/purchase-stock/transaction-confirmation-pending.tsx` to define the approval UI.
135
+
136
+ ```tsx title="@/components/tools/purchase-stock/transaction-confirmation-pending.tsx"
137
+ "use client";
138
+
139
+ import { CheckIcon, XIcon } from "lucide-react";
140
+
141
+ import { Button } from "@/components/ui/button";
142
+ import {
143
+ Card,
144
+ CardContent,
145
+ CardFooter,
146
+ CardHeader,
147
+ CardTitle,
148
+ } from "@/components/ui/card";
149
+
150
+ type TransactionConfirmation = {
151
+ ticker: string;
152
+ companyName: string;
153
+ quantity: number;
154
+ maxPurchasePrice: number;
155
+ onConfirm: () => void;
156
+ onReject: () => void;
157
+ };
158
+
159
+ export function TransactionConfirmationPending(props: TransactionConfirmation) {
160
+ const {
161
+ ticker,
162
+ companyName,
163
+ quantity,
164
+ maxPurchasePrice,
165
+ onConfirm,
166
+ onReject,
167
+ } = props;
168
+
169
+ return (
170
+ <Card className="mx-auto w-full max-w-md">
171
+ <CardHeader>
172
+ <CardTitle className="text-2xl font-bold">
173
+ Confirm Transaction
174
+ </CardTitle>
175
+ </CardHeader>
176
+ <CardContent className="space-y-4">
177
+ <div className="grid grid-cols-2 gap-2">
178
+ <p className="text-muted-foreground text-sm font-medium">Ticker:</p>
179
+ <p className="text-sm font-bold">{ticker}</p>
180
+ <p className="text-muted-foreground text-sm font-medium">Company:</p>
181
+ <p className="text-sm">{companyName}</p>
182
+ <p className="text-muted-foreground text-sm font-medium">Quantity:</p>
183
+ <p className="text-sm">{quantity} shares</p>
184
+ <p className="text-muted-foreground text-sm font-medium">
185
+ Max Purchase Price:
186
+ </p>
187
+ <p className="text-sm">${maxPurchasePrice?.toFixed(2)}</p>
188
+ </div>
189
+ <div className="bg-muted rounded-md p-3">
190
+ <p className="text-sm font-medium">Total Maximum Cost:</p>
191
+ <p className="text-lg font-bold">
192
+ ${(quantity * maxPurchasePrice)?.toFixed(2)}
193
+ </p>
194
+ </div>
195
+ </CardContent>
196
+ <CardFooter className="flex justify-end">
197
+ <Button variant="outline" onClick={onReject}>
198
+ <XIcon className="mr-2 h-4 w-4" />
199
+ Reject
200
+ </Button>
201
+ <Button onClick={onConfirm}>
202
+ <CheckIcon className="mr-2 h-4 w-4" />
203
+ Confirm
204
+ </Button>
205
+ </CardFooter>
206
+ </Card>
207
+ );
208
+ }
209
+ ```
210
+
211
+ ### Bind approval UI
212
+
213
+ ```tsx title="@/app/page.tsx" {1,8}
214
+ import { PurchaseStockTool } from "@/components/tools/purchase-stock/PurchaseStockTool";
215
+
216
+ export default function Home() {
217
+ return (
218
+ <div className="flex h-full flex-col">
219
+ <Thread
220
+ ...
221
+ tools={[PriceSnapshotTool, PurchaseStockTool]}
222
+ />
223
+ </div>
224
+ );
225
+ }
226
+ ```
227
+
228
+ ### Try it out!
229
+
230
+ Ask the assistant to buy 5 shares of Tesla. You should see the following appear:
231
+
232
+ import purchase from "./images/acme-approve.png";
233
+
234
+ <Image
235
+ src={purchase}
236
+ alt="Approval UI"
237
+ width={600}
238
+ className="mx-auto rounded-lg border shadow"
239
+ />
240
+
241
+ ## Add `TransactionConfirmationFinal` to show approval result
242
+
243
+ We will add a component to display the approval result.
244
+
245
+ ```ts title="@/components/tools/purchase-stock/transaction-confirmation-final.tsx"
246
+ "use client";
247
+
248
+ import { CheckCircle } from "lucide-react";
249
+
250
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
251
+
252
+ type TransactionConfirmation = {
253
+ ticker: string;
254
+ companyName: string;
255
+ quantity: number;
256
+ maxPurchasePrice: number;
257
+ };
258
+
259
+ export function TransactionConfirmationFinal(props: TransactionConfirmation) {
260
+ const { ticker, companyName, quantity, maxPurchasePrice } = props;
261
+
262
+ return (
263
+ <Card className="mx-auto w-full max-w-md">
264
+ <CardHeader className="text-center">
265
+ <CheckCircle className="mx-auto mb-4 h-16 w-16 text-green-500" />
266
+ <CardTitle className="text-2xl font-bold text-green-700">
267
+ Transaction Confirmed
268
+ </CardTitle>
269
+ </CardHeader>
270
+ <CardContent className="space-y-4">
271
+ <div className="rounded-md border border-green-200 bg-green-50 p-4">
272
+ <h3 className="mb-2 text-lg font-semibold text-green-800">
273
+ Purchase Summary
274
+ </h3>
275
+ <div className="grid grid-cols-2 gap-2 text-sm">
276
+ <p className="font-medium text-green-700">Ticker:</p>
277
+ <p className="font-bold text-green-900">{ticker}</p>
278
+ <p className="font-medium text-green-700">Company:</p>
279
+ <p className="text-green-900">{companyName}</p>
280
+ <p className="font-medium text-green-700">Quantity:</p>
281
+ <p className="text-green-900">{quantity} shares</p>
282
+ <p className="font-medium text-green-700">Price per Share:</p>
283
+ <p className="text-green-900">${maxPurchasePrice?.toFixed(2)}</p>
284
+ </div>
285
+ </div>
286
+ <div className="rounded-md border border-green-300 bg-green-100 p-4">
287
+ <p className="text-lg font-semibold text-green-800">Total Cost:</p>
288
+ <p className="text-2xl font-bold text-green-900">
289
+ ${(quantity * maxPurchasePrice)?.toFixed(2)}
290
+ </p>
291
+ </div>
292
+ <p className="text-center text-sm text-green-600">
293
+ Your purchase of {quantity} shares of {companyName} ({ticker}) has
294
+ been successfully processed.
295
+ </p>
296
+ </CardContent>
297
+ </Card>
298
+ );
299
+ }
300
+ ```
301
+
302
+ ### Update `PurchaseStockTool`
303
+
304
+ We will import the new `<TransactionConfirmationFinal />` component and use it in the `render` function whenever an approval result is available.
305
+
306
+ ```tsx title="@/components/tools/purchase-stock/PurchaseStockTool.tsx" {3,25-30,37-42}
307
+ "use client";
308
+
309
+ import { TransactionConfirmationPending } from "./transaction-confirmation-pending";
310
+ import { TransactionConfirmationFinal } from "./transaction-confirmation-final";
311
+ import { makeAssistantToolUI } from "@assistant-ui/react";
312
+ import { updateState } from "@/lib/chatApi";
313
+
314
+ type PurchaseStockArgs = {
315
+ ticker: string;
316
+ companyName: string;
317
+ quantity: number;
318
+ maxPurchasePrice: number;
319
+ };
320
+
321
+ type PurchaseStockResult = {
322
+ approve?: boolean;
323
+ cancelled?: boolean;
324
+ error?: string;
325
+ };
326
+
327
+ export const PurchaseStockTool = makeAssistantToolUI<PurchaseStockArgs, string>(
328
+ {
329
+ toolName: "purchase_stock",
330
+ render: function PurchaseStockUI({ args, result, status, addResult }) {
331
+ let resultObj: PurchaseStockResult;
332
+ try {
333
+ resultObj = result ? JSON.parse(result) : {};
334
+ } catch (e) {
335
+ resultObj = { error: result! };
336
+ }
337
+
338
+ const handleReject = () => {
339
+ addResult({ cancelled: true });
340
+ };
341
+
342
+ const handleConfirm = async () => {
343
+ addResult({ approve: true });
344
+ };
345
+
346
+ return (
347
+ <div className="mb-4 flex flex-col items-center gap-2">
348
+ <div>
349
+ <pre className="whitespace-pre-wrap break-all text-center">
350
+ purchase_stock({JSON.stringify(args)})
351
+ </pre>
352
+ </div>
353
+ {!result && status.type !== "running" && (
354
+ <TransactionConfirmationPending
355
+ {...args}
356
+ onConfirm={handleConfirm}
357
+ onReject={handleReject}
358
+ />
359
+ )}
360
+ {resultObj.approve && <TransactionConfirmationFinal {...args} />}
361
+ {resultObj.approve === false && (
362
+ <pre className="font-bold text-red-600">User rejected purchase</pre>
363
+ )}
364
+ {resultObj.cancelled && (
365
+ <pre className="font-bold text-red-600">Cancelled</pre>
366
+ )}
367
+ </div>
368
+ );
369
+ },
370
+ },
371
+ );
372
+ ```
373
+
374
+ ### Try it out!
375
+
376
+ Confirm the purchase of shares. You should see the approval confimration UI appear.
377
+
378
+ import purchase2 from "./images/acme-confirmed.png";
379
+
380
+ <Image
381
+ src={purchase2}
382
+ alt="Approval result"
383
+ width={600}
384
+ className="mx-auto rounded-lg border shadow"
385
+ />
@@ -0,0 +1,126 @@
1
+ ---
2
+ title: LangChain LangServe
3
+ ---
4
+
5
+ ## Overview
6
+
7
+ Integration with a LangServe server via Vercel AI SDK.
8
+
9
+ ## Getting Started
10
+
11
+ import { Steps, Step } from "fumadocs-ui/components/steps";
12
+
13
+ <Steps>
14
+ <Step>
15
+ ### Create a Next.JS project
16
+
17
+ ```sh
18
+ npx create-next-app@latest my-app
19
+ cd my-app
20
+ ```
21
+
22
+ </Step>
23
+ <Step>
24
+
25
+ ### Install `@langchain/core`, `ai-sdk` and `@assistant-ui/react`
26
+
27
+ ```sh npm2yarn
28
+ npm install @assistant-ui/react @assistant-ui/react-ai-sdk ai @ai-sdk/react @langchain/core
29
+ ```
30
+
31
+ </Step>
32
+ <Step>
33
+
34
+ ### Setup a backend route under `/api/chat`
35
+
36
+ ```tsx twoslash title="@/app/api/chat/route.ts"
37
+ // @errors: 2558 2345
38
+ import { RemoteRunnable } from "@langchain/core/runnables/remote";
39
+ import type { RunnableConfig } from "@langchain/core/runnables";
40
+ import { streamText, LangChainAdapter, type Message } from "ai";
41
+
42
+ export const maxDuration = 30;
43
+
44
+ export async function POST(req: Request) {
45
+ const { messages } = (await req.json()) as { messages: Message[] };
46
+
47
+ // TODO replace with your own langserve URL
48
+ const remoteChain = new RemoteRunnable<
49
+ { messages: Message[] },
50
+ string,
51
+ RunnableConfig
52
+ >({
53
+ url: "<YOUR_LANGSERVE_URL>",
54
+ });
55
+
56
+ const stream = await remoteChain.stream({
57
+ messages,
58
+ });
59
+
60
+ return LangChainAdapter.toDataStreamResponse(stream);
61
+ }
62
+ ```
63
+
64
+ </Step>
65
+ <Step>
66
+
67
+ ### Define a `MyRuntimeProvider` component
68
+
69
+ ```tsx twoslash include MyRuntimeProvider title="@/app/MyRuntimeProvider.tsx"
70
+ // @filename: /app/MyRuntimeProvider.tsx
71
+ // ---cut---
72
+ "use client";
73
+
74
+ import { useChat } from "@ai-sdk/react";
75
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
76
+ import { useVercelUseChatRuntime } from "@assistant-ui/react-ai-sdk";
77
+
78
+ export function MyRuntimeProvider({
79
+ children,
80
+ }: Readonly<{
81
+ children: React.ReactNode;
82
+ }>) {
83
+ const chat = useChat({
84
+ api: "/api/chat",
85
+ unstable_AISDKInterop: true,
86
+ });
87
+
88
+ const runtime = useVercelUseChatRuntime(chat);
89
+
90
+ return (
91
+ <AssistantRuntimeProvider runtime={runtime}>
92
+ {children}
93
+ </AssistantRuntimeProvider>
94
+ );
95
+ }
96
+ ```
97
+
98
+ </Step>
99
+ <Step>
100
+
101
+ ### Wrap your app in `MyRuntimeProvider`
102
+
103
+ ```tsx twoslash title="@/app/layout.tsx"
104
+ // @include: MyRuntimeProvider
105
+ // @filename: /app/layout.tsx
106
+ // ---cut---
107
+ import type { ReactNode } from "react";
108
+ import { MyRuntimeProvider } from "@/app/MyRuntimeProvider";
109
+
110
+ export default function RootLayout({
111
+ children,
112
+ }: Readonly<{
113
+ children: ReactNode;
114
+ }>) {
115
+ return (
116
+ <MyRuntimeProvider>
117
+ <html lang="en">
118
+ <body>{children}</body>
119
+ </html>
120
+ </MyRuntimeProvider>
121
+ );
122
+ }
123
+ ```
124
+
125
+ </Step>
126
+ </Steps>