Skip to content
Development
Agent

adk-python-live

Real-time voice and video agents built on ADK's **Gemini Live API Toolkit** (`Runner.run_live` + `LiveRequestQueue`). Use this for low-latency spoken conversation and interruption ("barge-in") — not for turn-based request/response agents (use a normal `Agent` with `run_async`

From plugin
agents-cli
6.2k31 skills31 agents

Claude Code

$ npx -y skills add google/agents-cli --agent claude-code

Agent definition

adk-python-live.md

ADK Live and Voice Agents

Real-time voice and video agents built on ADK's **Gemini Live API Toolkit** (`Runner.run_live` + `LiveRequestQueue`). Use this for low-latency spoken conversation and interruption ("barge-in") — not for turn-based request/response agents (use a normal `Agent` with `run_async` for those).

**Official docs:** [ADK Live Docs](https://adk.dev/live/index.md) · [Configuration](https://adk.dev/live/configuration/index.md) · [Tools](https://adk.dev/live/tools/index.md) · [Get started](https://adk.dev/live/get-started/index.md)

---

1. When to use Live

| Use `run_live` (Live) | Use `run_async` (normal) | |-----------------------|--------------------------| | Voice/phone assistants, live captioning | Chatbots, tools, batch/RAG | | User can interrupt mid-response | One turn completes before the next | | Continuous audio/video input | Discrete text/multimodal messages | | Latency-critical spoken UX | Latency-tolerant |

> **Live agents can't be served over A2A, and can't be published to Gemini.** > Both are request/response with no Live transport. This has > consequences for a scaffolded project beyond the model line — see > "Converting a scaffolded project to Live" next.

2. Converting a scaffolded project to Live

There is no Live scaffold template. Scaffold `adk_python` normally, then make these edits **together** — they are all consequences of one decision, and stopping after the first leaves a project whose `uv run pytest` fails.

| # | File | Edit | |---|------|------| | 1 | `app/agent.py` | Point `MODEL` at a Live model and, on Gemini platform, add `client_kwargs={"location": …}` to the `Gemini(...)` the scaffold already emits (see "Models"). No `.env` or Terraform change. | | 2 | `app/fast_api_app.py` | Delete the `attach_a2a_routes` call and its imports; delete `app/app_utils/a2a.py` and the `a2a-sdk` dependency. `/run_live` comes from `get_fast_api_app` and is untouched. | | 3 | `tests/integration/test_agent.py` | Rewrite onto `run_live` (below). | | 4 | `tests/integration/test_server_e2e.py` | Repoint the readiness probe, drop the A2A and SSE tests, add a `/run_live` test (below). | | 5 | — | Drop `agents-cli publish gemini` from the plan; the Gemini app has no Live transport to register against. |

Steps 3 and 4 are not optional cleanup. Both scaffolded integration tests drive the **non-live** path, and a Live model doesn't degrade to text — it rejects it, so `runner.run()` and `/run_sse` fail outright. Rewrite the tests; don't delete them.

`tests/integration/test_agent.py`

Same shape as the scaffolded test, but driven by `run_live` and asserting on the transcript rather than on text parts:

import asyncio

from google.adk.agents.live_request_queue import LiveRequestQueue
from google.adk.agents.run_config import RunConfig
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types

from app.agent import root_agent

APP_NAME = "test"
USER_ID = "test_user"


def test_agent_live_stream() -> None:
    """The agent answers over run_live and returns audio plus a transcript."""

    async def _turn() -> tuple[str, int]:
        session_service = InMemorySessionService()
        # The session must exist before run_live, or it raises "Session not found".
        session = await session_service.create_session(
            app_name=APP_NAME, user_id=USER_ID
        )
        runner = Runner(
            agent=root_agent, session_service=session_service, app_name=APP_NAME
        )
        queue = LiveRequestQueue()
        queue.send_content(
            types.Content(role="user", parts=[types.Part(text="Why is the sky blue?")])
        )

        transcript, audio_chunks = "", 0
        try:
            async for event in runner.run_live(
                user_id=USER_ID,
                session_id=session.id,
                live_request_queue=queue,
                # Transcription is on by default — see "RunConfig".
                run_config=RunConfig(response_modalities=["AUDIO"]),
            ):
                # Consume the finished aggregate; partials would duplicate text.
                if (
                    event.output_transcription
                    and event.output_transcription.finished
                    and event.output_transcription.text
                ):
                    transcript += event.output_transcription.text
                if event.content and event.content.parts:
                    audio_chunks += sum(
                        1 for part in event.content.parts if part.inline_data
                    )
                if event.turn_complete:
                    break
        finally:
            queue.close()
        return transcript, audio_chunks

    transcript, audio_chunks = asyncio.run(_turn())
    assert transcript.strip(), "Expected a non-empty output transcript"
    assert audio_chunks > 0, "Expected the agent to return audio"

`tests/integration/test_server_e2e.py`

Three edits, and the first is the one that's easy to miss:

  • **Repoint the readiness probe.** `wait_for_server()` polls `AGENT_CARD_URL`,

which step 2 deleted — use `f"{BASE_URL}/list-apps"` instead. Miss this and the probe raises `NameError`, which the surrounding `except RequestException` does **not** catch, so every test in the file errors before the server is even contacted. (`/list-apps` is a sound readiness signal: uvicorn serves no request until the lifespan startup completes.)

  • **Delete `test_adk_run_sse`, `test_a2a_chat_stream`, and `test_agent_card`**,

and add the `/run_live` test below. Those three are the whole file, so the new test replaces them rather than joining them.

  • **On the `agent_runtime` target only**, also delete

`test_reasoning_engine_stream` — `async_stream_query` is the non-live path too.

import asyncio
import json
import uuid

import requests
from websockets.asyncio.client import connect

APP_NAME = "app"  # t
Read more
@google
Ships withagents-cli

The CLI and skills that turn any coding assistant into an expert at creating, evaluating, and deploying AI agents on Google Cloud.

6.2k7 skills31 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
6.2k
Star history of google/agents-cli on GitHub, a chart by star-history.com

Other agents on agents-cli.

adk-go-workflows

adk-go-workflows

Agent

Requires `google.golang.org/adk/v2 >= v2.0.0`, which is where the `workflow` package and `agent/workflowagent` first ship.

@google@googleInstall Agent
adk-go

adk-go

Agent

Reflects `google.golang.org/adk/v2 v2.1.0`, the version the `adk_go` template pins. If a symbol here is missing, check your…

@google@googleInstall Agent
adk-python

adk-python

Agent

* **`Agent`**: The core intelligent unit. Can be `LlmAgent` (LLM-driven) or `BaseAgent` (custom/workflow). * **`Tool`**: Callable…

@google@googleInstall Agent
recipes

recipes

Agent

Recipes live in [google/adk-recipes](https://github.com/google/adk-recipes). **`core/python/`** is the curated tier — canonical…

@google@googleInstall Agent
agent-runtime

agent-runtime

Agent

**Assumes `/google-agents-cli-scaffold` scaffolding.** If your project isn't scaffolded yet, see `/google-agents-cli-scaffold`…

@google@googleInstall Agent

More agents from other plugins.

a11y-architect
Auto-invoked

a11y-architect

Agent

Accessibility Architect specializing in WCAG 2.2 compliance for Web and Native platforms. Use PROACTIVELY when designing UI…

ecc12d293k
@affaan-m@affaan-mInstall Agent
analyze-pass-impact

analyze-pass-impact

Agent

Analyzes how a specific topic affects a group of compiler passes. Used by the /plan-update skill to parallelize research across…

react1d252k
@facebook@facebookInstall Agent
orchestrator

orchestrator

Agent

- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as…

codex1d135k
@openai@openaiInstall Agent
cavecrew-builder

cavecrew-builder

Agent

Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…

caveman2d119k
@juliusbrussee@juliusbrusseeInstall Agent

Questions about adk-python-live.

Which coding agents can use adk-python-live?
adk-python-live installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.