Skip to content

feat: add live_bidi_streaming_demo_app sample - #6493

Closed
kazunori279 wants to merge 1 commit into
google:mainfrom
kazunori279:samples/live-bidi-streaming-demo-app
Closed

feat: add live_bidi_streaming_demo_app sample#6493
kazunori279 wants to merge 1 commit into
google:mainfrom
kazunori279:samples/live-bidi-streaming-demo-app

Conversation

@kazunori279

Copy link
Copy Markdown
Collaborator

Description

Adds a standalone FastAPI application demonstrating the full ADK bidirectional streaming lifecycle over a WebSocket, with a browser UI for text, voice, and camera input.

Unlike the other samples under contributing/samples/live/, this one does not run under adk web. It owns its own Runner, LiveRequestQueue, and run_live() loop, so it shows what an application built directly on ADK's streaming primitives looks like end to end:

  1. Application initialization (once at startup) — Agent, SessionService, Runner
  2. Session initialization (per connection) — Session, RunConfig, LiveRequestQueue, start run_live()
  3. Bidi-streaming — concurrent upstream (client → queue) and downstream (events → client) tasks
  4. Termination — close the LiveRequestQueue in a finally block

The bundled UI renders every raw ADK Event as it arrives, which makes it useful for inspecting Live API behavior directly.

Why here

This app is the reference implementation for the Gemini Live API Toolkit development guide, which walks through its source line by line with 36 pinned line-level references. It is currently published under google/adk-samples; moving it here keeps the guide's references alongside the ADK source they explain. The docs will be re-pointed at this path once this merges.

Only the minimum set needed to run and to satisfy those references is included. Deliberately excluded, since contributing/README.md scopes samples as "minimal and simplistic": Dockerfile, Agent Engine deployment scripts, pyproject.toml/uv.lock, and the test suite.

Testing Plan

Tested against ADK 2.5.0 on Vertex AI with gemini-live-2.5-flash-native-audio in us-east1.

Automated

An 8-test suite (kept in the source repo, not shipped here) spawns the real uvicorn server and talks to the real Live API. 8/8 pass, 33.9s.

Test Coverage
T1 / serves index.html; static JS/CSS return 200
T2 Text turn → audio parts + outputTranscription + turnComplete
T3 Real synthesized speech streamed as 20 ms PCM frames; asserts inputTranscription and a matching reply
T4 Image sent via {"type":"image"}, then a prompt about it
T5 Search-triggering prompt yields executableCode / functionCall / webSearchQueries / groundingChunks
T6 ?proactivity=true&affective_dialog=true accepted and applied
T7 Reconnect with the same session_id reuses the session
T8 Disconnect closes LiveRequestQueue with no unhandled error

Browser

Chrome DevTools MCP: page loads, WebSocket auto-connects, a text turn produced the expected reply with streaming output transcription, token usage, and turn-complete events; with "Show audio" enabled the console showed audio/pcm response frames. 0 ERROR lines in the server log across the session; the only console error is a favicon.ico 404. Teardown logged the clean sequence (Client disconnectedClosing live_request_queue).

In place, from this path

Ran uvicorn main:app from contributing/samples/live/live_bidi_streaming_demo_app/app/ to confirm the google_search_agent import and static paths resolve here, then drove one live WebSocket turn against it — 3 audio parts returned, transcript "4" for "What is 2 plus 2?".

Lint

pre-commit run --files <all 13 files> — all hooks pass (isort, pyink, addlicense, ADK Compliance Checks, mdformat, codespell, whitespace).

Not covered

The Gemini API (non-Vertex) path is untested — no API key was available on the test machine. The code path differs only in which env vars load_dotenv() supplies to google-genai.

Notes for reviewers

  • agent vs root_agent. Sibling live samples export root_agent because they load under adk web. This one is a standalone app that imports the symbol itself, and it exports agent to stay consistent with the published guide's code snippets. Happy to rename if you'd prefer uniformity — it would mean a follow-up docs update.
  • Native audio only. The app always requests the AUDIO response modality with transcription in both directions. Half-cascade support was removed during testing because no half-cascade model was reachable (gemini-live-2.5-flash serves only from global; gemini-2.0-flash-live-001 only from us-east1).
  • .env.example, not .env. The repo .gitignore blocks .env, so setup is cp .env.example app/.env.

Add a standalone FastAPI application demonstrating the full ADK
bidirectional streaming lifecycle over a WebSocket, with a browser UI for
text, voice, and camera input.

Unlike the other samples under contributing/samples/live/, this one does not
run under `adk web`. It owns its own Runner, LiveRequestQueue, and
run_live() loop, so it shows what an application built directly on ADK's
streaming primitives looks like end to end: application initialization,
per-connection session initialization, concurrent upstream/downstream tasks,
and termination. The bundled UI renders every raw ADK Event as it arrives,
which makes it useful for inspecting Live API behavior.

This app is the reference implementation for the Gemini Live API Toolkit
development guide at https://adk.dev/streaming/dev-guide/part1/, which walks
through its source line by line. It was previously published under
google/adk-samples and is being moved here so the guide references live
alongside the ADK source.
@adk-bot adk-bot added the live [Component] This issue is related to live, voice and video chat label Jul 27, 2026
@kazunori279
kazunori279 deleted the samples/live-bidi-streaming-demo-app branch July 27, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

live [Component] This issue is related to live, voice and video chat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants