@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.
- package/.docs/organized/code-examples/waterfall.md +801 -0
- package/.docs/organized/code-examples/with-ag-ui.md +38 -26
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +38 -28
- package/.docs/organized/code-examples/with-artifacts.md +467 -0
- package/.docs/organized/code-examples/with-assistant-transport.md +31 -24
- package/.docs/organized/code-examples/with-chain-of-thought.md +41 -32
- package/.docs/organized/code-examples/with-cloud-standalone.md +675 -0
- package/.docs/organized/code-examples/with-cloud.md +34 -27
- package/.docs/organized/code-examples/with-custom-thread-list.md +34 -27
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +41 -30
- package/.docs/organized/code-examples/with-expo.md +2031 -0
- package/.docs/organized/code-examples/with-external-store.md +32 -25
- package/.docs/organized/code-examples/with-ffmpeg.md +31 -27
- package/.docs/organized/code-examples/with-langgraph.md +96 -38
- package/.docs/organized/code-examples/with-parent-id-grouping.md +32 -25
- package/.docs/organized/code-examples/with-react-hook-form.md +63 -58
- package/.docs/organized/code-examples/with-react-router.md +38 -30
- package/.docs/organized/code-examples/with-store.md +16 -24
- package/.docs/organized/code-examples/with-tanstack.md +36 -26
- package/.docs/organized/code-examples/with-tap-runtime.md +10 -24
- package/.docs/raw/docs/(docs)/cli.mdx +13 -6
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +26 -3
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +5 -5
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +53 -52
- package/.docs/raw/docs/(docs)/guides/dictation.mdx +0 -2
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +169 -0
- package/.docs/raw/docs/(docs)/guides/quoting.mdx +327 -0
- package/.docs/raw/docs/(docs)/guides/speech.mdx +0 -1
- package/.docs/raw/docs/(docs)/index.mdx +12 -2
- package/.docs/raw/docs/(docs)/installation.mdx +8 -2
- package/.docs/raw/docs/(docs)/llm.mdx +9 -7
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +2 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-if.mdx +27 -27
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +60 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +78 -4
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +32 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/selection-toolbar.mdx +61 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +1 -1
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +1 -6
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +2 -2
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +1 -6
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +1 -5
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +17 -17
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +205 -0
- package/.docs/raw/docs/cloud/ai-sdk.mdx +292 -0
- package/.docs/raw/docs/cloud/authorization.mdx +178 -79
- package/.docs/raw/docs/cloud/{persistence/langgraph.mdx → langgraph.mdx} +2 -2
- package/.docs/raw/docs/cloud/overview.mdx +29 -39
- package/.docs/raw/docs/react-native/adapters.mdx +118 -0
- package/.docs/raw/docs/react-native/custom-backend.mdx +210 -0
- package/.docs/raw/docs/react-native/hooks.mdx +364 -0
- package/.docs/raw/docs/react-native/index.mdx +332 -0
- package/.docs/raw/docs/react-native/primitives.mdx +653 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +7 -15
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +103 -0
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +25 -2
- package/.docs/raw/docs/runtimes/data-stream.mdx +1 -3
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +113 -9
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +1 -4
- package/.docs/raw/docs/ui/attachment.mdx +4 -2
- package/.docs/raw/docs/ui/message-timing.mdx +92 -0
- package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
- package/.docs/raw/docs/ui/reasoning.mdx +4 -4
- package/.docs/raw/docs/ui/scrollbar.mdx +2 -2
- package/.docs/raw/docs/ui/syntax-highlighting.mdx +55 -50
- package/.docs/raw/docs/ui/thread.mdx +16 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/tools/tests/integration.test.ts +2 -2
- package/src/tools/tests/json-parsing.test.ts +1 -1
- package/src/tools/tests/mcp-protocol.test.ts +1 -3
- 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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
+
Choose the approach that fits your app:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
###
|
|
28
|
+
### Direct Integration with Auth Provider
|
|
26
29
|
|
|
27
|
-
|
|
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
|
-
|
|
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
|
|
53
|
-
|
|
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
|
-
###
|
|
43
|
+
### Backend Server Approach
|
|
58
44
|
|
|
59
|
-
|
|
45
|
+
Use this when you need custom workspace logic or unsupported auth providers.
|
|
60
46
|
|
|
61
|
-
|
|
47
|
+
<Steps>
|
|
48
|
+
<Step>
|
|
62
49
|
|
|
63
|
-
|
|
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 "
|
|
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)
|
|
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
|
|
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
|
-
|
|
86
|
+
</Step>
|
|
87
|
+
<Step>
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
#### Use the Token on the Frontend
|
|
89
90
|
|
|
90
|
-
```
|
|
91
|
+
```tsx title="app/chat/page.tsx"
|
|
91
92
|
const cloud = new AssistantCloud({
|
|
92
|
-
baseUrl: process.env
|
|
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
|
-
|
|
103
|
+
</Step>
|
|
104
|
+
</Steps>
|
|
106
105
|
|
|
107
|
-
|
|
106
|
+
### Anonymous Mode (No Auth)
|
|
108
107
|
|
|
109
|
-
|
|
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
|
|
114
|
+
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
|
|
114
115
|
anonymous: true,
|
|
115
116
|
});
|
|
117
|
+
```
|
|
116
118
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
127
|
+
<Steps>
|
|
128
|
+
<Step>
|
|
135
129
|
|
|
136
|
-
|
|
130
|
+
#### Configure the JWT Template
|
|
137
131
|
|
|
138
|
-
|
|
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
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|