Tool confirmations, auth, input requests, artifacts, escalation, metadata, structured events.
Reference for the runtime's React hooks. These expose ADK-specific state and HITL primitives. Start with quickstart if you have not wired up a basic runtime yet.
Agent and session state
import {
useAdkAgentInfo,
useAdkSessionState,
useAdkSend,
} from "@assistant-ui/react-google-adk";
function MyComponent() {
// Current active agent name and branch path (multi-agent)
const agentInfo = useAdkAgentInfo();
// agentInfo?.name = "search_agent"
// agentInfo?.branch = "root.search_agent"
// Accumulated session state delta
const state = useAdkSessionState();
// Send raw ADK messages programmatically
const send = useAdkSend();
}Tool confirmations
When ADK's SecurityPlugin or tool callbacks request user confirmation before executing a tool, use useAdkToolConfirmations to read pending requests and useAdkConfirmTool to respond:
import {
useAdkToolConfirmations,
useAdkConfirmTool,
} from "@assistant-ui/react-google-adk";
function ToolConfirmationUI() {
const confirmations = useAdkToolConfirmations();
const confirmTool = useAdkConfirmTool();
if (confirmations.length === 0) return null;
return confirmations.map((conf) => (
<div key={conf.toolCallId}>
<p>
Tool "{conf.toolName}" wants to run. {conf.hint}
</p>
<button onClick={() => confirmTool(conf.toolCallId, true)}>Approve</button>
<button onClick={() => confirmTool(conf.toolCallId, false)}>Deny</button>
</div>
));
}Auth requests
When a tool requires OAuth or other authentication, use useAdkAuthRequests to read pending requests and useAdkSubmitAuth to submit credentials:
import {
useAdkAuthRequests,
useAdkSubmitAuth,
type AdkAuthCredential,
} from "@assistant-ui/react-google-adk";
function AuthUI() {
const authRequests = useAdkAuthRequests();
const submitAuth = useAdkSubmitAuth();
if (authRequests.length === 0) return null;
return authRequests.map((req) => (
<div key={req.toolCallId}>
<button
onClick={() => {
const credential: AdkAuthCredential = {
authType: "oauth2",
oauth2: { accessToken: "..." },
};
submitAuth(req.toolCallId, credential);
}}
>
Authenticate
</button>
</div>
));
}AdkAuthCredential supports all ADK auth types: apiKey, http, oauth2, openIdConnect, serviceAccount.
Input requests
When an ADK Python 2.0+ Workflow's RequestInput node pauses execution to ask the user a question, ADK emits an adk_request_input function call marked as long-running. Respond with useAdkSubmitInput inside a tool UI; the helper wraps the answer as { result } to match ADK's unwrap_response contract, so the Workflow node resumes with the unwrapped value:
import { makeAssistantToolUI } from "@assistant-ui/react";
import { useAdkSubmitInput } from "@assistant-ui/react-google-adk";
type RequestInputArgs = {
interrupt_id?: string;
message?: string;
payload?: unknown;
response_schema?: unknown;
};
export const RequestInputToolUI = makeAssistantToolUI<
RequestInputArgs,
unknown
>({
toolName: "adk_request_input",
render: function RequestInputUI({ toolCallId, args, result }) {
const submitInput = useAdkSubmitInput();
if (result !== undefined) {
return <p>Answered: {String(result)}</p>;
}
return (
<form
onSubmit={(e) => {
e.preventDefault();
const value = (
e.currentTarget.elements.namedItem("answer") as HTMLInputElement
).value;
submitInput(toolCallId, value);
}}
>
<p>{args.message ?? "Please provide input:"}</p>
<input name="answer" autoFocus />
<button type="submit">Submit</button>
</form>
);
},
});Register the tool UI inside AssistantRuntimeProvider:
<AssistantRuntimeProvider runtime={runtime}>
<RequestInputToolUI />
<Thread />
</AssistantRuntimeProvider>adk_request_input is emitted only by ADK Python 2.0+ Workflow RequestInput nodes; ADK JS has no equivalent. Always respond via a tool UI with useAdkSubmitInput. HITL interrupts are automatically exempt from autoCancelPendingToolCalls, so typing a normal message in the composer will not overwrite the pending interrupt.
useAdkSubmitInput is sugar over the generic addResult. If you prefer, call addResult({ result: value }) from inside the render function directly. The { result } wrapper is required either way: the adapter JSON-stringifies the value before sending, and ADK's unwrap_response unwraps it on the backend before the Workflow node resumes.
Artifacts
Track file artifacts created or modified by the agent:
import { useAdkArtifacts } from "@assistant-ui/react-google-adk";
function ArtifactList() {
const artifacts = useAdkArtifacts();
// Record<string, number> — filename to version number
}Artifact fetching
When using createAdkSessionAdapter (see api reference), the returned artifacts object provides functions to fetch artifact content from the ADK server:
const { artifacts } = createAdkSessionAdapter({ apiUrl, appName, userId });
// List all artifact filenames in a session
const filenames = await artifacts.list(sessionId);
// Load artifact content (latest version)
const data = await artifacts.load(sessionId, "document.pdf");
// data.inlineData?.data — base64 content
// data.inlineData?.mimeType — MIME type
// data.text — text content (if text artifact)
// Load a specific version
const v1 = await artifacts.load(sessionId, "document.pdf", 1);
// List all versions
const versions = await artifacts.listVersions(sessionId, "document.pdf");
// Delete an artifact
await artifacts.delete(sessionId, "document.pdf");Escalation
Detect when an agent requests escalation to a human operator:
import { useAdkEscalation } from "@assistant-ui/react-google-adk";
function EscalationBanner() {
const escalated = useAdkEscalation();
if (!escalated) return null;
return <div>Agent has requested human assistance.</div>;
}Long-running tools
Track tools that are executing asynchronously and awaiting external input:
import { useAdkLongRunningToolIds } from "@assistant-ui/react-google-adk";
function PendingToolsIndicator() {
const pendingToolIds = useAdkLongRunningToolIds();
if (pendingToolIds.length === 0) return null;
return <div>{pendingToolIds.length} tool(s) awaiting input</div>;
}This hook reports every tool call ADK marked via long_running_tool_ids, including HITL interrupts. To respond to a specific HITL type, see tool confirmations, auth requests, or input requests.
Per-message metadata
Access grounding, citation, and token usage metadata per message:
import { useAdkMessageMetadata } from "@assistant-ui/react-google-adk";
function MessageMetadata({ messageId }: { messageId: string }) {
const metadataMap = useAdkMessageMetadata();
const meta = metadataMap.get(messageId);
// meta?.groundingMetadata — Google Search grounding sources
// meta?.citationMetadata — citation references
// meta?.usageMetadata — token counts
}Session state by scope
ADK uses key prefixes to scope state. These helpers filter and strip the prefix:
import {
useAdkAppState,
useAdkUserState,
useAdkTempState,
} from "@assistant-ui/react-google-adk";
function StateDebug() {
const appState = useAdkAppState(); // app:* keys (app-level, shared)
const userState = useAdkUserState(); // user:* keys (user-level)
const tempState = useAdkTempState(); // temp:* keys (not persisted)
}Use useAdkSessionState() for the full unfiltered state delta.
Structured events
Convert raw ADK events into typed, structured events for custom renderers:
import {
toAdkStructuredEvents,
AdkEventType,
type AdkStructuredEvent,
} from "@assistant-ui/react-google-adk";
const structured = toAdkStructuredEvents(event);
for (const e of structured) {
switch (e.type) {
case AdkEventType.CONTENT:
console.log("Text:", e.content);
break;
case AdkEventType.THOUGHT:
console.log("Reasoning:", e.content);
break;
case AdkEventType.TOOL_CALL:
console.log("Tool:", e.call.name, e.call.args);
break;
case AdkEventType.ERROR:
console.error(e.errorMessage);
break;
}
}Hooks reference
| Hook | Description |
|---|---|
useAdkAgentInfo() | Current agent name and branch path. |
useAdkSessionState() | Full accumulated session state delta. |
useAdkAppState() | App-level state (app:* prefix, stripped). |
useAdkUserState() | User-level state (user:* prefix, stripped). |
useAdkTempState() | Temp state (temp:* prefix, stripped, not persisted). |
useAdkSend() | Send raw ADK messages. |
useAdkConfirmTool() | Confirm or deny a pending tool confirmation. |
useAdkSubmitAuth() | Submit auth credentials for a pending auth request. |
useAdkSubmitInput() | Submit the user's answer for a pending adk_request_input HITL interrupt. |
useAdkToolConfirmations() | Pending tool confirmation requests. |
useAdkAuthRequests() | Pending auth credential requests. |
useAdkLongRunningToolIds() | IDs of long-running tools awaiting input. |
useAdkArtifacts() | Artifact delta (filename → version). |
useAdkEscalation() | Whether escalation was requested. |
useAdkMessageMetadata() | Per-message grounding, citation, and usage metadata. |
Feature support
| Feature | Status |
|---|---|
| Streaming text (SSE) | Supported |
| Tool calls and results | Supported |
Tool confirmations (useAdkConfirmTool) | Supported |
Auth credential flow (useAdkSubmitAuth) | Supported |
Workflow input requests (useAdkSubmitInput, ADK Python 2.0+) | Supported |
| Multi-agent (author and branch tracking) | Supported |
| Agent transfer events | Supported |
| Escalation detection | Supported |
| Chain-of-thought / reasoning | Supported |
| Code execution (executableCode + result) | Supported |
| Inline images and file data | Supported |
| Session state delta + scoped state | Supported |
| Artifact delta tracking + fetching | Supported |
| Long-running tools (HITL) | Supported |
| Grounding / citation / usage metadata | Supported |
Structured events (toAdkStructuredEvents) | Supported |
Typed AdkRunConfig | Supported |
Client → server stateDelta | Supported |
finishReason mapping (17 values) | Supported |
interrupted event handling | Supported |
| Snake_case events (Python ADK) | Supported |
| Cloud thread persistence | Supported |
| ADK session-backed thread persistence | Supported |
| Direct ADK server connection (no proxy) | Supported |
One-liner API route (createAdkApiRoute) | Supported |
| Message editing and regeneration | Supported |
| Automatic tool invocations | Supported |