@assistant-ui/mcp-docs-server 0.1.23 → 0.1.25
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 +5 -3
- package/.docs/organized/code-examples/with-a2a.md +676 -0
- package/.docs/organized/code-examples/with-ag-ui.md +7 -8
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +28 -16
- package/.docs/organized/code-examples/with-artifacts.md +5 -5
- package/.docs/organized/code-examples/with-assistant-transport.md +3 -3
- package/.docs/organized/code-examples/with-chain-of-thought.md +34 -26
- package/.docs/organized/code-examples/with-cloud-standalone.md +10 -8
- package/.docs/organized/code-examples/with-cloud.md +5 -5
- package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +8 -8
- package/.docs/organized/code-examples/with-expo.md +571 -539
- package/.docs/organized/code-examples/with-external-store.md +3 -4
- package/.docs/organized/code-examples/with-ffmpeg.md +5 -5
- package/.docs/organized/code-examples/with-google-adk.md +353 -0
- package/.docs/organized/code-examples/with-heat-graph.md +304 -0
- package/.docs/organized/code-examples/with-langgraph.md +25 -23
- package/.docs/organized/code-examples/with-parent-id-grouping.md +4 -4
- package/.docs/organized/code-examples/with-react-hook-form.md +6 -9
- package/.docs/organized/code-examples/with-react-ink.md +265 -0
- package/.docs/organized/code-examples/with-react-router.md +10 -11
- package/.docs/organized/code-examples/with-store.md +29 -18
- package/.docs/organized/code-examples/with-tanstack.md +7 -7
- package/.docs/organized/code-examples/with-tap-runtime.md +6 -4
- package/.docs/raw/blog/2025-01-31-changelog/index.mdx +1 -1
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +227 -0
- package/.docs/raw/docs/(docs)/architecture.mdx +1 -1
- package/.docs/raw/docs/(docs)/cli.mdx +14 -9
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +8 -3
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +5 -1
- package/.docs/raw/docs/(docs)/copilots/{make-assistant-readable.mdx → make-assistant-visible.mdx} +14 -5
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +11 -11
- package/.docs/raw/docs/(docs)/copilots/motivation.mdx +2 -2
- package/.docs/raw/docs/(docs)/devtools.mdx +3 -2
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +9 -11
- package/.docs/raw/docs/(docs)/guides/branching.mdx +11 -6
- package/.docs/raw/docs/(docs)/guides/chain-of-thought.mdx +18 -16
- package/.docs/raw/docs/(docs)/guides/context-api.mdx +81 -43
- package/.docs/raw/docs/(docs)/guides/dictation.mdx +5 -5
- package/.docs/raw/docs/(docs)/guides/editing.mdx +16 -7
- package/.docs/raw/docs/(docs)/guides/latex.mdx +3 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +2 -1
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +173 -0
- package/.docs/raw/docs/(docs)/guides/quoting.mdx +55 -206
- package/.docs/raw/docs/(docs)/guides/speech.mdx +1 -4
- package/.docs/raw/docs/(docs)/guides/suggestions.mdx +9 -15
- package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +17 -7
- package/.docs/raw/docs/(docs)/guides/tools.mdx +24 -9
- package/.docs/raw/docs/(docs)/index.mdx +3 -3
- package/.docs/raw/docs/(docs)/installation.mdx +69 -46
- package/.docs/raw/docs/(reference)/api-reference/context-providers/text-message-part-provider.mdx +20 -6
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-data-stream.mdx +24 -4
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-hook-form.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/integrations/vercel-ai-sdk.mdx +20 -19
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +28 -53
- package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar.mdx +4 -4
- package/.docs/raw/docs/(reference)/api-reference/primitives/assistant-modal.mdx +7 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/attachment.mdx +20 -14
- package/.docs/raw/docs/(reference)/api-reference/primitives/branch-picker.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +99 -45
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +52 -40
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +343 -23
- package/.docs/raw/docs/(reference)/api-reference/primitives/suggestion.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item.mdx +4 -2
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list.mdx +3 -5
- package/.docs/raw/docs/(reference)/api-reference/primitives/thread.mdx +169 -22
- package/.docs/raw/docs/(reference)/api-reference/runtimes/assistant-runtime.mdx +14 -4
- package/.docs/raw/docs/(reference)/api-reference/runtimes/attachment-runtime.mdx +15 -26
- package/.docs/raw/docs/(reference)/api-reference/runtimes/composer-runtime.mdx +39 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-part-runtime.mdx +33 -9
- package/.docs/raw/docs/(reference)/api-reference/runtimes/message-runtime.mdx +48 -21
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-item-runtime.mdx +36 -7
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-list-runtime.mdx +30 -10
- package/.docs/raw/docs/(reference)/api-reference/runtimes/thread-runtime.mdx +12 -10
- package/.docs/raw/docs/(reference)/migrations/deprecation-policy.mdx +1 -1
- package/.docs/raw/docs/(reference)/migrations/react-langgraph-v0-7.mdx +9 -4
- package/.docs/raw/docs/(reference)/migrations/v0-11.mdx +7 -5
- package/.docs/raw/docs/(reference)/migrations/v0-12.mdx +9 -7
- package/.docs/raw/docs/(reference)/migrations/v0-14.mdx +159 -0
- package/.docs/raw/docs/(reference)/react-compatibility.mdx +5 -134
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +89 -7
- package/.docs/raw/docs/cloud/ai-sdk.mdx +19 -5
- package/.docs/raw/docs/cloud/langgraph.mdx +13 -3
- package/.docs/raw/docs/ink/adapters.mdx +41 -0
- package/.docs/raw/docs/ink/custom-backend.mdx +203 -0
- package/.docs/raw/docs/ink/hooks.mdx +448 -0
- package/.docs/raw/docs/ink/index.mdx +239 -0
- package/.docs/raw/docs/ink/migration.mdx +140 -0
- package/.docs/raw/docs/ink/primitives.mdx +699 -0
- package/.docs/raw/docs/react-native/adapters.mdx +63 -87
- package/.docs/raw/docs/react-native/custom-backend.mdx +11 -14
- package/.docs/raw/docs/react-native/hooks.mdx +214 -232
- package/.docs/raw/docs/react-native/index.mdx +118 -159
- package/.docs/raw/docs/react-native/migration.mdx +144 -0
- package/.docs/raw/docs/react-native/primitives.mdx +431 -302
- package/.docs/raw/docs/runtimes/a2a/index.mdx +294 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +9 -9
- package/.docs/raw/docs/runtimes/ai-sdk/v5-legacy.mdx +14 -3
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +53 -0
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +59 -25
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +13 -6
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +138 -38
- package/.docs/raw/docs/runtimes/custom/local.mdx +184 -42
- package/.docs/raw/docs/runtimes/data-stream.mdx +92 -19
- package/.docs/raw/docs/runtimes/google-adk/index.mdx +624 -0
- package/.docs/raw/docs/runtimes/helicone.mdx +6 -6
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +38 -27
- package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +15 -20
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +7 -11
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +8 -11
- package/.docs/raw/docs/runtimes/langserve.mdx +6 -7
- package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +18 -3
- package/.docs/raw/docs/ui/context-display.mdx +147 -0
- package/.docs/raw/docs/ui/file.mdx +5 -4
- package/.docs/raw/docs/ui/image.mdx +5 -4
- package/.docs/raw/docs/ui/markdown.mdx +3 -1
- package/.docs/raw/docs/ui/model-selector.mdx +8 -8
- package/.docs/raw/docs/ui/part-grouping.mdx +7 -10
- package/.docs/raw/docs/ui/quote.mdx +210 -0
- package/.docs/raw/docs/ui/reasoning.mdx +12 -11
- package/.docs/raw/docs/ui/sources.mdx +88 -17
- package/.docs/raw/docs/ui/streamdown.mdx +16 -7
- package/.docs/raw/docs/ui/thread-list.mdx +11 -13
- package/.docs/raw/docs/ui/thread.mdx +28 -33
- package/.docs/raw/docs/ui/tool-fallback.mdx +5 -6
- package/.docs/raw/docs/ui/tool-group.mdx +9 -8
- package/.docs/raw/docs/utilities/heat-graph.mdx +236 -0
- package/.docs/raw/docs/utilities/tw-shimmer.mdx +211 -0
- package/package.json +4 -4
- package/.docs/raw/docs/(reference)/legacy/styled/assistant-modal.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/decomposition.mdx +0 -635
- package/.docs/raw/docs/(reference)/legacy/styled/markdown.mdx +0 -77
- package/.docs/raw/docs/(reference)/legacy/styled/scrollbar.mdx +0 -72
- package/.docs/raw/docs/(reference)/legacy/styled/thread-width.mdx +0 -22
- package/.docs/raw/docs/(reference)/legacy/styled/thread.mdx +0 -77
- /package/.docs/raw/docs/cloud/{overview.mdx → index.mdx} +0 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Google ADK
|
|
3
|
+
description: Connect to Google ADK (Agent Development Kit) agents with streaming, tool calls, and multi-agent support.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
The `@assistant-ui/react-google-adk` package provides integration with [Google ADK JS](https://github.com/google/adk-js), Google's official agent framework for TypeScript. It supports streaming text, tool calls, multi-agent orchestration, code execution, session state, tool confirmations, auth flows, and more.
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
You need a Google ADK agent running on a server. ADK supports `LlmAgent` with Gemini models, tool use, multi-agent orchestration (sequential, parallel, loop agents), and session management.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
<InstallCommand npm={["@assistant-ui/react", "@assistant-ui/react-google-adk", "@google/adk"]} />
|
|
15
|
+
|
|
16
|
+
<Callout type="info">
|
|
17
|
+
`@google/adk` is only needed on the server side. The client-side runtime has no dependency on it.
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
20
|
+
## Getting Started
|
|
21
|
+
|
|
22
|
+
<Steps>
|
|
23
|
+
<Step>
|
|
24
|
+
|
|
25
|
+
### Create a backend API endpoint
|
|
26
|
+
|
|
27
|
+
Use `createAdkApiRoute` to create an API route in one line:
|
|
28
|
+
|
|
29
|
+
```typescript title="app/api/chat/route.ts"
|
|
30
|
+
import { createAdkApiRoute } from "@assistant-ui/react-google-adk/server";
|
|
31
|
+
import { InMemoryRunner, LlmAgent } from "@google/adk";
|
|
32
|
+
|
|
33
|
+
const agent = new LlmAgent({
|
|
34
|
+
name: "my_agent",
|
|
35
|
+
model: "gemini-2.5-flash",
|
|
36
|
+
instruction: "You are a helpful assistant.",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const runner = new InMemoryRunner({ agent, appName: "my-app" });
|
|
40
|
+
|
|
41
|
+
export const POST = createAdkApiRoute({
|
|
42
|
+
runner,
|
|
43
|
+
userId: "user_1",
|
|
44
|
+
sessionId: (req) =>
|
|
45
|
+
new URL(req.url).searchParams.get("sessionId") ?? "default",
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
</Step>
|
|
50
|
+
<Step>
|
|
51
|
+
|
|
52
|
+
### Set up the client runtime
|
|
53
|
+
|
|
54
|
+
Use `createAdkStream` to connect to your API route — no manual SSE parsing needed:
|
|
55
|
+
|
|
56
|
+
```tsx title="components/MyAssistant.tsx"
|
|
57
|
+
"use client";
|
|
58
|
+
|
|
59
|
+
import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
60
|
+
import {
|
|
61
|
+
useAdkRuntime,
|
|
62
|
+
createAdkStream,
|
|
63
|
+
} from "@assistant-ui/react-google-adk";
|
|
64
|
+
import { Thread } from "@/components/assistant-ui/thread";
|
|
65
|
+
|
|
66
|
+
export function MyAssistant() {
|
|
67
|
+
const runtime = useAdkRuntime({
|
|
68
|
+
stream: createAdkStream({ api: "/api/chat" }),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
73
|
+
<Thread />
|
|
74
|
+
</AssistantRuntimeProvider>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
</Step>
|
|
80
|
+
<Step>
|
|
81
|
+
|
|
82
|
+
### Use the component
|
|
83
|
+
|
|
84
|
+
```tsx title="app/page.tsx"
|
|
85
|
+
import { MyAssistant } from "@/components/MyAssistant";
|
|
86
|
+
|
|
87
|
+
export default function Home() {
|
|
88
|
+
return (
|
|
89
|
+
<main className="h-dvh">
|
|
90
|
+
<MyAssistant />
|
|
91
|
+
</main>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
</Step>
|
|
97
|
+
<Step>
|
|
98
|
+
|
|
99
|
+
### Setup UI components
|
|
100
|
+
|
|
101
|
+
Follow the [UI Components](/docs/ui/thread) guide to setup the Thread and other UI components.
|
|
102
|
+
|
|
103
|
+
</Step>
|
|
104
|
+
</Steps>
|
|
105
|
+
|
|
106
|
+
## `createAdkStream`
|
|
107
|
+
|
|
108
|
+
Creates an `AdkStreamCallback` that connects to an ADK endpoint via SSE. Supports two modes:
|
|
109
|
+
|
|
110
|
+
**Proxy mode** — POST to your own API route:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { createAdkStream } from "@assistant-ui/react-google-adk";
|
|
114
|
+
|
|
115
|
+
const stream = createAdkStream({ api: "/api/chat" });
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Direct mode** — connect directly to an ADK server:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const stream = createAdkStream({
|
|
122
|
+
api: "http://localhost:8000",
|
|
123
|
+
appName: "my-app",
|
|
124
|
+
userId: "user-1",
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
| Option | Type | Description |
|
|
129
|
+
|--------|------|-------------|
|
|
130
|
+
| `api` | `string` | URL to POST to (proxy route or ADK server base URL) |
|
|
131
|
+
| `appName` | `string?` | ADK app name (enables direct mode when set) |
|
|
132
|
+
| `userId` | `string?` | ADK user ID (required with `appName`) |
|
|
133
|
+
| `headers` | `Record<string, string> \| (() => ...)` | Static or dynamic request headers |
|
|
134
|
+
|
|
135
|
+
## Direct ADK Server Connection
|
|
136
|
+
|
|
137
|
+
When connecting directly to an ADK server (without a proxy API route), use `createAdkSessionAdapter` to back your thread list with ADK sessions:
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import {
|
|
141
|
+
useAdkRuntime,
|
|
142
|
+
createAdkStream,
|
|
143
|
+
createAdkSessionAdapter,
|
|
144
|
+
} from "@assistant-ui/react-google-adk";
|
|
145
|
+
|
|
146
|
+
const ADK_URL = "http://localhost:8000";
|
|
147
|
+
|
|
148
|
+
const { adapter, load, artifacts } = createAdkSessionAdapter({
|
|
149
|
+
apiUrl: ADK_URL,
|
|
150
|
+
appName: "my-app",
|
|
151
|
+
userId: "user-1",
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const runtime = useAdkRuntime({
|
|
155
|
+
stream: createAdkStream({
|
|
156
|
+
api: ADK_URL,
|
|
157
|
+
appName: "my-app",
|
|
158
|
+
userId: "user-1",
|
|
159
|
+
}),
|
|
160
|
+
sessionAdapter: adapter,
|
|
161
|
+
load,
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The session adapter maps ADK sessions to assistant-ui threads:
|
|
166
|
+
|
|
167
|
+
- **`adapter`** — a `RemoteThreadListAdapter` that uses ADK's session REST API for thread CRUD
|
|
168
|
+
- **`load`** — reconstructs messages from session events via `AdkEventAccumulator`
|
|
169
|
+
- **`artifacts`** — functions to fetch, list, and delete session artifacts (see [Artifact Fetching](#artifact-fetching))
|
|
170
|
+
|
|
171
|
+
| Option | Type | Description |
|
|
172
|
+
|--------|------|-------------|
|
|
173
|
+
| `apiUrl` | `string` | ADK server base URL |
|
|
174
|
+
| `appName` | `string` | ADK app name |
|
|
175
|
+
| `userId` | `string` | ADK user ID |
|
|
176
|
+
| `headers` | `Record<string, string> \| (() => ...)` | Static or dynamic request headers |
|
|
177
|
+
|
|
178
|
+
## Server Helpers
|
|
179
|
+
|
|
180
|
+
### `createAdkApiRoute`
|
|
181
|
+
|
|
182
|
+
One-liner API route handler that combines request parsing and SSE streaming:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { createAdkApiRoute } from "@assistant-ui/react-google-adk/server";
|
|
186
|
+
|
|
187
|
+
export const POST = createAdkApiRoute({
|
|
188
|
+
runner,
|
|
189
|
+
userId: "default-user",
|
|
190
|
+
sessionId: (req) =>
|
|
191
|
+
new URL(req.url).searchParams.get("sessionId") ?? "default",
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Both `userId` and `sessionId` accept a static string or a function `(req: Request) => string` for dynamic resolution (e.g. from cookies, headers, or query params).
|
|
196
|
+
|
|
197
|
+
### `adkEventStream`
|
|
198
|
+
|
|
199
|
+
Converts an `AsyncGenerator<Event>` from ADK's `Runner.runAsync()` into an SSE `Response`. Sends an initial `:ok` comment to keep connections alive through proxies.
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { adkEventStream } from "@assistant-ui/react-google-adk/server";
|
|
203
|
+
|
|
204
|
+
const events = runner.runAsync({ userId, sessionId, newMessage });
|
|
205
|
+
return adkEventStream(events);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### `parseAdkRequest` / `toAdkContent`
|
|
209
|
+
|
|
210
|
+
Lower-level helpers for custom API routes. Parse incoming requests and convert to ADK's `Content` format. Supports user messages, tool results, `stateDelta`, `checkpointId`, and multimodal content:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { parseAdkRequest, toAdkContent } from "@assistant-ui/react-google-adk/server";
|
|
214
|
+
|
|
215
|
+
const parsed = await parseAdkRequest(req);
|
|
216
|
+
// parsed.type is "message" or "tool-result"
|
|
217
|
+
// parsed.config contains runConfig, checkpointId
|
|
218
|
+
// parsed.stateDelta contains session state changes
|
|
219
|
+
|
|
220
|
+
const newMessage = toAdkContent(parsed);
|
|
221
|
+
const events = runner.runAsync({
|
|
222
|
+
userId,
|
|
223
|
+
sessionId,
|
|
224
|
+
newMessage,
|
|
225
|
+
stateDelta: parsed.stateDelta,
|
|
226
|
+
});
|
|
227
|
+
return adkEventStream(events);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Hooks
|
|
231
|
+
|
|
232
|
+
### Agent & Session State
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import {
|
|
236
|
+
useAdkAgentInfo,
|
|
237
|
+
useAdkSessionState,
|
|
238
|
+
useAdkSend,
|
|
239
|
+
} from "@assistant-ui/react-google-adk";
|
|
240
|
+
|
|
241
|
+
function MyComponent() {
|
|
242
|
+
// Current active agent name and branch path (multi-agent)
|
|
243
|
+
const agentInfo = useAdkAgentInfo();
|
|
244
|
+
// agentInfo?.name = "search_agent"
|
|
245
|
+
// agentInfo?.branch = "root.search_agent"
|
|
246
|
+
|
|
247
|
+
// Accumulated session state delta
|
|
248
|
+
const state = useAdkSessionState();
|
|
249
|
+
|
|
250
|
+
// Send raw ADK messages programmatically
|
|
251
|
+
const send = useAdkSend();
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Tool Confirmations
|
|
256
|
+
|
|
257
|
+
When ADK's `SecurityPlugin` or tool callbacks request user confirmation before executing a tool, use `useAdkToolConfirmations` to read pending requests and `useAdkConfirmTool` to respond:
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import {
|
|
261
|
+
useAdkToolConfirmations,
|
|
262
|
+
useAdkConfirmTool,
|
|
263
|
+
} from "@assistant-ui/react-google-adk";
|
|
264
|
+
|
|
265
|
+
function ToolConfirmationUI() {
|
|
266
|
+
const confirmations = useAdkToolConfirmations();
|
|
267
|
+
const confirmTool = useAdkConfirmTool();
|
|
268
|
+
|
|
269
|
+
if (confirmations.length === 0) return null;
|
|
270
|
+
|
|
271
|
+
return confirmations.map((conf) => (
|
|
272
|
+
<div key={conf.toolCallId}>
|
|
273
|
+
<p>Tool "{conf.toolName}" wants to run. {conf.hint}</p>
|
|
274
|
+
<button onClick={() => confirmTool(conf.toolCallId, true)}>
|
|
275
|
+
Approve
|
|
276
|
+
</button>
|
|
277
|
+
<button onClick={() => confirmTool(conf.toolCallId, false)}>
|
|
278
|
+
Deny
|
|
279
|
+
</button>
|
|
280
|
+
</div>
|
|
281
|
+
));
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Auth Requests
|
|
286
|
+
|
|
287
|
+
When a tool requires OAuth or other authentication, use `useAdkAuthRequests` to read pending requests and `useAdkSubmitAuth` to submit credentials:
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import {
|
|
291
|
+
useAdkAuthRequests,
|
|
292
|
+
useAdkSubmitAuth,
|
|
293
|
+
type AdkAuthCredential,
|
|
294
|
+
} from "@assistant-ui/react-google-adk";
|
|
295
|
+
|
|
296
|
+
function AuthUI() {
|
|
297
|
+
const authRequests = useAdkAuthRequests();
|
|
298
|
+
const submitAuth = useAdkSubmitAuth();
|
|
299
|
+
|
|
300
|
+
if (authRequests.length === 0) return null;
|
|
301
|
+
|
|
302
|
+
return authRequests.map((req) => (
|
|
303
|
+
<div key={req.toolCallId}>
|
|
304
|
+
<button onClick={() => {
|
|
305
|
+
const credential: AdkAuthCredential = {
|
|
306
|
+
authType: "oauth2",
|
|
307
|
+
oauth2: { accessToken: "..." },
|
|
308
|
+
};
|
|
309
|
+
submitAuth(req.toolCallId, credential);
|
|
310
|
+
}}>
|
|
311
|
+
Authenticate
|
|
312
|
+
</button>
|
|
313
|
+
</div>
|
|
314
|
+
));
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
`AdkAuthCredential` supports all ADK auth types: `apiKey`, `http`, `oauth2`, `openIdConnect`, `serviceAccount`.
|
|
319
|
+
|
|
320
|
+
### Artifacts
|
|
321
|
+
|
|
322
|
+
Track file artifacts created or modified by the agent:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { useAdkArtifacts } from "@assistant-ui/react-google-adk";
|
|
326
|
+
|
|
327
|
+
function ArtifactList() {
|
|
328
|
+
const artifacts = useAdkArtifacts();
|
|
329
|
+
// Record<string, number> — filename to version number
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### Artifact Fetching
|
|
334
|
+
|
|
335
|
+
When using `createAdkSessionAdapter`, the returned `artifacts` object provides functions to fetch artifact content from the ADK server:
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
const { artifacts } = createAdkSessionAdapter({ apiUrl, appName, userId });
|
|
339
|
+
|
|
340
|
+
// List all artifact filenames in a session
|
|
341
|
+
const filenames = await artifacts.list(sessionId);
|
|
342
|
+
|
|
343
|
+
// Load artifact content (latest version)
|
|
344
|
+
const data = await artifacts.load(sessionId, "document.pdf");
|
|
345
|
+
// data.inlineData?.data — base64 content
|
|
346
|
+
// data.inlineData?.mimeType — MIME type
|
|
347
|
+
// data.text — text content (if text artifact)
|
|
348
|
+
|
|
349
|
+
// Load a specific version
|
|
350
|
+
const v1 = await artifacts.load(sessionId, "document.pdf", 1);
|
|
351
|
+
|
|
352
|
+
// List all versions
|
|
353
|
+
const versions = await artifacts.listVersions(sessionId, "document.pdf");
|
|
354
|
+
|
|
355
|
+
// Delete an artifact
|
|
356
|
+
await artifacts.delete(sessionId, "document.pdf");
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Escalation
|
|
360
|
+
|
|
361
|
+
Detect when an agent requests escalation to a human operator:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { useAdkEscalation } from "@assistant-ui/react-google-adk";
|
|
365
|
+
|
|
366
|
+
function EscalationBanner() {
|
|
367
|
+
const escalated = useAdkEscalation();
|
|
368
|
+
if (!escalated) return null;
|
|
369
|
+
return <div>Agent has requested human assistance.</div>;
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Long-Running Tools
|
|
374
|
+
|
|
375
|
+
Track tools that are executing asynchronously and awaiting external input:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { useAdkLongRunningToolIds } from "@assistant-ui/react-google-adk";
|
|
379
|
+
|
|
380
|
+
function PendingToolsIndicator() {
|
|
381
|
+
const pendingToolIds = useAdkLongRunningToolIds();
|
|
382
|
+
if (pendingToolIds.length === 0) return null;
|
|
383
|
+
return <div>{pendingToolIds.length} tool(s) awaiting input</div>;
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Per-Message Metadata
|
|
388
|
+
|
|
389
|
+
Access grounding, citation, and token usage metadata per message:
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { useAdkMessageMetadata } from "@assistant-ui/react-google-adk";
|
|
393
|
+
|
|
394
|
+
function MessageMetadata({ messageId }: { messageId: string }) {
|
|
395
|
+
const metadataMap = useAdkMessageMetadata();
|
|
396
|
+
const meta = metadataMap.get(messageId);
|
|
397
|
+
// meta?.groundingMetadata — Google Search grounding sources
|
|
398
|
+
// meta?.citationMetadata — citation references
|
|
399
|
+
// meta?.usageMetadata — token counts
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Session State by Scope
|
|
404
|
+
|
|
405
|
+
ADK uses key prefixes to scope state. These helpers filter and strip the prefix:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import {
|
|
409
|
+
useAdkAppState,
|
|
410
|
+
useAdkUserState,
|
|
411
|
+
useAdkTempState,
|
|
412
|
+
} from "@assistant-ui/react-google-adk";
|
|
413
|
+
|
|
414
|
+
function StateDebug() {
|
|
415
|
+
const appState = useAdkAppState(); // app:* keys (app-level, shared)
|
|
416
|
+
const userState = useAdkUserState(); // user:* keys (user-level)
|
|
417
|
+
const tempState = useAdkTempState(); // temp:* keys (not persisted)
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Use `useAdkSessionState()` for the full unfiltered state delta.
|
|
422
|
+
|
|
423
|
+
## Structured Events
|
|
424
|
+
|
|
425
|
+
Convert raw ADK events into typed, structured events for custom renderers:
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
import {
|
|
429
|
+
toAdkStructuredEvents,
|
|
430
|
+
AdkEventType,
|
|
431
|
+
type AdkStructuredEvent,
|
|
432
|
+
} from "@assistant-ui/react-google-adk";
|
|
433
|
+
|
|
434
|
+
const structured = toAdkStructuredEvents(event);
|
|
435
|
+
for (const e of structured) {
|
|
436
|
+
switch (e.type) {
|
|
437
|
+
case AdkEventType.CONTENT:
|
|
438
|
+
console.log("Text:", e.content);
|
|
439
|
+
break;
|
|
440
|
+
case AdkEventType.THOUGHT:
|
|
441
|
+
console.log("Reasoning:", e.content);
|
|
442
|
+
break;
|
|
443
|
+
case AdkEventType.TOOL_CALL:
|
|
444
|
+
console.log("Tool:", e.call.name, e.call.args);
|
|
445
|
+
break;
|
|
446
|
+
case AdkEventType.ERROR:
|
|
447
|
+
console.error(e.errorMessage);
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
## State Delta
|
|
454
|
+
|
|
455
|
+
Send session state mutations along with messages using `stateDelta`:
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
const send = useAdkSend();
|
|
459
|
+
|
|
460
|
+
// Pre-populate session state before the agent runs
|
|
461
|
+
send(
|
|
462
|
+
[{ id: "1", type: "human", content: "Start task" }],
|
|
463
|
+
{ stateDelta: { taskId: "abc", mode: "verbose" } },
|
|
464
|
+
);
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
This maps to ADK's `stateDelta` parameter on `/run_sse`.
|
|
468
|
+
|
|
469
|
+
## RunConfig
|
|
470
|
+
|
|
471
|
+
Pass `AdkRunConfig` to control agent behavior:
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
const send = useAdkSend();
|
|
475
|
+
|
|
476
|
+
send(messages, {
|
|
477
|
+
runConfig: {
|
|
478
|
+
streamingMode: "sse",
|
|
479
|
+
maxLlmCalls: 10,
|
|
480
|
+
pauseOnToolCalls: true, // pause for client-side tool execution
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Event Handlers
|
|
486
|
+
|
|
487
|
+
Listen to streaming events:
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
const runtime = useAdkRuntime({
|
|
491
|
+
stream: createAdkStream({ api: "/api/chat" }),
|
|
492
|
+
eventHandlers: {
|
|
493
|
+
onError: (error) => {
|
|
494
|
+
console.error("Stream error:", error);
|
|
495
|
+
},
|
|
496
|
+
onAgentTransfer: (toAgent) => {
|
|
497
|
+
console.log("Agent transferred to:", toAgent);
|
|
498
|
+
},
|
|
499
|
+
onCustomEvent: (key, value) => {
|
|
500
|
+
// Fired for each entry in event.customMetadata
|
|
501
|
+
console.log("Custom metadata:", key, value);
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Thread Management
|
|
508
|
+
|
|
509
|
+
### ADK Session Adapter
|
|
510
|
+
|
|
511
|
+
Use `createAdkSessionAdapter` to persist threads via ADK's session API (see [Direct ADK Server Connection](#direct-adk-server-connection) above).
|
|
512
|
+
|
|
513
|
+
### Custom Thread Management
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
const runtime = useAdkRuntime({
|
|
517
|
+
stream: createAdkStream({ api: "/api/chat" }),
|
|
518
|
+
create: async () => {
|
|
519
|
+
const sessionId = await createSession();
|
|
520
|
+
return { externalId: sessionId };
|
|
521
|
+
},
|
|
522
|
+
load: async (externalId) => {
|
|
523
|
+
const history = await loadSession(externalId);
|
|
524
|
+
return { messages: history };
|
|
525
|
+
},
|
|
526
|
+
delete: async (externalId) => {
|
|
527
|
+
await deleteSession(externalId);
|
|
528
|
+
},
|
|
529
|
+
});
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Cloud Persistence
|
|
533
|
+
|
|
534
|
+
For persistent thread history via assistant-cloud:
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
import { AssistantCloud } from "assistant-cloud";
|
|
538
|
+
|
|
539
|
+
const runtime = useAdkRuntime({
|
|
540
|
+
cloud: new AssistantCloud({
|
|
541
|
+
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL,
|
|
542
|
+
anonymous: true,
|
|
543
|
+
}),
|
|
544
|
+
stream: createAdkStream({ api: "/api/chat" }),
|
|
545
|
+
});
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
## Message Editing & Regeneration
|
|
549
|
+
|
|
550
|
+
Provide a `getCheckpointId` callback to enable edit and regenerate buttons:
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
const runtime = useAdkRuntime({
|
|
554
|
+
stream: createAdkStream({ api: "/api/chat" }),
|
|
555
|
+
getCheckpointId: async (threadId, parentMessages) => {
|
|
556
|
+
// Resolve checkpoint ID for server-side forking
|
|
557
|
+
return checkpointId;
|
|
558
|
+
},
|
|
559
|
+
});
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
When `getCheckpointId` is provided:
|
|
563
|
+
- **Edit buttons** appear on user messages
|
|
564
|
+
- **Regenerate buttons** appear on assistant messages
|
|
565
|
+
|
|
566
|
+
The resolved `checkpointId` is passed to your `stream` callback via `config.checkpointId`.
|
|
567
|
+
|
|
568
|
+
<Callout type="info">
|
|
569
|
+
Without `getCheckpointId`, edit and regenerate buttons will not appear.
|
|
570
|
+
</Callout>
|
|
571
|
+
|
|
572
|
+
## Hooks Reference
|
|
573
|
+
|
|
574
|
+
| Hook | Description |
|
|
575
|
+
|------|-------------|
|
|
576
|
+
| `useAdkAgentInfo()` | Current agent name and branch path |
|
|
577
|
+
| `useAdkSessionState()` | Full accumulated session state delta |
|
|
578
|
+
| `useAdkAppState()` | App-level state (`app:*` prefix, stripped) |
|
|
579
|
+
| `useAdkUserState()` | User-level state (`user:*` prefix, stripped) |
|
|
580
|
+
| `useAdkTempState()` | Temp state (`temp:*` prefix, stripped, not persisted) |
|
|
581
|
+
| `useAdkSend()` | Send raw ADK messages |
|
|
582
|
+
| `useAdkConfirmTool()` | Confirm or deny a pending tool confirmation |
|
|
583
|
+
| `useAdkSubmitAuth()` | Submit auth credentials for a pending auth request |
|
|
584
|
+
| `useAdkToolConfirmations()` | Pending tool confirmation requests |
|
|
585
|
+
| `useAdkAuthRequests()` | Pending auth credential requests |
|
|
586
|
+
| `useAdkLongRunningToolIds()` | IDs of long-running tools awaiting input |
|
|
587
|
+
| `useAdkArtifacts()` | Artifact delta (filename → version) |
|
|
588
|
+
| `useAdkEscalation()` | Whether escalation was requested |
|
|
589
|
+
| `useAdkMessageMetadata()` | Per-message grounding/citation/usage metadata |
|
|
590
|
+
|
|
591
|
+
## Features
|
|
592
|
+
|
|
593
|
+
| Feature | Status |
|
|
594
|
+
|---|---|
|
|
595
|
+
| Streaming text (SSE) | Supported |
|
|
596
|
+
| Tool calls & results | Supported |
|
|
597
|
+
| Tool confirmations (`useAdkConfirmTool`) | Supported |
|
|
598
|
+
| Auth credential flow (`useAdkSubmitAuth`) | Supported |
|
|
599
|
+
| Multi-agent (author/branch tracking) | Supported |
|
|
600
|
+
| Agent transfer events | Supported |
|
|
601
|
+
| Escalation detection | Supported |
|
|
602
|
+
| Chain-of-thought / reasoning | Supported |
|
|
603
|
+
| Code execution (executableCode + result) | Supported |
|
|
604
|
+
| Inline images & file data | Supported |
|
|
605
|
+
| Session state delta + scoped state | Supported |
|
|
606
|
+
| Artifact delta tracking + fetching | Supported |
|
|
607
|
+
| Long-running tools (HITL) | Supported |
|
|
608
|
+
| Grounding / citation / usage metadata | Supported |
|
|
609
|
+
| Structured events (`toAdkStructuredEvents`) | Supported |
|
|
610
|
+
| Typed `AdkRunConfig` | Supported |
|
|
611
|
+
| Client → server `stateDelta` | Supported |
|
|
612
|
+
| `finishReason` mapping (17 values) | Supported |
|
|
613
|
+
| `interrupted` event handling | Supported |
|
|
614
|
+
| Snake\_case events (Python ADK) | Supported |
|
|
615
|
+
| Cloud thread persistence | Supported |
|
|
616
|
+
| ADK session-backed thread persistence | Supported |
|
|
617
|
+
| Direct ADK server connection (no proxy) | Supported |
|
|
618
|
+
| One-liner API route (`createAdkApiRoute`) | Supported |
|
|
619
|
+
| Message editing & regeneration | Supported |
|
|
620
|
+
| Automatic tool invocations | Supported |
|
|
621
|
+
|
|
622
|
+
### ADK Python Backend
|
|
623
|
+
|
|
624
|
+
The package automatically normalizes snake\_case event fields from ADK Python backends to camelCase. No configuration needed — connect to either ADK JS or ADK Python servers. This includes all nested fields: `function_call` → `functionCall`, `requested_tool_confirmations` → `requestedToolConfirmations`, etc.
|
|
@@ -30,7 +30,7 @@ export async function POST(req: Request) {
|
|
|
30
30
|
return streamText({
|
|
31
31
|
model: openai("gpt-4o"),
|
|
32
32
|
prompt,
|
|
33
|
-
});
|
|
33
|
+
}).toUIMessageStreamResponse();
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -44,15 +44,15 @@ export async function POST(req: Request) {
|
|
|
44
44
|
2. **Configure ChatOpenAI:**
|
|
45
45
|
|
|
46
46
|
```python
|
|
47
|
-
from
|
|
47
|
+
from langchain_openai import ChatOpenAI
|
|
48
48
|
import os
|
|
49
49
|
|
|
50
50
|
llm = ChatOpenAI(
|
|
51
|
-
model_name="gpt-
|
|
51
|
+
model_name="gpt-4o",
|
|
52
52
|
temperature=0,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
base_url="https://oai.helicone.ai/v1",
|
|
54
|
+
api_key=os.environ["OPENAI_API_KEY"],
|
|
55
|
+
default_headers={"Helicone-Auth": f"Bearer {os.environ['HELICONE_API_KEY']}"}
|
|
56
56
|
)
|
|
57
57
|
```
|
|
58
58
|
|