@assistant-ui/mcp-docs-server 0.1.22 → 0.1.23

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 (74) hide show
  1. package/.docs/organized/code-examples/waterfall.md +801 -0
  2. package/.docs/organized/code-examples/with-ag-ui.md +38 -26
  3. package/.docs/organized/code-examples/with-ai-sdk-v6.md +38 -28
  4. package/.docs/organized/code-examples/with-artifacts.md +467 -0
  5. package/.docs/organized/code-examples/with-assistant-transport.md +31 -24
  6. package/.docs/organized/code-examples/with-chain-of-thought.md +41 -32
  7. package/.docs/organized/code-examples/with-cloud-standalone.md +675 -0
  8. package/.docs/organized/code-examples/with-cloud.md +34 -27
  9. package/.docs/organized/code-examples/with-custom-thread-list.md +34 -27
  10. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +41 -30
  11. package/.docs/organized/code-examples/with-expo.md +2031 -0
  12. package/.docs/organized/code-examples/with-external-store.md +32 -25
  13. package/.docs/organized/code-examples/with-ffmpeg.md +31 -27
  14. package/.docs/organized/code-examples/with-langgraph.md +96 -38
  15. package/.docs/organized/code-examples/with-parent-id-grouping.md +32 -25
  16. package/.docs/organized/code-examples/with-react-hook-form.md +63 -58
  17. package/.docs/organized/code-examples/with-react-router.md +38 -30
  18. package/.docs/organized/code-examples/with-store.md +16 -24
  19. package/.docs/organized/code-examples/with-tanstack.md +36 -26
  20. package/.docs/organized/code-examples/with-tap-runtime.md +10 -24
  21. package/.docs/raw/docs/(docs)/cli.mdx +13 -6
  22. package/.docs/raw/docs/(docs)/guides/attachments.mdx +26 -3
  23. package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +5 -5
  24. package/.docs/raw/docs/(docs)/guides/context-api.mdx +53 -52
  25. package/.docs/raw/docs/(docs)/guides/dictation.mdx +0 -2
  26. package/.docs/raw/docs/(docs)/guides/message-timing.mdx +169 -0
  27. package/.docs/raw/docs/(docs)/guides/quoting.mdx +327 -0
  28. package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -1
  29. package/.docs/raw/docs/(docs)/index.mdx +12 -2
  30. package/.docs/raw/docs/(docs)/installation.mdx +8 -2
  31. package/.docs/raw/docs/(docs)/llm.mdx +9 -7
  32. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +1 -1
  33. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +2 -2
  34. package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +27 -27
  35. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +60 -0
  36. package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +78 -4
  37. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +32 -0
  38. package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +61 -0
  39. package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +1 -1
  40. package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +1 -6
  41. package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +2 -2
  42. package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +1 -6
  43. package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +1 -5
  44. package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +17 -17
  45. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +205 -0
  46. package/.docs/raw/docs/cloud/ai-sdk.mdx +292 -0
  47. package/.docs/raw/docs/cloud/authorization.mdx +178 -79
  48. package/.docs/raw/docs/cloud/{persistence/langgraph.mdx → langgraph.mdx} +2 -2
  49. package/.docs/raw/docs/cloud/overview.mdx +29 -39
  50. package/.docs/raw/docs/react-native/adapters.mdx +118 -0
  51. package/.docs/raw/docs/react-native/custom-backend.mdx +210 -0
  52. package/.docs/raw/docs/react-native/hooks.mdx +364 -0
  53. package/.docs/raw/docs/react-native/index.mdx +332 -0
  54. package/.docs/raw/docs/react-native/primitives.mdx +653 -0
  55. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -15
  56. package/.docs/raw/docs/runtimes/assistant-transport.mdx +103 -0
  57. package/.docs/raw/docs/runtimes/custom/external-store.mdx +25 -2
  58. package/.docs/raw/docs/runtimes/data-stream.mdx +1 -3
  59. package/.docs/raw/docs/runtimes/langgraph/index.mdx +113 -9
  60. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +1 -4
  61. package/.docs/raw/docs/ui/attachment.mdx +4 -2
  62. package/.docs/raw/docs/ui/message-timing.mdx +92 -0
  63. package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
  64. package/.docs/raw/docs/ui/reasoning.mdx +4 -4
  65. package/.docs/raw/docs/ui/scrollbar.mdx +2 -2
  66. package/.docs/raw/docs/ui/syntax-highlighting.mdx +55 -50
  67. package/.docs/raw/docs/ui/thread.mdx +16 -9
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/package.json +3 -3
  71. package/src/tools/tests/integration.test.ts +2 -2
  72. package/src/tools/tests/json-parsing.test.ts +1 -1
  73. package/src/tools/tests/mcp-protocol.test.ts +1 -3
  74. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +0 -108
@@ -0,0 +1,292 @@
1
+ ---
2
+ title: AI SDK
3
+ description: Add cloud persistence to your existing AI SDK app with a single hook.
4
+ ---
5
+
6
+ import { InstallCommand } from "@/components/docs/fumadocs/install/install-command";
7
+
8
+ ## Overview
9
+
10
+ The `@assistant-ui/cloud-ai-sdk` package provides a single hook that adds full message and thread persistence to any [AI SDK](https://sdk.vercel.ai/) application:
11
+
12
+ - **`useCloudChat`** — wraps `useChat` with automatic cloud persistence and built-in thread management
13
+
14
+ This hook works with any React UI. You keep full control of your components.
15
+
16
+ <Callout type="tip">
17
+ See [AI SDK + assistant-ui](/docs/cloud/ai-sdk-assistant-ui) for the full integration with assistant-ui's primitives and runtime.
18
+ </Callout>
19
+
20
+ ## Prerequisites
21
+
22
+ <Callout type="info">
23
+ You need an assistant-cloud account to follow this guide. [Sign up here](https://cloud.assistant-ui.com/) to get started.
24
+ </Callout>
25
+
26
+ ## Setup
27
+
28
+ <Steps>
29
+
30
+ <Step>
31
+
32
+ ### Create a Cloud Project
33
+
34
+ Create a new project in the [assistant-cloud dashboard](https://cloud.assistant-ui.com/) and from the settings page, copy your **Frontend API URL** (`https://proj-[ID].assistant-api.com`).
35
+
36
+ </Step>
37
+
38
+ <Step>
39
+
40
+ ### Configure Environment Variables
41
+
42
+ ```bash title=".env.local"
43
+ NEXT_PUBLIC_ASSISTANT_BASE_URL=https://proj-[YOUR-ID].assistant-api.com
44
+ ```
45
+
46
+ </Step>
47
+
48
+ <Step>
49
+
50
+ ### Install Dependencies
51
+
52
+ <InstallCommand npm={["@assistant-ui/cloud-ai-sdk", "assistant-cloud", "@ai-sdk/react", "ai"]} />
53
+
54
+ </Step>
55
+
56
+ <Step>
57
+
58
+ ### Integrate
59
+
60
+ ```tsx title="app/page.tsx"
61
+ "use client";
62
+
63
+ import { useState } from "react";
64
+ import { useCloudChat } from "@assistant-ui/cloud-ai-sdk";
65
+
66
+ export default function Chat() {
67
+ // Zero-config: auto-initializes anonymous cloud from env var with built-in threads.
68
+ // For custom config, pass: { cloud, threads: useThreads(...), onSyncError }
69
+ const { messages, sendMessage, threads } = useCloudChat();
70
+
71
+ const [input, setInput] = useState("");
72
+ const handleSubmit = () => {
73
+ if (!input.trim()) return;
74
+ sendMessage({ text: input });
75
+ setInput("");
76
+ };
77
+
78
+ return (
79
+ <div>
80
+ {/* Thread list */}
81
+ <ul>
82
+ {threads.threads.map((t) => (
83
+ <li key={t.id} onClick={() => threads.selectThread(t.id)}>
84
+ {t.title || "New conversation"}
85
+ </li>
86
+ ))}
87
+ <li onClick={() => threads.selectThread(null)}>New chat</li>
88
+ </ul>
89
+
90
+ {/* Chat messages */}
91
+ <div>
92
+ {messages.map((m) => (
93
+ <div key={m.id}>
94
+ {m.parts.map((p) => p.type === "text" && p.text)}
95
+ </div>
96
+ ))}
97
+ </div>
98
+
99
+ {/* Composer */}
100
+ <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
101
+ <input value={input} onChange={(e) => setInput(e.target.value)} />
102
+ <button type="submit">Send</button>
103
+ </form>
104
+ </div>
105
+ );
106
+ }
107
+ ```
108
+
109
+ </Step>
110
+
111
+ </Steps>
112
+
113
+ That's it. Messages persist automatically as they complete, and switching threads loads the full history.
114
+
115
+ ## API Reference
116
+
117
+ ### `useCloudChat(options?)`
118
+
119
+ Wraps AI SDK's `useChat` with automatic cloud persistence and built-in thread management. Messages are persisted as they finish streaming. Thread creation is automatic on the first message — the hook will auto-create the thread, select it, refresh the thread list, and generate a title after the first response.
120
+
121
+ #### Configuration Modes
122
+
123
+ **1. Zero-config** — Set `NEXT_PUBLIC_ASSISTANT_BASE_URL` env var, call with no args:
124
+
125
+ ```tsx
126
+ const chat = useCloudChat();
127
+ ```
128
+
129
+ **2. Custom cloud instance** — For authenticated users or custom configuration:
130
+
131
+ ```tsx
132
+ const cloud = new AssistantCloud({ baseUrl, authToken });
133
+ const chat = useCloudChat({ cloud });
134
+ ```
135
+
136
+ **3. External thread management** — When threads need to be accessed from a separate component or you need custom thread options like `includeArchived`:
137
+
138
+ ```tsx
139
+ // In a context provider or parent component
140
+ const myThreads = useThreads({ cloud, includeArchived: true });
141
+
142
+ // Pass to useCloudChat - it will use your thread state
143
+ const chat = useCloudChat({ threads: myThreads });
144
+ ```
145
+
146
+ #### Parameters
147
+
148
+ | Parameter | Type | Description |
149
+ |-----------|------|-------------|
150
+ | `options.cloud` | `AssistantCloud` | Cloud instance (optional — auto-creates anonymous instance from `NEXT_PUBLIC_ASSISTANT_BASE_URL` env var if not provided) |
151
+ | `options.threads` | `UseThreadsResult` | External thread management from `useThreads()`. Use when you need thread operations in a separate component or custom thread options like `includeArchived` |
152
+ | `options.onSyncError` | `(error: Error) => void` | Callback invoked when a sync error occurs |
153
+
154
+ All other [AI SDK `useChat` options](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-chat) are also accepted.
155
+
156
+ **Returns:** `UseCloudChatResult`
157
+
158
+ | Value | Type | Description |
159
+ |-------|------|-------------|
160
+ | `messages` | `UIMessage[]` | Chat messages (from AI SDK) |
161
+ | `status` | `string` | Chat status: `"ready"`, `"submitted"`, `"streaming"`, or `"error"` |
162
+ | `sendMessage` | `(message, options?) => Promise<void>` | Send a message (auto-creates thread if needed) |
163
+ | `stop` | `() => void` | Stop the current stream |
164
+ | `threads` | `UseThreadsResult` | Thread management (see below) |
165
+
166
+ Plus all other properties from AI SDK's [`UseChatHelpers`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-chat).
167
+
168
+ **Thread management (`threads`):**
169
+
170
+ | Value | Type | Description |
171
+ |-------|------|-------------|
172
+ | `threads.threads` | `CloudThread[]` | Active threads sorted by recency |
173
+ | `threads.threadId` | `string \| null` | Current thread ID (`null` for a new unsaved chat) |
174
+ | `threads.selectThread` | `(id: string \| null) => void` | Switch threads or pass `null` for a new chat |
175
+ | `threads.isLoading` | `boolean` | `true` during initial load or refresh |
176
+ | `threads.error` | `Error \| null` | Last error, if any |
177
+ | `threads.refresh` | `() => Promise<boolean>` | Re-fetch the thread list |
178
+ | `threads.delete` | `(id: string) => Promise<boolean>` | Delete a thread |
179
+ | `threads.rename` | `(id: string, title: string) => Promise<boolean>` | Rename a thread |
180
+ | `threads.archive` | `(id: string) => Promise<boolean>` | Archive a thread |
181
+ | `threads.unarchive` | `(id: string) => Promise<boolean>` | Unarchive a thread |
182
+ | `threads.generateTitle` | `(threadId: string) => Promise<string \| null>` | Generate a title using AI |
183
+
184
+ ### `useThreads(options)`
185
+
186
+ Thread list management for use with `useCloudChat`. Call this explicitly and pass to `useCloudChat({ threads })` when you need access to thread operations outside the chat context (e.g., in a separate sidebar component).
187
+
188
+ ```tsx
189
+ const myThreads = useThreads({ cloud: myCloud });
190
+ const { messages, sendMessage } = useCloudChat({ threads: myThreads });
191
+ ```
192
+
193
+ **Parameters:**
194
+
195
+ | Parameter | Type | Description |
196
+ |-----------|------|-------------|
197
+ | `options.cloud` | `AssistantCloud` | Cloud client instance |
198
+ | `options.includeArchived` | `boolean` | Include archived threads (default: `false`) |
199
+ | `options.enabled` | `boolean` | Enable thread fetching (default: `true`) |
200
+
201
+ **Returns:** `UseThreadsResult` — same shape as `threads` from `useCloudChat()`.
202
+
203
+ ## Telemetry
204
+
205
+ The `useCloudChat` hook automatically reports run telemetry to Assistant Cloud after each assistant response. This includes:
206
+
207
+ **Automatically captured:**
208
+ - `status` — `"completed"` or `"incomplete"` based on response content
209
+ - `tool_calls` — Tool invocations with name, arguments, results, and source (MCP, frontend, or backend)
210
+ - `total_steps` — Number of reasoning/tool steps in the response
211
+ - `output_text` — Full response text (truncated at 50K characters)
212
+
213
+ **Requires route configuration:**
214
+ - `model_id` — The model used for the response
215
+ - `input_tokens` / `output_tokens` — Token usage statistics
216
+
217
+ To capture model and usage data, configure the `messageMetadata` callback in your AI SDK route:
218
+
219
+ ```tsx title="app/api/chat/route.ts"
220
+ import { streamText } from "ai";
221
+
222
+ export async function POST(req: Request) {
223
+ const result = streamText({
224
+ model: openai("gpt-5-mini"),
225
+ messages,
226
+ });
227
+
228
+ return result.toUIMessageStreamResponse({
229
+ messageMetadata: ({ part }) => {
230
+ if (part.type === "finish-step") {
231
+ return {
232
+ modelId: part.response.modelId,
233
+ usage: part.usage,
234
+ };
235
+ }
236
+ return undefined;
237
+ },
238
+ });
239
+ }
240
+ ```
241
+
242
+ <Callout type="info">
243
+ The standalone hook does not capture `duration_ms`, per-step breakdowns (`steps`), custom `metadata` pass-through, or `"error"` status. These require the full runtime integration available via [`useChatRuntime`](/docs/cloud/ai-sdk-assistant-ui).
244
+ </Callout>
245
+
246
+ ### Customizing Reports
247
+
248
+ Use the `beforeReport` hook to enrich or filter telemetry:
249
+
250
+ ```tsx
251
+ const cloud = new AssistantCloud({
252
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
253
+ telemetry: {
254
+ beforeReport: (report) => ({
255
+ ...report,
256
+ metadata: { environment: "production", version: "1.0.0" },
257
+ }),
258
+ },
259
+ });
260
+ ```
261
+
262
+ Return `null` from `beforeReport` to skip reporting a specific run. To disable telemetry entirely, pass `telemetry: false`.
263
+
264
+ ## Authentication
265
+
266
+ The example above uses anonymous mode (browser session-based user ID) via the env var. For production apps with user accounts, pass an explicit cloud instance:
267
+
268
+ ```tsx
269
+ import { useAuth } from "@clerk/nextjs";
270
+ import { AssistantCloud } from "assistant-cloud";
271
+ import { useCloudChat } from "@assistant-ui/cloud-ai-sdk";
272
+
273
+ function Chat() {
274
+ const { getToken } = useAuth();
275
+
276
+ const cloud = useMemo(() => new AssistantCloud({
277
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
278
+ authToken: async () => getToken({ template: "assistant-ui" }),
279
+ }), [getToken]);
280
+
281
+ const { messages, sendMessage, threads } = useCloudChat({ cloud });
282
+ // ...
283
+ }
284
+ ```
285
+
286
+ See the [Cloud Authorization](/docs/cloud/authorization) guide for other auth providers.
287
+
288
+ ## Next Steps
289
+
290
+ - If you want pre-built UI components, see [AI SDK + assistant-ui](/docs/cloud/ai-sdk-assistant-ui) for the full integration
291
+ - Learn about [user authentication](/docs/cloud/authorization) for multi-user applications
292
+ - Check out the [complete example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-cloud-standalone) on GitHub
@@ -3,139 +3,133 @@ title: User Authorization
3
3
  description: Configure workspace auth tokens and integrate with auth providers.
4
4
  ---
5
5
 
6
- The assistant-ui API can be directly accessed by your frontend. This elliminates the need for a backend server from your side, except for authorization of your users.
6
+ The Assistant Cloud API is accessed directly from your frontend. This eliminates the need for a backend server for most operations—except for authorizing your users.
7
7
 
8
- This document explains how you can setup your server to authorize users to access the assistant-ui API.
8
+ This guide explains how to set up user authentication and authorization for Assistant Cloud.
9
9
 
10
10
  ## Workspaces
11
11
 
12
- Authorization is granted to a workspace. Depending on the structure of your app, you might want to use user_ids as the workspace_id, or you might want to use a more complex structure.
13
- For example, if your app supports multiple "projects", you might want to use the project_id + user_id as the workspace id (thread history scoped to user+project pairs).
12
+ Authorization is granted to a **workspace**. A workspace is a scope that contains threads and messages. Most commonly:
14
13
 
15
- ## Workspace Auth Tokens
14
+ - Use a `userId` as the workspace for personal chats
15
+ - Use `orgId + userId` for organization-scoped conversations
16
+ - Use `projectId + userId` for project-based apps
16
17
 
17
- assistant-ui issues workspace auth tokens. These tokens give access to the assistant-ui API for a specific workspace.
18
- Tokens are short lived (5 minutes), so the client needs to periodically request a new token (handled by assistant-ui).
18
+ ## Authentication Approaches
19
19
 
20
- There are two supported approaches to obtain a workspace auth token:
20
+ Choose the approach that fits your app:
21
21
 
22
- - Direct integration with your auth provider
23
- - From a backend server / serverless function
22
+ | Approach | Best For | Complexity |
23
+ |----------|----------|------------|
24
+ | **Direct auth provider integration** | Supported providers (Clerk, Auth0, Supabase, etc.) | Low |
25
+ | **Backend server** | Custom auth, multi-user workspaces, or self-hosted solutions | Medium |
26
+ | **Anonymous mode** | Demos, prototypes, or testing | None |
24
27
 
25
- ### Choosing the right approach
28
+ ### Direct Integration with Auth Provider
26
29
 
27
- Direct integration with your auth provider:
30
+ In the Assistant Cloud dashboard, go to **Auth Integrations** and add your provider. This sets up automatic workspace assignment based on the user's ID from your auth provider.
28
31
 
29
- - simpler to setup and maintain
30
- - assigns a workspace_id to every user (by using the user_id as the workspace_id)
31
- - requires a supported auth provider (Clerk, Auth0, Supabase, Firebase, Stytch, Kinde, ...)
32
-
33
- Backend server:
34
-
35
- - more complex to setup
36
- - more flexible workspace structure (multi-user workspaces, workspaces per project, etc.)
37
- - supports self hosted auth solutions, e.g. Auth.js
38
- - requires a backend server / serverless function
39
-
40
- You can always switch between the two approaches without any downtime or necessary database migrations.
41
- Choose direct integration with your auth provider if you can. Otherwise, use a backend server.
42
-
43
- ### Auth Provider Integration
44
- In the AssistantUI dashboard, go to the "Auth Integrations" tab and add a new integration.
45
- Follow the steps to add your auth provider. (See the auth providers we have guides for at the bottom of this page.)
46
-
47
- Then, pass in a function to `authToken` that returns an ID token from your auth provider.
32
+ Then pass an `authToken` function that returns your provider's ID token:
48
33
 
49
34
  ```ts
50
35
  import { AssistantCloud } from "@assistant-ui/react";
51
36
 
52
- const assistantCloud = new AssistantCloud({
53
- authToken: () => JWT_TOKEN
37
+ const cloud = new AssistantCloud({
38
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
39
+ authToken: () => getTokenFromYourProvider(), // Returns JWT
54
40
  });
55
41
  ```
56
42
 
57
- ### Integration with an Auth Provider
43
+ ### Backend Server Approach
58
44
 
59
- #### Backend API Endpoint
45
+ Use this when you need custom workspace logic or unsupported auth providers.
60
46
 
61
- The following is an api route example to create an auth token based on an authenticated user's orgId and userId.
47
+ <Steps>
48
+ <Step>
62
49
 
63
- In the Assistant Cloud dashboard, go to the "API Keys" tab and add a new API key, add the key the environment variable `ASSISTANT_API_KEY=[KEY]`
50
+ #### Create an API Key
51
+
52
+ In the Assistant Cloud dashboard, go to **API Keys** and create a key. Add it to your environment:
53
+
54
+ ```bash
55
+ ASSISTANT_API_KEY=your_key_here
56
+ ```
57
+
58
+ </Step>
59
+ <Step>
60
+
61
+ #### Create the Token Endpoint
64
62
 
65
63
  ```ts title="/app/api/assistant-ui-token/route.ts"
66
- import { AssistantCloud } from "@assistant-ui/react";
67
- import { auth } from "@clerk/nextjs/server";
68
-
64
+ import { AssistantCloud } from "assistant-cloud";
65
+ import { auth } from "@clerk/nextjs/server"; // Or your auth provider
66
+
69
67
  export const POST = async (req: Request) => {
70
68
  const { userId, orgId } = await auth();
71
-
72
- if (!userId) throw new Error("User not authenticated");
73
-
69
+
70
+ if (!userId) return new Response("Unauthorized", { status: 401 });
71
+
72
+ // Define your workspace ID based on your app's structure
74
73
  const workspaceId = orgId ? `${orgId}_${userId}` : userId;
74
+
75
75
  const assistantCloud = new AssistantCloud({
76
- apiKey: process.env["ASSISTANT_API_KEY"]!,
76
+ apiKey: process.env.ASSISTANT_API_KEY!,
77
77
  userId,
78
78
  workspaceId,
79
79
  });
80
- const {token} = await assistantCloud.auth.tokens.create();
81
80
 
81
+ const { token } = await assistantCloud.auth.tokens.create();
82
82
  return new Response(token);
83
83
  };
84
84
  ```
85
85
 
86
- #### Frontend Implementation
86
+ </Step>
87
+ <Step>
87
88
 
88
- The following is an api route example to create an auth token based on an authenticated user's orgId and userId.
89
+ #### Use the Token on the Frontend
89
90
 
90
- ```ts title="client.ts"
91
+ ```tsx title="app/chat/page.tsx"
91
92
  const cloud = new AssistantCloud({
92
- baseUrl: process.env["NEXT_PUBLIC_ASSISTANT_BASE_URL"]!,
93
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
93
94
  authToken: () =>
94
- fetch("/api/assistant-ui-token", { method: "POST" }).then((r) =>
95
- r.text(),
96
- ),
95
+ fetch("/api/assistant-ui-token", { method: "POST" }).then((r) => r.text()),
97
96
  });
98
97
 
99
98
  const runtime = useChatRuntime({
100
- api: "/api/chat",
101
99
  cloud,
102
100
  });
103
101
  ```
104
102
 
105
- ### Anonymous (without auth provider) Frontend Implementation
103
+ </Step>
104
+ </Steps>
106
105
 
107
- The following is a example to get auth tokens for Clerk based on the org_id and user_id:
106
+ ### Anonymous Mode (No Auth)
108
107
 
109
- ```ts title="/app/api/assistant-ui-token/route.ts"
108
+ For demos or testing, use anonymous mode to create browser-session-based users:
109
+
110
+ ```tsx
110
111
  import { AssistantCloud } from "@assistant-ui/react";
111
112
 
112
113
  const cloud = new AssistantCloud({
113
- baseUrl: process.env["NEXT_PUBLIC_ASSISTANT_BASE_URL"]!,
114
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
114
115
  anonymous: true,
115
116
  });
117
+ ```
116
118
 
117
- const runtime = useChatRuntime({
118
- api: "/api/chat",
119
- cloud,
120
- });
121
-
122
- return (
123
- <AssistantRuntimeProvider runtime={runtime}>
124
- <div className="grid h-dvh grid-cols-[200px_1fr] gap-x-2 px-4 py-4">
125
- <ThreadList />
126
- <MyThread />
127
- </div>
128
- </AssistantRuntimeProvider>
129
- );
119
+ <Callout type="warning">
120
+ Anonymous mode creates a new user for each browser session. Threads won't persist across sessions or devices. Use this only for prototyping.
121
+ </Callout>
130
122
 
131
- ```
123
+ ## Auth Provider Examples
132
124
 
125
+ ### Clerk
133
126
 
134
- ### Setting up the Clerk Auth Provider
127
+ <Steps>
128
+ <Step>
135
129
 
136
- First, go to the Clerk dashboard and under "Configure" tab, "JWT Templates" section, create a new template. Choose a blank template and name it "assistant-ui".
130
+ #### Configure the JWT Template
137
131
 
138
- As the "Claims" field, enter the following:
132
+ In the Clerk dashboard, go to **Configure → JWT Templates**. Create a new blank template named "assistant-ui":
139
133
 
140
134
  ```json
141
135
  {
@@ -143,11 +137,116 @@ As the "Claims" field, enter the following:
143
137
  }
144
138
  ```
145
139
 
146
- <Callout emoji="⚠️">
147
- <b>Note:</b> The aud claim ensures that the JWT is only valid for the
148
- assistant-ui API.
140
+ <Callout type="info">
141
+ The `aud` claim ensures the JWT is only valid for Assistant Cloud.
149
142
  </Callout>
150
143
 
151
- You can leave everything else as default. Take note of the "Issuer" and "JWKS Endpoint" fields.
144
+ Note the **Issuer** and **JWKS Endpoint** values.
145
+
146
+ </Step>
147
+ <Step>
148
+
149
+ #### Add Auth Integration in Assistant Cloud
150
+
151
+ In the Assistant Cloud dashboard, go to **Auth Rules** and create a new rule:
152
+
153
+ - **Provider**: Clerk
154
+ - **Issuer**: Paste from Clerk JWT Template
155
+ - **JWKS Endpoint**: Paste from Clerk JWT Template
156
+ - **Audience**: `assistant-ui`
157
+
158
+ </Step>
159
+ <Step>
152
160
 
153
- Then, In the assistant-cloud dashboard, navigate to the "Auth Rules" tab and create a new rule. Choose "Clerk" and enter the Issuer and JWKS Endpoint from the previous step. As the "Audience" field, enter "assistant-ui".
161
+ #### Use in Your App
162
+
163
+ ```tsx
164
+ import { useAuth } from "@clerk/nextjs";
165
+ import { AssistantCloud } from "@assistant-ui/react";
166
+
167
+ function Chat() {
168
+ const { getToken } = useAuth();
169
+
170
+ const cloud = useMemo(
171
+ () =>
172
+ new AssistantCloud({
173
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
174
+ authToken: () => getToken({ template: "assistant-ui" }),
175
+ }),
176
+ [getToken],
177
+ );
178
+
179
+ // Use with your runtime...
180
+ }
181
+ ```
182
+
183
+ </Step>
184
+ </Steps>
185
+
186
+ ### Auth0
187
+
188
+ ```tsx
189
+ import { useAuth0 } from "@auth0/auth0-react";
190
+ import { AssistantCloud } from "@assistant-ui/react";
191
+
192
+ function Chat() {
193
+ const { getAccessTokenSilently } = useAuth0();
194
+
195
+ const cloud = useMemo(
196
+ () =>
197
+ new AssistantCloud({
198
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
199
+ authToken: () => getAccessTokenSilently(),
200
+ }),
201
+ [getAccessTokenSilently],
202
+ );
203
+
204
+ // Use with your runtime...
205
+ }
206
+ ```
207
+
208
+ Configure the Auth0 integration in the Assistant Cloud dashboard with your Auth0 domain and audience.
209
+
210
+ ### Supabase Auth
211
+
212
+ ```tsx
213
+ import { useSupabaseClient } from "@supabase/auth-helpers-react";
214
+ import { AssistantCloud } from "@assistant-ui/react";
215
+
216
+ function Chat() {
217
+ const supabase = useSupabaseClient();
218
+
219
+ const cloud = useMemo(
220
+ () =>
221
+ new AssistantCloud({
222
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
223
+ authToken: async () => {
224
+ const { data } = await supabase.auth.getSession();
225
+ return data.session?.access_token ?? "";
226
+ },
227
+ }),
228
+ [supabase],
229
+ );
230
+
231
+ // Use with your runtime...
232
+ }
233
+ ```
234
+
235
+ ### Firebase Auth
236
+
237
+ ```tsx
238
+ import { getAuth, getIdToken } from "firebase/auth";
239
+ import { AssistantCloud } from "@assistant-ui/react";
240
+
241
+ function Chat() {
242
+ const cloud = useMemo(() => {
243
+ const auth = getAuth();
244
+ return new AssistantCloud({
245
+ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
246
+ authToken: () => getIdToken(auth.currentUser!, true),
247
+ });
248
+ }, []);
249
+
250
+ // Use with your runtime...
251
+ }
252
+ ```
@@ -1,12 +1,12 @@
1
1
  ---
2
- title: Chat History for LangGraph Cloud
2
+ title: LangGraph + assistant-ui
3
3
  description: Integrate cloud persistence and thread management with LangGraph Cloud.
4
4
  ---
5
5
 
6
6
 
7
7
  ## Overview
8
8
 
9
- assistant-cloud provides thread management and persistent chat history for applications built with [LangGraph Cloud](https://langchain-ai.github.io/langgraph/cloud/). This guide shows you how to integrate cloud persistence into your LangGraph application.
9
+ This guide shows how to integrate Assistant Cloud with [LangGraph Cloud](https://langchain-ai.github.io/langgraph/cloud/) using assistant-ui's runtime system and pre-built UI components.
10
10
 
11
11
  ## Prerequisites
12
12