Theme 05 — Interruptible Real-Time Agents
Benchmark: Full-Duplex-Bench v3 (FDB-v3) — multi-step tool calling under real-world speech disfluency
Stack: LiveKit Voice Agents SDK · Google Gemini 2.5 Flash Native Audio (end-to-end speech model)
Team: MSRIT_Cache_Me · AI usage disclosure
Contact: 1ms24is013@msrit.edu
Submission Tag: PRISM_GENAI_HACKATHON_Y2026
Full Demo Video: DEMO.mp4 (04:30 min, 1440x900 @ 30 fps)
A low-latency, full-duplex conversational voice agent that understands spontaneous human speech (hesitations, filler words, self-corrections), supports immediate mid-utterance barge-in, and executes multi-step tool calls across four domains, all handled natively by a single realtime audio model.
- Why This Project
- Architecture
- Models & Providers
- Setup & One-Command Run
- Results
- Reproducibility
- Extension Demo: In-Car Voice Navigation Assistant
- Known Limitations
- References
- Troubleshooting
- Team
Real conversations are messy. Speakers pause mid-sentence, say "um", change their mind ("book to the mall, no wait, the office"), and interrupt the agent before it finishes. FDB-v3 measures exactly this: can a voice agent wait for the right moment, ignore disfluencies, and still fire the correct sequence of tool calls with correct arguments?
This submission takes a fully native approach. Instead of a cascaded STT → LLM → TTS pipeline (which serializes speech through rigid text transcripts and adds latency at every stage), a single end-to-end audio model, Gemini 2.5 Flash Native Audio, handles speech understanding, turn-taking, interruption, intent detection, function calling, and spoken responses in one model pass.
Design principle: the conversation should remain alive while the agent works.
| Domain | Why interruption & correction are essential |
|---|---|
| 🚗 Driving | Hands-free requests where users frequently interrupt or redirect |
This is the intended use case, not a current production deployment.
- Native realtime: no separate ASR → LLM → TTS cascade; one end-to-end audio model.
- Real tool interaction: the agent doesn't stop at generating text; it calls tools.
- Disfluency-aware evaluation: the benchmark contains false starts, self-corrections, disfluencies and interruptions.
- Measured, not assumed: we instrument F1, precision, recall, strict pass rate, and latency.
The system is evaluated as an interactive agent, not just a chatbot.
| Design decision | Rationale |
|---|---|
| Native realtime (Gemini Live) over cascaded pipeline | ~4.25 s vs ~10.12 s published latency; no paid API key needed for the agent runtime; native disfluency handling (see NOTES.md, ARCH-001) |
| LiveKit Cloud WebRTC transport | Production-grade real-time audio, free tier, built-in room dispatch |
| Exact-match evaluation available (no LLM judge) | Reported baseline metrics reproducible without any paid API key |
| Mock tool backends | Deterministic, auditable tool behavior with configurable latency profiles |
flowchart TD
User([Spoken User Audio]) <-->|WebRTC Stream| LK[LiveKit Cloud Room Transport]
LK <-->|Bidirectional Audio Frames| GM[Gemini 2.5 Flash Native Audio<br/>gemini-2.5-flash-native-audio-preview-12-2025]
subgraph Agent Runtime [LiveKit Agent Worker: lk_agent_tool.py]
GM -->|Native Turn Detection| TD[Barge-in / Interruption Cutoff]
GM -->|Tool Call Request| TC[Function Calling Engine]
TC -->|Async Call| MOCK[MockAPIRegistry: 12 Tools across 4 Domains]
MOCK -->|Latency Injection / Result JSON| TC
TC -->|Tool Output Context| GM
end
subgraph Evaluation Pipeline [Evaluation Only - Not Agent Runtime]
LK -.->|Spoken Response WAV| REC[Audio Capture]
REC -.->|ASR Transcription| ASR[NVIDIA Parakeet TDT 0.6B v2]
ASR -.-> EVAL[Evaluators: evaluate_tool_calls.py & evaluate_pass_rate.py]
TC -.->|Execution Log| EVAL
EVAL -.-> RES[Results & Reports: results/]
end
- Fast path (conversational response): For direct queries that need no external data, the native audio model synthesizes spoken audio tokens in a single pass and streams them back over WebRTC with no tool overhead.
- Slow path (tool execution): When a query needs backend state (tracking an order, checking FX rates, modifying autopay), Gemini emits a structured function call. LiveKit's async dispatcher in
Full-Duplex-Bench/v3/lk_agent_tool.pyinvokes the matching method onMockAPIRegistryinFull-Duplex-Bench/v3/mock_apis.py, with configurable simulated latency fromlatency_injector.py. The JSON result is returned to the model session, which speaks the answer. - Interruption handling: Detection runs natively across the WebRTC stream and LiveKit
AgentSession. When user speech is detected while the agent is speaking, outbound audio is halted immediately. Note: if an interruption lands mid-execution of a slow-path tool call, application-level cancellation and rollback of that backend call are not implemented (see Known Limitations).
| Component | Provider / Checkpoint | Role | Required Keys |
|---|---|---|---|
| Realtime model | Google gemini-2.5-flash-native-audio-preview-12-2025 |
End-to-end speech understanding, reasoning, tool selection, speech synthesis | GOOGLE_API_KEY |
| Transport | LiveKit Cloud WebRTC (livekit-agents==1.8.3) |
Real-time audio streaming, room dispatch, session lifecycle | LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET |
| Default voice | Puck (configurable via GOOGLE_VOICE) |
Spoken voice persona | None |
| Evaluation ASR | nvidia/parakeet-tdt-0.6b-v2 |
Transcribes recorded agent responses for scoring only (not in agent runtime) | None (public HuggingFace weights) |
| LLM judge | OpenAI gpt-4o |
Semantic argument matching and response-quality scoring; enabled by default in the reproduction scripts, optional otherwise | OPENAI_API_KEY |
Place all credentials in a .env file at the repository root (template: .env.example):
# LiveKit Cloud (free tier: https://cloud.livekit.io)
LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
# Google AI Studio (https://aistudio.google.com)
GOOGLE_API_KEY=your_google_api_key
# Model selection & voice
LK_PROVIDER=gemini2_5
GOOGLE_VOICE=Puck
# Evaluation LLM judge (required unless you pass --no-llm-judge)
OPENAI_API_KEY=your_openai_keyCentralized parameters (provider, model name, voice, random seed, pinned FDB commit) live in agent_config.json and are read dynamically by the agent.
- Python 3.10, 3.11 or 3.12 (64-bit). The scripts auto-detect the newest version on
PATH. - FFmpeg on your system
PATH(for 48 kHz PCM transcoding). - Credentials for LiveKit Cloud and Google AI Studio (and OpenAI if using the LLM judge).
- Verify the Python version.
- Create an isolated virtual environment (
.venv) and install pinned dependencies fromrequirements.txt. - Validate that required credentials exist in
.env(fails fast, never prints secrets). - Verify or download the benchmark audio dataset (
fdb_v3_data_released/). - Start the agent worker in the background.
- Stream benchmark scenarios through WebRTC LiveKit rooms.
- Run the evaluators and write summaries and logs to
results/.
# 1. Clone and enter the repo
git clone https://github.com/AnanthAkshay/Samsung_Gen_AI.git
cd Samsung_Gen_AI
# 2. Configure credentials
cp .env.example .env
# Edit .env with your LIVEKIT_*, GOOGLE_API_KEY (and OPENAI_API_KEY) values
# 3. Run the full 100-scenario benchmark
.\reproduce.ps1
# (Optional) Quick 3-scenario smoke test
.\reproduce.ps1 -Limit 3
# (Optional) Exact-match only, no OpenAI key needed
.\reproduce.ps1 -Limit 3 -NoLlmJudge# 1. Clone and enter the repo
git clone https://github.com/AnanthAkshay/Samsung_Gen_AI.git
cd Samsung_Gen_AI
# 2. Configure credentials
cp .env.example .env
# Edit .env with your LIVEKIT_*, GOOGLE_API_KEY (and OPENAI_API_KEY) values
# 3. Run the full 100-scenario benchmark
chmod +x reproduce.sh
./reproduce.sh
# (Optional) Quick 3-scenario smoke test
./reproduce.sh --limit 3
# (Optional) Exact-match only, no OpenAI key needed
./reproduce.sh --limit 3 --no-llm-judgeLegacy wrappers
scripts/run_eval.ps1andscripts/run_eval.shforward to the root scripts for backwards compatibility.
Verified baseline on the full 100-scenario released FDB-v3 dataset. Metrics are exact-match mode (no LLM judge). Artifacts are preserved in results/baseline_final_20261001_020033/. Organizers run evaluation with the LLM judge enabled (--use-llm, OpenAI gpt-4o).
| Metric | Verified Baseline (Exact-Match) | Notes |
|---|---|---|
| Scenarios evaluated | 100 / 100 | Full released dataset, 12 human speakers |
| Strict pass rate | 45.0% (45 / 100) | Requires all expected tool calls with exact arguments |
| Mean tool-selection F1 | 0.823 | Precision 0.835, recall 0.838 |
| Mean argument accuracy | 0.528 | Exact string match across invoked argument pairs |
| Mean response latency | 11.732 s | End of user speech to first agent audio token (excludes 5 interruption cases) |
| Turn-taking success rate | 100.0% (100 / 100) | Every scenario produced a non-silent spoken response |
| Failures: wrong tools | 34 | Disfluency caused wrong or missing tool invocation |
| Failures: wrong arguments | 21 | Correct tool, but argument format differed from ground truth |
| Domain | Pass Rate | Fraction |
|---|---|---|
| Finance & Billing | 92.0% | 23 / 25 |
| E-Commerce Support | 58.6% | 17 / 29 |
| Housing & Location | 11.5% | 3 / 26 |
| Travel & Identity | 10.0% | 2 / 20 |
| Difficulty | Pass Rate | Fraction |
|---|---|---|
| Easy (1 tool call) | 52.8% | 19 / 36 |
| Medium (2 tool calls) | 41.2% | 14 / 34 |
| Hard (3 tool calls) | 40.0% | 12 / 30 |
Disclaimer: official scoring is determined exclusively by the hackathon organizers' independent evaluation runs.
- Local RNG fixed:
seed=42inagent_config.jsonseeds Pythonrandom, NumPy and PyTorch for local evaluation scripts and mock-API latency injection. - Gemini Live is non-deterministic: the realtime audio model exposes no temperature or seed control, so spoken responses and argument formatting vary across runs. Expect the strict pass rate to fluctuate by roughly ±3–5% run to run.
- Expected runtime: a full 100-scenario run takes about 2 hours, since audio streams in real time (user speech, agent processing, simulated tool latency, and room teardown for each scenario). Use
--limit Nfor faster smoke tests.
The reproduction scripts enable the LLM judge by default (--use-llm passed to evaluate_tool_calls.py and evaluate_pass_rate.py) to match the organizer procedure.
- Judge model: OpenAI
gpt-4o(pinned inFull-Duplex-Bench/v3/evaluate_tool_calls.pyandevaluate_pass_rate.py) - Required key:
OPENAI_API_KEYin.env - Purpose: semantic argument matching (e.g.
2026-08-20vs "August twentieth, two thousand twenty-six") and response-quality scoring - Opt-out:
./reproduce.sh --limit 3 --no-llm-judge(exact-match only) - Approximate cost: about $0.15–$1.00 USD per 100 scenarios, depending on OpenAI tier and transcript length
When the judge is enabled, results are saved in both modes:
summary_exact_match.json: string-level exact match (no API key needed)summary_llm_judge.json: semantic match viagpt-4o(needsOPENAI_API_KEY)
A side-by-side comparison is written to results/<run_id>/score_comparison_table.txt.
- Google AI Studio free tier has strict rate limits (about 15 requests/minute, 1,500/day). A full 100-scenario run will exceed the daily quota and stall. A paid tier (pay-as-you-go) with enough streaming-session quota is recommended.
- Resume support: if a run is interrupted (Ctrl+C, rate limit, network error), re-run the same command. Scenarios that already have a
result_*.jsonare skipped unless you pass--force.
./reproduce.sh # resumes where it stopped
./reproduce.sh --force # overwrites existing results- Python: 3.10, 3.11 or 3.12. On Python 3.10 only,
backports.tarfile==1.2.0is installed to work around NeMo'starfile.extract(filter=)incompatibility. - Tested: Windows 11 + Python 3.10.11 + CUDA 12.8 (development machine, verified). Ubuntu 22.04 + Python 3.11 + CPU (not verified on this machine).
- Linux:
reproduce.shtargets Ubuntu 22.04/24.04. Required system packages:git,ffmpeg,libsndfile1,python3-venv,python3-pip(the script checks and fails with clear instructions if any are missing). - Windows:
reproduce.ps1targets Windows 10/11 with PowerShell 5.1+ and FFmpeg onPATH(winget install Gyan.FFmpeg). - GPU: an NVIDIA GPU (48 GB VRAM recommended) is used only for local NeMo Parakeet ASR during evaluation post-processing. The Gemini Live agent runs on Google's hosted API and needs no local GPU. CPU fallback works but is slower and may run out of memory on machines with under 16 GB RAM.
- Torch CUDA:
scripts/install_deps.pyinstallstorch==2.14.0fromhttps://download.pytorch.org/whl/cu128(CUDA 12.8 wheels, compatible with CUDA 12.x and 13.x hosts) and falls back to CPU-only torch whennvidia-smiis absent.
- Upstream commit:
3e799c45a045256f47d5f1c9cda90157e2d2ec9e(declared inagent_config.json). - Vendored code:
Full-Duplex-Bench/v3/is committed directly into this repo (not a submodule). Our edits tolk_agent_tool.pyandrun_tool_benchmark_all_released.pyare already applied. - Audio dataset:
fdb_v3_data_released/(~8 GB) is not tracked in git (.gitignoreexcludes*.wavand*.zip). The reproduction script downloads it viagdownfrom Google Drive (ID1SO_4MTazWQ_jvCx0dtmpQ-t40bdd07yz). If the download fails (Drive quota, network), the script prints manual instructions.
git clone https://github.com/AnanthAkshay/Samsung_Gen_AI.git
cd Samsung_Gen_AI
cp .env.example .env # edit with your keys; never commit .env
./reproduce.sh --limit 3 # smoke test with the LLM judge
./reproduce.sh --limit 3 --no-llm-judge # offline smoke test, no OpenAI key
# Expected: results/baseline_<timestamp>/ with summary_exact_match.json
# (and summary_llm_judge.json when the judge is enabled)
git status # should show .env as untracked at most
grep -rE "AIza|sk-|LIVEKIT_API_SECRET=.{10}" . --exclude-dir=.git --exclude="*.example" || echo "No secrets found"- Gemini Live token-level variance: spoken audio and argument formatting are not deterministic for identical input.
- ASR transcription: Parakeet shows minor punctuation/capitalization differences across hardware (GPU vs CPU, CUDA versions).
- WebRTC jitter: network conditions and server load add under 100 ms of variance to frame timestamps.
- LLM judge:
gpt-4oscoring is itself non-deterministic.
These are acceptable under FDB-v3 methodology; organizers average across runs or use significance tests.
The extension applies the same LiveKit + Gemini Realtime stack to an automotive in-cabin assistant, where drivers frequently self-correct mid-sentence. It is implemented in extension_demo.py and verified by the offline test suite tests/test_extension_tools.py.
Tools
| Tool | Behavior |
|---|---|
navigate_to(destination) |
Activates turn-by-turn navigation state and logs the destination |
cancel_navigation() |
Clears active navigation state and records the cancellation |
get_eta() |
Reports the ETA if navigation is active; otherwise returns "There is no active navigation" |
Auditable logging: every tool call appends an event line to logs/extension_tool_calls.log.
Offline unit tests (no network or LiveKit connection required):
python tests/test_extension_tools.pyIn the interest of full technical transparency, these are verified in the current codebase:
- No application-level rollback or stale-call abort: WebRTC audio cutoff halts speech immediately on interruption, but background tool calls dispatched to
MockAPIRegistryhave no transactional abort or rollback. - Argument formatting discrepancies: mean argument accuracy (0.528) trails tool-selection F1 (0.823). The 21 argument mismatches come mainly from date formatting (
2026-08-20vs spoken variants) and alphanumeric spelling (ABC123vsA B C 1 2 3). - No idempotency or confirmation layer: mock API calls run directly on model dispatch, with no idempotency cache or safety-confirmation gate.
- Event-loop load sensitivity: during sustained multi-room batch runs, synchronous crypto and ASR operations can trigger asyncio loop-stall warnings, raising mean response latency to about 11.7 s.
- Lin, G.-T., Chen, C., Chen, Z., & Lee, H.-y. Full-Duplex-Bench-v3: Benchmarking Tool Use for Full-Duplex Voice Agents Under Real-World Disfluency. arXiv:2604.04847 (2026).
- Lin, G.-T., et al. Full-Duplex-Bench (v3). https://github.com/DanielLin94144/Full-Duplex-Bench
- LiveKit. LiveKit Agents: Real-time multimodal AI framework. https://github.com/livekit/agents (
livekit-agents==1.8.3) - Google DeepMind. Gemini 2.5 Flash Native Audio (
gemini-2.5-flash-native-audio-preview-12-2025). https://ai.google.dev/gemini-api/docs/live - NVIDIA NeMo. parakeet-tdt-0.6b-v2. https://huggingface.co/nvidia/parakeet-tdt-0.6b-v2
- Silero Team. Silero VAD (comparative baseline reference). https://github.com/snakers4/silero-vad
| Issue / Error | Root Cause | Resolution |
|---|---|---|
UnicodeEncodeError: 'charmap' codec can't encode... |
Windows console defaults to the legacy CP1252 codepage | Both reproduction scripts export PYTHONUTF8=1 and PYTHONIOENCODING=utf-8 automatically |
FileNotFoundError: /tmp/agent_heartbeat.log |
Hardcoded /tmp/ path fails on Windows when C:\tmp doesn't exist |
lk_agent_tool.py creates the directory on startup; reproduce.ps1 initializes C:\tmp |
worker is at full capacity, marking as unavailable |
LiveKit AgentServer defaults to a 0.70 load threshold and rejects new rooms during CPU spikes |
lk_agent_tool.py sets load_threshold=0.95 |
ffmpeg: The term 'ffmpeg' is not recognized |
FFmpeg missing from PATH |
winget install Gyan.FFmpeg (Windows), apt install ffmpeg (Linux) or brew install ffmpeg (macOS) |
TarFile.extract() got an unexpected keyword argument 'filter' |
Python 3.10's tarfile lacks filter="data" |
backports.tarfile==1.2.0 is pinned in requirements.txt |
| Agent fails to accept incoming rooms | Multiple agent workers registered under the same LiveKit project credentials | Keep only one worker active per project; stop any running lk_agent_tool.py or extension_demo.py |
Team Cache_Me · MSRIT
Akshay A · Aaditya V · H M Pranav · Tejas M
Built for the Samsung PRISM Gen AI Hackathon 3.0 · Theme 05: Interruptible Real-Time Agents · PRISM_GENAI_HACKATHON_Y2026
