@assistant-ui/mcp-docs-server 0.1.30 → 0.1.31

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 (208) hide show
  1. package/.docs/organized/code-examples/waterfall.md +1 -1
  2. package/.docs/organized/code-examples/with-a2a.md +2 -2
  3. package/.docs/organized/code-examples/with-ag-ui.md +3 -3
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +5 -5
  5. package/.docs/organized/code-examples/with-artifacts.md +5 -5
  6. package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +79 -50
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +4 -4
  9. package/.docs/organized/code-examples/with-cloud.md +4 -4
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +56 -11
  11. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +7 -7
  12. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +7 -7
  13. package/.docs/organized/code-examples/with-expo.md +16 -16
  14. package/.docs/organized/code-examples/with-external-store.md +2 -2
  15. package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
  16. package/.docs/organized/code-examples/with-generative-ui.md +5 -5
  17. package/.docs/organized/code-examples/with-google-adk.md +4 -4
  18. package/.docs/organized/code-examples/with-heat-graph.md +1 -1
  19. package/.docs/organized/code-examples/with-interactables.md +5 -5
  20. package/.docs/organized/code-examples/with-langchain.md +3 -3
  21. package/.docs/organized/code-examples/with-langgraph.md +3 -3
  22. package/.docs/organized/code-examples/with-livekit.md +8 -8
  23. package/.docs/organized/code-examples/with-opencode.md +99 -54
  24. package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
  25. package/.docs/organized/code-examples/with-react-hook-form.md +5 -5
  26. package/.docs/organized/code-examples/with-react-ink.md +1 -1
  27. package/.docs/organized/code-examples/with-react-router.md +8 -8
  28. package/.docs/organized/code-examples/with-store.md +1 -1
  29. package/.docs/organized/code-examples/with-tanstack.md +5 -5
  30. package/.docs/organized/code-examples/with-tap-runtime.md +2 -2
  31. package/.docs/raw/docs/(docs)/cli.mdx +2 -1
  32. package/.docs/raw/docs/(docs)/copilots/assistant-frame.mdx +1 -0
  33. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +10 -3
  34. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +8 -3
  35. package/.docs/raw/docs/(docs)/copilots/make-assistant-visible.mdx +1 -0
  36. package/.docs/raw/docs/(docs)/copilots/model-context.mdx +1 -0
  37. package/.docs/raw/docs/(docs)/copilots/motivation.mdx +1 -0
  38. package/.docs/raw/docs/(docs)/copilots/use-assistant-instructions.mdx +1 -0
  39. package/.docs/raw/docs/(docs)/devtools.mdx +1 -0
  40. package/.docs/raw/docs/(docs)/index.mdx +1 -0
  41. package/.docs/raw/docs/(docs)/installation.mdx +1 -0
  42. package/.docs/raw/docs/(docs)/rtl.mdx +1 -0
  43. package/.docs/raw/docs/(reference)/api-reference/adapters/attachments.mdx +34 -0
  44. package/.docs/raw/docs/(reference)/api-reference/adapters/feedback-speech.mdx +41 -0
  45. package/.docs/raw/docs/(reference)/api-reference/adapters/index.mdx +26 -0
  46. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +34 -0
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/runtime.mdx +31 -0
  48. package/.docs/raw/docs/(reference)/api-reference/context-providers/index.mdx +20 -0
  49. package/.docs/raw/docs/(reference)/api-reference/hooks/index.mdx +26 -0
  50. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +72 -0
  51. package/.docs/raw/docs/(reference)/api-reference/hooks/runtimes.mdx +41 -0
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/state.mdx +48 -0
  53. package/.docs/raw/docs/(reference)/api-reference/hooks/utilities.mdx +30 -0
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +23 -0
  55. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +21 -0
  56. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +7 -0
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/index.mdx +65 -0
  58. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +50 -6
  59. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +15 -0
  60. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +36 -1
  61. package/.docs/raw/docs/(reference)/api-reference/runtimes/index.mdx +38 -0
  62. package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +5 -0
  63. package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +144 -6
  64. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +230 -2
  65. package/.docs/raw/docs/cloud/ai-sdk.mdx +221 -3
  66. package/.docs/raw/docs/cloud/langgraph.mdx +274 -2
  67. package/.docs/raw/docs/{(docs)/guides → guides}/attachments.mdx +41 -36
  68. package/.docs/raw/docs/guides/branching.mdx +76 -0
  69. package/.docs/raw/docs/guides/chain-of-thought.mdx +166 -0
  70. package/.docs/raw/docs/{(docs)/guides → guides}/context-api.mdx +50 -22
  71. package/.docs/raw/docs/{(docs)/guides → guides}/dictation.mdx +2 -0
  72. package/.docs/raw/docs/guides/editing.mdx +102 -0
  73. package/.docs/raw/docs/guides/index.mdx +103 -0
  74. package/.docs/raw/docs/{(docs)/guides → guides}/interactables.mdx +49 -0
  75. package/.docs/raw/docs/{(docs)/guides → guides}/latex.mdx +51 -8
  76. package/.docs/raw/docs/{(docs)/guides → guides}/mentions.mdx +61 -86
  77. package/.docs/raw/docs/{(docs)/guides → guides}/message-timing.mdx +8 -2
  78. package/.docs/raw/docs/{(docs)/guides → guides}/multi-agent.mdx +64 -4
  79. package/.docs/raw/docs/{(docs)/guides → guides}/quoting.mdx +10 -17
  80. package/.docs/raw/docs/{(docs)/guides → guides}/slash-commands.mdx +103 -37
  81. package/.docs/raw/docs/guides/speech.mdx +156 -0
  82. package/.docs/raw/docs/{(docs)/guides → guides}/suggestions.mdx +21 -83
  83. package/.docs/raw/docs/{(docs)/guides → guides}/tool-ui.mdx +108 -36
  84. package/.docs/raw/docs/{(docs)/guides → guides}/tools.mdx +131 -35
  85. package/.docs/raw/docs/{(docs)/guides → guides}/voice.mdx +39 -0
  86. package/.docs/raw/docs/ink/index.mdx +1 -3
  87. package/.docs/raw/docs/ink/migration.mdx +1 -3
  88. package/.docs/raw/docs/ink/primitives.mdx +37 -1
  89. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +520 -0
  90. package/.docs/raw/docs/integrations/auth/better-auth.mdx +191 -0
  91. package/.docs/raw/docs/integrations/auth/clerk.mdx +172 -0
  92. package/.docs/raw/docs/integrations/auth/next-auth.mdx +196 -0
  93. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +79 -0
  94. package/.docs/raw/docs/integrations/frameworks/mastra/full-stack.mdx +188 -0
  95. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +57 -0
  96. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +201 -0
  97. package/.docs/raw/docs/integrations/gateways/index.mdx +157 -0
  98. package/.docs/raw/docs/integrations/index.mdx +173 -0
  99. package/.docs/raw/docs/integrations/observability/helicone.mdx +130 -0
  100. package/.docs/raw/docs/integrations/observability/langfuse.mdx +156 -0
  101. package/.docs/raw/docs/integrations/observability/langsmith.mdx +146 -0
  102. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +712 -0
  103. package/.docs/raw/docs/integrations/tools/mcp.mdx +267 -0
  104. package/.docs/raw/docs/primitives/action-bar.mdx +1 -0
  105. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -0
  106. package/.docs/raw/docs/primitives/attachment.mdx +1 -0
  107. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -0
  108. package/.docs/raw/docs/primitives/chain-of-thought.mdx +90 -85
  109. package/.docs/raw/docs/primitives/composer.mdx +2 -1
  110. package/.docs/raw/docs/primitives/error.mdx +1 -0
  111. package/.docs/raw/docs/primitives/index.mdx +2 -1
  112. package/.docs/raw/docs/primitives/message.mdx +68 -5
  113. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -0
  114. package/.docs/raw/docs/primitives/suggestion.mdx +1 -0
  115. package/.docs/raw/docs/primitives/thread-list.mdx +39 -0
  116. package/.docs/raw/docs/primitives/thread.mdx +16 -13
  117. package/.docs/raw/docs/react-native/index.mdx +1 -3
  118. package/.docs/raw/docs/react-native/migration.mdx +1 -3
  119. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +396 -0
  120. package/.docs/raw/docs/runtimes/a2a/overview.mdx +60 -0
  121. package/.docs/raw/docs/runtimes/a2a/quickstart.mdx +216 -0
  122. package/.docs/raw/docs/runtimes/ag-ui/overview.mdx +70 -0
  123. package/.docs/raw/docs/runtimes/ag-ui/quickstart.mdx +243 -0
  124. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +123 -0
  125. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +52 -0
  126. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +71 -131
  127. package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +69 -63
  128. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +330 -123
  129. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +265 -0
  130. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +125 -0
  131. package/.docs/raw/docs/runtimes/concepts/stability.mdx +67 -0
  132. package/.docs/raw/docs/runtimes/concepts/threads.mdx +428 -0
  133. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +703 -0
  134. package/.docs/raw/docs/runtimes/custom/data-stream.mdx +323 -0
  135. package/.docs/raw/docs/runtimes/custom/external-store.mdx +253 -1236
  136. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +746 -0
  137. package/.docs/raw/docs/runtimes/custom/overview.mdx +71 -0
  138. package/.docs/raw/docs/runtimes/google-adk/api.mdx +256 -0
  139. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +717 -0
  140. package/.docs/raw/docs/runtimes/google-adk/overview.mdx +69 -0
  141. package/.docs/raw/docs/runtimes/google-adk/quickstart.mdx +229 -0
  142. package/.docs/raw/docs/runtimes/langchain.mdx +533 -0
  143. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +305 -0
  144. package/.docs/raw/docs/runtimes/langgraph/interrupts.mdx +104 -0
  145. package/.docs/raw/docs/runtimes/langgraph/overview.mdx +84 -0
  146. package/.docs/raw/docs/runtimes/langgraph/quickstart.mdx +496 -0
  147. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +127 -0
  148. package/.docs/raw/docs/runtimes/langgraph/threads.mdx +113 -0
  149. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +3 -3
  150. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +0 -23
  151. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -1
  152. package/.docs/raw/docs/runtimes/opencode/hooks.mdx +191 -0
  153. package/.docs/raw/docs/runtimes/opencode/overview.mdx +48 -0
  154. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +119 -0
  155. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +71 -203
  156. package/.docs/raw/docs/ui/accordion.mdx +1 -0
  157. package/.docs/raw/docs/ui/assistant-modal.mdx +1 -0
  158. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -0
  159. package/.docs/raw/docs/ui/attachment.mdx +1 -0
  160. package/.docs/raw/docs/ui/badge.mdx +1 -0
  161. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +1 -0
  162. package/.docs/raw/docs/ui/context-display.mdx +1 -0
  163. package/.docs/raw/docs/ui/diff-viewer.mdx +1 -0
  164. package/.docs/raw/docs/ui/directive-text.mdx +1 -0
  165. package/.docs/raw/docs/ui/file.mdx +1 -0
  166. package/.docs/raw/docs/ui/image.mdx +1 -0
  167. package/.docs/raw/docs/ui/markdown.mdx +2 -14
  168. package/.docs/raw/docs/ui/mermaid.mdx +1 -0
  169. package/.docs/raw/docs/ui/message-timing.mdx +3 -2
  170. package/.docs/raw/docs/ui/model-selector.mdx +1 -0
  171. package/.docs/raw/docs/ui/part-grouping.mdx +325 -313
  172. package/.docs/raw/docs/ui/quote.mdx +1 -0
  173. package/.docs/raw/docs/ui/reasoning.mdx +66 -33
  174. package/.docs/raw/docs/ui/scrollbar.mdx +1 -0
  175. package/.docs/raw/docs/ui/select.mdx +1 -0
  176. package/.docs/raw/docs/ui/sources.mdx +1 -0
  177. package/.docs/raw/docs/ui/streamdown.mdx +1 -0
  178. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -0
  179. package/.docs/raw/docs/ui/tabs.mdx +1 -0
  180. package/.docs/raw/docs/ui/thread-list.mdx +17 -0
  181. package/.docs/raw/docs/ui/thread.mdx +56 -1
  182. package/.docs/raw/docs/ui/tool-fallback.mdx +1 -0
  183. package/.docs/raw/docs/ui/tool-group.mdx +39 -11
  184. package/.docs/raw/docs/ui/voice.mdx +1 -0
  185. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -0
  186. package/.docs/raw/docs/utilities/react-o11y.mdx +278 -0
  187. package/.docs/raw/docs/utilities/tw-shimmer.mdx +1 -0
  188. package/package.json +3 -3
  189. package/src/tools/tests/path-traversal.test.ts +1 -1
  190. package/.docs/raw/docs/(docs)/guides/branching.mdx +0 -65
  191. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +0 -164
  192. package/.docs/raw/docs/(docs)/guides/editing.mdx +0 -66
  193. package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -38
  194. package/.docs/raw/docs/runtimes/a2a/index.mdx +0 -298
  195. package/.docs/raw/docs/runtimes/assistant-transport.mdx +0 -1033
  196. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +0 -314
  197. package/.docs/raw/docs/runtimes/custom/local.mdx +0 -1464
  198. package/.docs/raw/docs/runtimes/data-stream.mdx +0 -422
  199. package/.docs/raw/docs/runtimes/google-adk/index.mdx +0 -686
  200. package/.docs/raw/docs/runtimes/helicone.mdx +0 -61
  201. package/.docs/raw/docs/runtimes/langchain/comparison.mdx +0 -60
  202. package/.docs/raw/docs/runtimes/langchain/index.mdx +0 -210
  203. package/.docs/raw/docs/runtimes/langgraph/index.mdx +0 -699
  204. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +0 -12
  205. package/.docs/raw/docs/runtimes/langserve.mdx +0 -116
  206. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +0 -218
  207. package/.docs/raw/docs/runtimes/mastra/overview.mdx +0 -18
  208. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +0 -217
@@ -1,699 +0,0 @@
1
- ---
2
- title: Getting Started
3
- description: Connect to LangGraph Cloud API for agent workflows with streaming.
4
- ---
5
-
6
- <Callout type="info">
7
- If you are already using `@langchain/react`'s `useStream` hook, the alternative [`@assistant-ui/react-langchain`](/docs/runtimes/langchain) adapter may fit better. `@assistant-ui/react-langgraph` (this page) integrates with `@langchain/langgraph-sdk` directly and has the broader feature set — subgraph events, UI messages, message metadata, end-to-end cancellation. See the [comparison](/docs/runtimes/langchain/comparison).
8
- </Callout>
9
-
10
- ## Requirements
11
-
12
- You need a LangGraph Cloud API server. You can start a server locally via [LangGraph Studio](https://github.com/langchain-ai/langgraph-studio) or use [LangSmith](https://www.langchain.com/langsmith) for a hosted version.
13
-
14
- The state of the graph you are using must have a `messages` key with a list of LangChain-alike messages.
15
-
16
- ## New project from template
17
-
18
-
19
- <Steps>
20
- <Step>
21
- ### Create a new project based on the LangGraph assistant-ui template
22
-
23
- ```sh
24
- npx create-assistant-ui@latest -t langgraph my-app
25
- ```
26
-
27
- </Step>
28
- <Step>
29
- ### Set environment variables
30
-
31
- Create a `.env.local` file in your project with the following variables:
32
-
33
- ```sh
34
- # LANGCHAIN_API_KEY=your_api_key # for production
35
- # LANGGRAPH_API_URL=your_api_url # for production
36
- NEXT_PUBLIC_LANGGRAPH_API_URL=your_api_url # for development (no api key required)
37
- NEXT_PUBLIC_LANGGRAPH_ASSISTANT_ID=your_graph_id
38
- ```
39
-
40
- </Step>
41
- </Steps>
42
-
43
-
44
- ## Installation in existing React project
45
-
46
- <Steps>
47
- <Step>
48
-
49
- ### Install dependencies
50
-
51
- <InstallCommand npm={["@assistant-ui/react", "@assistant-ui/react-langgraph", "@langchain/langgraph-sdk"]} />
52
-
53
- </Step>
54
- <Step>
55
-
56
- ### Setup a proxy backend endpoint (optional, for production)
57
-
58
- <Callout type="warn">
59
- This example forwards every request to the LangGraph server directly from the
60
- browser. For production use-cases, you should limit the API calls to the
61
- subset of endpoints that you need and perform authorization checks.
62
- </Callout>
63
-
64
- ```tsx twoslash title="@/app/api/[...path]/route.ts"
65
- import { NextRequest, NextResponse } from "next/server";
66
-
67
- export const runtime = "edge";
68
-
69
- function getCorsHeaders() {
70
- return {
71
- "Access-Control-Allow-Origin": "*",
72
- "Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS",
73
- "Access-Control-Allow-Headers": "*",
74
- };
75
- }
76
-
77
- async function handleRequest(req: NextRequest, method: string) {
78
- try {
79
- const path = req.nextUrl.pathname.replace(/^\/?api\//, "");
80
- const url = new URL(req.url);
81
- const searchParams = new URLSearchParams(url.search);
82
- searchParams.delete("_path");
83
- searchParams.delete("nxtP_path");
84
- const queryString = searchParams.toString()
85
- ? `?${searchParams.toString()}`
86
- : "";
87
-
88
- const options: RequestInit = {
89
- method,
90
- headers: {
91
- "x-api-key": process.env["LANGCHAIN_API_KEY"] || "",
92
- },
93
- signal: req.signal,
94
- };
95
-
96
- if (["POST", "PUT", "PATCH"].includes(method)) {
97
- options.body = await req.text();
98
- }
99
-
100
- const res = await fetch(
101
- `${process.env["LANGGRAPH_API_URL"]}/${path}${queryString}`,
102
- options,
103
- );
104
-
105
- const headers = new Headers(res.headers);
106
- headers.delete("content-encoding");
107
- headers.delete("content-length");
108
- headers.delete("transfer-encoding");
109
- const corsHeaders = getCorsHeaders();
110
- for (const [key, value] of Object.entries(corsHeaders)) {
111
- headers.set(key, value);
112
- }
113
-
114
- return new NextResponse(res.body, {
115
- status: res.status,
116
- statusText: res.statusText,
117
- headers,
118
- });
119
- } catch (e: unknown) {
120
- if (e instanceof Error) {
121
- const typedError = e as Error & { status?: number };
122
- return NextResponse.json(
123
- { error: typedError.message },
124
- { status: typedError.status ?? 500 },
125
- );
126
- }
127
- return NextResponse.json({ error: "Unknown error" }, { status: 500 });
128
- }
129
- }
130
-
131
- export const GET = (req: NextRequest) => handleRequest(req, "GET");
132
- export const POST = (req: NextRequest) => handleRequest(req, "POST");
133
- export const PUT = (req: NextRequest) => handleRequest(req, "PUT");
134
- export const PATCH = (req: NextRequest) => handleRequest(req, "PATCH");
135
- export const DELETE = (req: NextRequest) => handleRequest(req, "DELETE");
136
- export const OPTIONS = () =>
137
- new NextResponse(null, {
138
- status: 204,
139
- headers: getCorsHeaders(),
140
- });
141
- ```
142
-
143
- </Step>
144
- <Step>
145
-
146
- ### Setup helper functions
147
-
148
- ```tsx twoslash include chatApi title="@/lib/chatApi.ts"
149
- // @filename: /lib/chatApi.ts
150
-
151
- // ---cut---
152
- import { Client } from "@langchain/langgraph-sdk";
153
-
154
- export const createClient = () => {
155
- const apiUrl =
156
- process.env["NEXT_PUBLIC_LANGGRAPH_API_URL"] ||
157
- (typeof window !== "undefined"
158
- ? new URL("/api", window.location.href).href
159
- : "/api");
160
- return new Client({ apiUrl });
161
- };
162
- ```
163
-
164
- </Step>
165
- <Step>
166
-
167
- ### Define a `MyAssistant` component
168
-
169
- ```tsx twoslash include MyAssistant title="@/components/MyAssistant.tsx"
170
- // @filename: /components/MyAssistant.tsx
171
- // @include: chatApi
172
-
173
- // ---cut---
174
- "use client";
175
-
176
- import { useMemo } from "react";
177
- import { Thread } from "@/components/assistant-ui/thread";
178
- import { AssistantRuntimeProvider } from "@assistant-ui/react";
179
- import {
180
- unstable_createLangGraphStream,
181
- useLangGraphRuntime,
182
- type LangChainMessage,
183
- } from "@assistant-ui/react-langgraph";
184
-
185
- import { createClient } from "@/lib/chatApi";
186
-
187
- const ASSISTANT_ID = process.env["NEXT_PUBLIC_LANGGRAPH_ASSISTANT_ID"]!;
188
-
189
- export function MyAssistant() {
190
- const client = useMemo(() => createClient(), []);
191
- const stream = useMemo(
192
- () =>
193
- unstable_createLangGraphStream({
194
- client,
195
- assistantId: ASSISTANT_ID,
196
- }),
197
- [client],
198
- );
199
-
200
- const runtime = useLangGraphRuntime({
201
- unstable_allowCancellation: true,
202
- stream,
203
- create: async () => {
204
- const { thread_id } = await client.threads.create();
205
- return { externalId: thread_id };
206
- },
207
- load: async (externalId) => {
208
- const state = await client.threads.getState<{
209
- messages: LangChainMessage[];
210
- }>(externalId);
211
- return {
212
- messages: state.values.messages,
213
- interrupts: state.tasks[0]?.interrupts,
214
- };
215
- },
216
- });
217
-
218
- return (
219
- <AssistantRuntimeProvider runtime={runtime}>
220
- <Thread />
221
- </AssistantRuntimeProvider>
222
- );
223
- }
224
- ```
225
-
226
- </Step>
227
- <Step>
228
-
229
- ### Use the `MyAssistant` component
230
-
231
- ```tsx twoslash title="@/app/page.tsx" {1,6}
232
- // @include: MyAssistant
233
- // @filename: /app/page.tsx
234
- // ---cut---
235
- import { MyAssistant } from "@/components/MyAssistant";
236
-
237
- export default function Home() {
238
- return (
239
- <main className="h-dvh">
240
- <MyAssistant />
241
- </main>
242
- );
243
- }
244
- ```
245
-
246
- </Step>
247
- <Step>
248
-
249
- ### Setup environment variables
250
-
251
- Create a `.env.local` file in your project with the following variables:
252
-
253
- ```sh
254
- # LANGCHAIN_API_KEY=your_api_key # for production
255
- # LANGGRAPH_API_URL=your_api_url # for production
256
- NEXT_PUBLIC_LANGGRAPH_API_URL=your_api_url # for development (no api key required)
257
- NEXT_PUBLIC_LANGGRAPH_ASSISTANT_ID=your_graph_id
258
- ```
259
-
260
- </Step>
261
- <Step>
262
-
263
- ### Setup UI components
264
-
265
- Follow the [UI Components](/docs/ui/thread) guide to setup the UI components.
266
-
267
- </Step>
268
- </Steps>
269
-
270
- ## Advanced APIs
271
-
272
- ### Message Accumulator
273
-
274
- The `LangGraphMessageAccumulator` lets you append messages incoming from the server to replicate the messages state client side.
275
-
276
- ```typescript
277
- import {
278
- LangGraphMessageAccumulator,
279
- appendLangChainChunk,
280
- } from "@assistant-ui/react-langgraph";
281
-
282
- const accumulator = new LangGraphMessageAccumulator({
283
- appendMessage: appendLangChainChunk,
284
- });
285
-
286
- // Add new chunks from the server
287
- if (event.event === "messages/partial") accumulator.addMessages(event.data);
288
- ```
289
-
290
- ### Message Conversion
291
-
292
- Use `convertLangChainMessages` to transform LangChain messages to assistant-ui format:
293
-
294
- ```typescript
295
- import { convertLangChainMessages } from "@assistant-ui/react-langgraph";
296
-
297
- const threadMessage = convertLangChainMessages(langChainMessage);
298
- ```
299
-
300
- ### Event Handlers
301
-
302
- You can listen to streaming events by passing `eventHandlers` to `useLangGraphRuntime`:
303
-
304
- ```typescript
305
- const runtime = useLangGraphRuntime({
306
- stream: async (messages, { initialize, ...config }) => { /* ... */ },
307
- eventHandlers: {
308
- onMessageChunk: (chunk, metadata) => {
309
- // Fired for each chunk in messages-tuple mode.
310
- // `metadata` contains langgraph_step, langgraph_node, ls_model_name, etc.
311
- // For pipe-namespaced events emitted by subgraphs (e.g. `messages|tools:call_abc`),
312
- // `metadata.namespace` holds the suffix ("tools:call_abc"). Use it to attribute
313
- // a chunk to a specific subgraph.
314
- },
315
- onValues: (values) => {
316
- // Fired when a top-level `values` event is received.
317
- // Subgraph `values` events are routed to `onSubgraphValues` instead.
318
- },
319
- onUpdates: (updates) => {
320
- // Fired when a top-level `updates` event is received.
321
- // Subgraph `updates` events are routed to `onSubgraphUpdates` instead.
322
- },
323
- onSubgraphValues: (namespace, values) => {
324
- // Fired when a subgraph `values|<namespace>` event is received
325
- // (e.g. `namespace === "tools:call_abc"`). Use this to observe
326
- // subgraph-internal state without mixing it into `onValues`.
327
- },
328
- onSubgraphUpdates: (namespace, updates) => {
329
- // Fired when a subgraph `updates|<namespace>` event is received.
330
- },
331
- onMetadata: (metadata) => { /* thread metadata */ },
332
- onInfo: (info) => { /* informational messages */ },
333
- onError: (error) => {
334
- // Fired for both top-level and subgraph errors.
335
- },
336
- onSubgraphError: (namespace, error) => {
337
- // Additionally fired for subgraph errors with the namespace.
338
- // Use to attribute a subgraph failure to its source without marking
339
- // the parent message as incomplete (that only happens for top-level errors).
340
- },
341
- onCustomEvent: (type, data) => { /* custom events */ },
342
- },
343
- });
344
- ```
345
-
346
- ### Message Metadata
347
-
348
- When using `streamMode: "messages-tuple"`, each chunk includes metadata from the LangGraph server. Access accumulated metadata per message with the `useLangGraphMessageMetadata` hook:
349
-
350
- ```typescript
351
- import { useLangGraphMessageMetadata } from "@assistant-ui/react-langgraph";
352
-
353
- function MyComponent() {
354
- const metadata = useLangGraphMessageMetadata();
355
- // Map<string, LangGraphTupleMetadata> keyed by message ID
356
- }
357
- ```
358
-
359
- ## Thread Management
360
-
361
- ### Basic Thread Support
362
-
363
- The `useLangGraphRuntime` hook now includes built-in thread management capabilities:
364
-
365
- ```typescript
366
- const runtime = useLangGraphRuntime({
367
- stream: async (messages, { initialize, ...config }) => {
368
- // initialize() creates or loads a thread and returns its IDs
369
- const { remoteId, externalId } = await initialize();
370
- // Use externalId (your backend's thread ID) for API calls
371
- return sendMessage({ threadId: externalId, messages, config });
372
- },
373
- create: async () => {
374
- // Called when creating a new thread
375
- const { thread_id } = await createThread();
376
- return { externalId: thread_id };
377
- },
378
- load: async (externalId) => {
379
- // Called when loading an existing thread
380
- const state = await getThreadState(externalId);
381
- return {
382
- messages: state.values.messages,
383
- interrupts: state.tasks[0]?.interrupts,
384
- };
385
- },
386
- });
387
- ```
388
-
389
- ### Cloud Persistence
390
-
391
- For persistent thread history across sessions, integrate with assistant-cloud:
392
-
393
- ```typescript
394
- const runtime = useLangGraphRuntime({
395
- cloud: new AssistantCloud({
396
- baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL,
397
- anonymous: true,
398
- }),
399
- // ... stream, create, load functions
400
- });
401
- ```
402
-
403
- See the [Cloud Persistence guide](/docs/cloud/langgraph) for detailed setup instructions.
404
-
405
- ### Custom Thread List
406
-
407
- To surface pre-existing LangGraph `thread_id`s in the thread picker without running assistant-cloud, pass a `RemoteThreadListAdapter` via `unstable_threadListAdapter`. A common implementation backs `list()` with `client.threads.search()` and `initialize()` with `client.threads.create()`.
408
-
409
- ```typescript
410
- import type { RemoteThreadListAdapter } from "@assistant-ui/react";
411
- import { Client } from "@langchain/langgraph-sdk";
412
-
413
- const client = new Client({ apiUrl: process.env.NEXT_PUBLIC_LANGGRAPH_API_URL });
414
-
415
- const threadListAdapter: RemoteThreadListAdapter = {
416
- async list() {
417
- const threads = await client.threads.search({ limit: 50 });
418
- return {
419
- threads: threads.map((t) => ({
420
- status: "regular",
421
- remoteId: t.thread_id,
422
- externalId: t.thread_id,
423
- title: (t.metadata as { title?: string } | undefined)?.title,
424
- })),
425
- };
426
- },
427
- async initialize() {
428
- const t = await client.threads.create();
429
- return { remoteId: t.thread_id, externalId: t.thread_id };
430
- },
431
- async delete(remoteId) {
432
- await client.threads.delete(remoteId);
433
- },
434
- // rename, archive, unarchive, fetch, generateTitle — see link below
435
- };
436
-
437
- const runtime = useLangGraphRuntime({
438
- stream: async function* (messages, { initialize }) { /* ... */ },
439
- load: async (externalId) => { /* ... */ },
440
- unstable_threadListAdapter: threadListAdapter,
441
- });
442
- ```
443
-
444
- Setting `remoteId === externalId` keeps the ids assistant-ui stores aligned with the LangGraph thread ids your `load` and `stream` callbacks receive. See the [Custom Thread List guide](/docs/runtimes/custom/custom-thread-list) for the full adapter contract.
445
-
446
- <Callout type="info">
447
- When `unstable_threadListAdapter` is provided, the `cloud`, `create`, and `delete` options are ignored — the adapter owns the full thread-list lifecycle.
448
- </Callout>
449
-
450
- ## Message Editing & Regeneration
451
-
452
- LangGraph uses server-side checkpoints for state management. To support message editing (branching) and regeneration, you need to provide a `getCheckpointId` callback that resolves the appropriate checkpoint for server-side forking.
453
-
454
- ```typescript
455
- const runtime = useLangGraphRuntime({
456
- stream: async (messages, { initialize, ...config }) => {
457
- const { externalId } = await initialize();
458
- if (!externalId) throw new Error("Thread not found");
459
- return sendMessage({ threadId: externalId, messages, config });
460
- },
461
- create: async () => {
462
- const { thread_id } = await createThread();
463
- return { externalId: thread_id };
464
- },
465
- load: async (externalId) => {
466
- const state = await getThreadState(externalId);
467
- return {
468
- messages: state.values.messages,
469
- interrupts: state.tasks[0]?.interrupts,
470
- };
471
- },
472
- getCheckpointId: async (threadId, parentMessages) => {
473
- const client = createClient();
474
- // Get the thread state history and find the checkpoint
475
- // that matches the parent messages by exact message ID sequence.
476
- // If IDs are missing, return null and skip edit/reload for safety.
477
- const history = await client.threads.getHistory(threadId);
478
- for (const state of history) {
479
- const stateMessages = state.values.messages;
480
- if (!stateMessages || stateMessages.length !== parentMessages.length) {
481
- continue;
482
- }
483
-
484
- const hasStableIds =
485
- parentMessages.every((message) => typeof message.id === "string") &&
486
- stateMessages.every((message) => typeof message.id === "string");
487
- if (!hasStableIds) {
488
- continue;
489
- }
490
-
491
- const isMatch = parentMessages.every(
492
- (message, index) => message.id === stateMessages[index]?.id,
493
- );
494
-
495
- if (isMatch) {
496
- return state.checkpoint.checkpoint_id ?? null;
497
- }
498
- }
499
- return null;
500
- },
501
- });
502
- ```
503
-
504
- When `getCheckpointId` is provided:
505
- - **Edit buttons** appear on user messages, allowing users to edit and resend from that point
506
- - **Regenerate buttons** appear on assistant messages, allowing users to regenerate the response
507
-
508
- The resolved `checkpointId` is passed to your `stream` callback via `config.checkpointId`. Your `sendMessage` helper should map it to the LangGraph SDK's `checkpoint_id` parameter (see the helper function in the setup section above).
509
-
510
- <Callout type="info">
511
- Without `getCheckpointId`, the edit and regenerate buttons will not appear. This is intentional — simply truncating client-side messages without forking from the correct server-side checkpoint would produce incorrect state.
512
- </Callout>
513
-
514
- ## Interrupt Persistence
515
-
516
- LangGraph supports interrupting the execution flow to request user input or handle specific interactions. These interrupts can be persisted and restored when switching between threads:
517
-
518
- 1. Make sure your thread state type includes the `interrupts` field
519
- 2. Return the interrupts from the `load` function along with the messages
520
- 3. The runtime will automatically restore the interrupt state when switching threads
521
-
522
- This feature is particularly useful for applications that require user approval flows, multi-step forms, or any other interactive elements that might span multiple thread switches.
523
-
524
- ## Generative UI (`ui_message`)
525
-
526
- LangGraph's [Generative UI](https://docs.langchain.com/langsmith/generative-ui-react) lets your graph emit structured UI components alongside assistant messages via `push_ui_message` (Python) or `typedUi().push()` (TypeScript). The assistant-ui LangGraph adapter translates these into [`DataMessagePart`s](/docs/guides/tool-ui) on the associated assistant message, which you render with the existing `makeAssistantDataUI` API.
527
-
528
- ### Enable the `custom` stream mode
529
-
530
- UI messages are emitted through LangGraph's `custom` stream channel. Make sure your `sendMessage` helper includes `"custom"` in `streamMode`:
531
-
532
- ```ts
533
- streamMode: ["messages", "updates", "custom"]
534
- ```
535
-
536
- Alternatively, if your graph accumulates UI messages in state under the `ui` key (the default for `typedUi`), `"values"` also works — the adapter reads both paths.
537
-
538
- ### Custom state key
539
-
540
- If your graph uses a non-default `stateKey` with `typedUi(config, { stateKey: "my_ui" })` on the server, pass the matching `uiStateKey` option to `useLangGraphRuntime` on the client:
541
-
542
- ```ts
543
- const runtime = useLangGraphRuntime({
544
- stream: async function* (messages, { initialize }) { /* ... */ },
545
- uiStateKey: "my_ui",
546
- });
547
- ```
548
-
549
- This only affects the `values` stream path — the `custom` channel carries each UI event individually and doesn't rely on the state key.
550
-
551
- ### Emit a UI message from your graph
552
-
553
- ```python title="Python"
554
- from langgraph.graph.ui import push_ui_message
555
- from langchain_core.messages import AIMessage
556
-
557
- async def chart_node(state, config):
558
- message = AIMessage(id="msg-1", content="Here's your chart.")
559
- push_ui_message(
560
- "chart",
561
- {"series": [1, 2, 3], "title": "Sales"},
562
- message=message, # Links the UI to this AI message
563
- )
564
- return {"messages": [message]}
565
- ```
566
-
567
- ```ts title="TypeScript"
568
- import { typedUi } from "@langchain/langgraph-sdk/react-ui/server";
569
- import type { ComponentRegistry } from "./components";
570
-
571
- export async function chartNode(state, config) {
572
- const ui = typedUi<ComponentRegistry>(config);
573
- const message = { id: "msg-1", type: "ai", content: "Here's your chart." };
574
- ui.push(
575
- { name: "chart", props: { series: [1, 2, 3], title: "Sales" } },
576
- { message },
577
- );
578
- return { messages: [message] };
579
- }
580
- ```
581
-
582
- Passing `message` (Python) or `{ message }` (TypeScript) is what links the UI component to a specific assistant message — the adapter reads `metadata.message_id` to attach the generated `DataMessagePart` to the correct message in the thread.
583
-
584
- ### Register a renderer on the client
585
-
586
- ```tsx title="@/components/ChartUI.tsx"
587
- import { makeAssistantDataUI } from "@assistant-ui/react";
588
-
589
- type ChartProps = {
590
- series: number[];
591
- title: string;
592
- };
593
-
594
- export const ChartUI = makeAssistantDataUI<ChartProps>({
595
- name: "chart",
596
- render: ({ data }) => (
597
- <div>
598
- <h3>{data.title}</h3>
599
- <Chart series={data.series} />
600
- </div>
601
- ),
602
- });
603
- ```
604
-
605
- Mount the component once somewhere inside the `AssistantRuntimeProvider` tree. It renders nothing itself — it only registers the renderer:
606
-
607
- ```tsx title="@/components/MyAssistant.tsx"
608
- <AssistantRuntimeProvider runtime={runtime}>
609
- <ChartUI />
610
- <Thread />
611
- </AssistantRuntimeProvider>
612
- ```
613
-
614
- When a matching UI message arrives, the adapter appends a `{ type: "data", name: "chart", data: { series, title } }` part to the parent assistant message and the registered component renders inline.
615
-
616
- ### Register renderers via `uiComponents`
617
-
618
- Instead of mounting separate `makeAssistantDataUI` components, you can register renderers directly on the runtime hook via the `uiComponents` option:
619
-
620
- ```tsx title="@/components/MyAssistant.tsx"
621
- const runtime = useLangGraphRuntime({
622
- stream: async function* (messages, { initialize }) { /* ... */ },
623
- uiComponents: {
624
- renderers: {
625
- chart: ({ data }) => <Chart series={data.series} title={data.title} />,
626
- table: ({ data }) => <DataTable rows={data.rows} />,
627
- },
628
- },
629
- });
630
- ```
631
-
632
- Static `renderers` are matched by `ui_message` name. If no match is found, the part renders nothing unless a `fallback` is provided.
633
-
634
- ### Dynamic loading with `fallback`
635
-
636
- LangSmith's [Generative UI](https://docs.langchain.com/langsmith/generative-ui-react) supports colocating UI code with your graph and loading it at runtime via `LoadExternalComponent`. The `fallback` option handles any `ui_message` name that has no static renderer:
637
-
638
- ```tsx title="@/components/MyAssistant.tsx"
639
- import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui";
640
-
641
- const runtime = useLangGraphRuntime({
642
- stream: async function* (messages, { initialize }) { /* ... */ },
643
- uiComponents: {
644
- fallback: ({ name, data }) => (
645
- <LoadExternalComponent name={name} props={data} />
646
- ),
647
- renderers: {
648
- chart: ({ data }) => <Chart {...data} />,
649
- },
650
- },
651
- });
652
- ```
653
-
654
- With this setup:
655
- - A `ui_message` with `name: "chart"` renders the static `Chart` component
656
- - Any other name (e.g. `"dashboard"`, `"form"`) is handled by `fallback`, which fetches the component from LangSmith at runtime
657
-
658
- The `fallback` component receives the same props as any data renderer: `name`, `data`, and part state metadata. This lets you pass the component name and props straight through to `LoadExternalComponent`.
659
-
660
- ### Semantics
661
-
662
- The adapter mirrors the reducer in `@langchain/langgraph-sdk/react-ui` exactly:
663
-
664
- - UI messages are keyed by their own `id`. Pushing the same id again **replaces** the existing entry
665
- - Passing `metadata: { merge: true }` shallow-merges `props` onto the previous entry
666
- - Emitting `{ type: "remove-ui", id }` (via `delete_ui_message` / `ui.delete(id)`) removes the entry
667
- - UI messages without `metadata.message_id` are held in the runtime but not injected into any message; use `useLangGraphUIMessages()` to access the raw list if needed
668
-
669
- ### Restore persisted UI messages on thread switch
670
-
671
- If your graph persists UI messages in state via `typedUi`, return them from the `load` callback so they're restored when the user switches threads or refreshes the page:
672
-
673
- ```tsx
674
- const runtime = useLangGraphRuntime({
675
- stream: async function* (messages, { initialize }) { /* ... */ },
676
- load: async (externalId) => {
677
- const state = await getThreadState(externalId);
678
- return {
679
- messages: state.values.messages,
680
- uiMessages: state.values.ui,
681
- interrupts: state.tasks[0]?.interrupts,
682
- };
683
- },
684
- });
685
- ```
686
-
687
- Without this, each reload starts with an empty UI list even though the messages themselves are loaded.
688
-
689
- ### Escape hatch: `useLangGraphUIMessages`
690
-
691
- ```tsx
692
- import { useLangGraphUIMessages } from "@assistant-ui/react-langgraph";
693
-
694
- function Sidebar() {
695
- const uiMessages = useLangGraphUIMessages();
696
- // Filter, group, or render UI messages outside the thread
697
- return <>{uiMessages.map(/* ... */)}</>;
698
- }
699
- ```
@@ -1,12 +0,0 @@
1
- ---
2
- title: "Introduction"
3
- description: Build a stockbroker assistant with LangGraph and assistant-ui.
4
- ---
5
-
6
- import { redirect } from "next/navigation";
7
-
8
- <>
9
- {redirect(
10
- "/docs/runtimes/langgraph/tutorial/introduction",
11
- )}
12
- </>