# Hooks
URL: /docs/runtimes/google-adk/hooks

Tool confirmations, auth, input requests, artifacts, escalation, metadata, structured events.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

Reference for the runtime's React hooks. These expose ADK-specific state and HITL primitives. Start with [quickstart](/docs/runtimes/google-adk/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:

**React**

```
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:

**React**

```
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:

**React**

```
import type { ToolCallMessagePartComponent } 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: ToolCallMessagePartComponent<
  RequestInputArgs,
  unknown
> = 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 renderer with a backend toolkit entry inside `AssistantRuntimeProvider`:

**React**

```
import {
  AssistantRuntimeProvider,
  defineToolkit,
  Tools,
  useAui,
} from "@assistant-ui/react";
import {
  createAdkStream,
  useAdkRuntime,
} from "@assistant-ui/react-google-adk";
import { Thread } from "@/components/assistant-ui/thread";

const toolkit = defineToolkit({
  adk_request_input: {
    type: "backend",
    render: RequestInputToolUI,
  },
});

function App() {
  const runtime = useAdkRuntime({
    stream: createAdkStream({ api: "/api/chat" }),
  });
  const aui = useAui({ tools: Tools({ toolkit }) });

  return (
    <AssistantRuntimeProvider aui={aui} runtime={runtime}>
      <Thread />
    </AssistantRuntimeProvider>
  );
}
```

> [!info]
>
> `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](/docs/runtimes/google-adk/api#direct-adk-server-connection)), 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:

**React**

```
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:

**React**

```
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](#tool-confirmations), [auth requests](#auth-requests), or [input requests](#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 |

## Related

- [API reference](/docs/runtimes/google-adk/api) — createAdkStream, server helpers, session adapter, threads.
- [Quickstart](/docs/runtimes/google-adk/quickstart) — Minimal API route + client setup.
- [Adapters](/docs/runtimes/concepts/adapters) — Attachments, speech, feedback, history, threads.