Voice gateway: full-duplex voice for any registered agent#90
Open
lezama wants to merge 2 commits into
Open
Conversation
Sidecar daemon (Python, same pattern as wp-carpeta's bridge/) that puts Gemini Live in front of openclaWP's agenttic chat endpoint as a pure voice shell: native STT/TTS, turn-taking and barge-in stay in Gemini, while every domain request is forwarded through a single ask_agent tool to the registered agent — so memory, destructive-tool gating and transcripts stay in WordPress. - gateway.py: WS bridge browser⇄Gemini Live (BidiGenerateContent), async tool execution, sticky openclawp sessionId per voice session, per-session audio cost log, /healthz. - static/index.html: mic capture (PCM s16 16kHz), scheduled 24kHz playback with barge-in flush, live transcripts, text fallback. - README: setup, Caddy path-prefix proxy, launchd unit, wire protocol. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
POST /openclawp/v1/voice/session exchanges the Google key already stored in the AI Client credential store (read via AiClient::defaultRegistry() ->getProviderRequestAuthentication) for a single-use Gemini Live ephemeral token (v1alpha auth_tokens, model-constrained, 30 min expiry). The long-lived key never leaves WordPress; returning it raw sits behind an off-by-default filter. The gateway now asks WP for its credential per voice session (?access_token= on the v1alpha Bidi WS) and keeps a local GEMINI_API_KEY only as fallback for older sites. Shaped deliberately as a core proposal proof of concept: php-ai-client providers could expose ephemeral client credentials for realtime sessions natively — see docs/voice-gateway-core-proposal.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Update: credentials now come from WordPress, shaped as a core proposal. New
The gateway asks WP for its credential per session (
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A sidecar daemon (
voice-gateway/, Python — same ship-a-daemon-in-the-plugin-repo pattern as wp-carpeta'sbridge/) that gives full-duplex voice to any agent registered with the Agents API on a site running openclaWP.Design: one brain
Gemini Live is only the voice shell — native STT/TTS, turn-taking, barge-in. It gets exactly one tool,
ask_agent, which forwards every domain request to the agenttic chat endpoint. The registered agent stays the single brain: conversational memory (stickysessionId), destructive-tool gating (/decisions) and transcripts all stay in WordPress. The voice model is instructed to never answer domain questions from its own knowledge and to verbalize the wait while the agent thinks (tool runs async over the open audio channel).This deliberately avoids the duplicated-brain architecture (declaring the product's full tool surface to the voice model), which would drift from the agent's prompt and bypass site-side gating.
Pieces
gateway.py— FastAPI WS bridge browser⇄Gemini Live (BidiGenerateContent), async tool execution, per-session audio-seconds cost log,/healthz.static/index.html— dependency-free page: mic capture (PCM s16 16 kHz), scheduled 24 kHz playback with barge-in flush, live transcripts, text-input fallback. WS URL is computed relative to the page so a reverse-proxy path prefix works.README.md— setup, Caddy snippet, launchd unit, wire protocol.Tested
/healthzreports missing config, WS politely rejects unconfigured sessions.Not in this PR
🤖 Generated with Claude Code