Skip to content

Voice mode: Gemini Live with tool calls, dynamic prompt injection, and animated orb #581

Description

@vybe

Summary

Upgrade the existing voice chat implementation (VOICE-004) to use Gemini Live for real-time bidirectional audio, enable tool calls mid-conversation so agents can actually do things while you speak to them, inject conversation context dynamically into the voice session so it continues where the text chat left off, and replace the current simple pulsing-circle overlay with a beautiful animated speaking orb.

Context

The agent detail page already has a voice overlay (`VoiceOverlay.vue`) backed by `useVoiceSession.js`, but the implementation uses an older model and has no tool-call support — the agent can only respond with words. A working reference implementation exists in a private agent: it uses the Gemini Live WebSocket API, declares tools in the session setup, routes tool calls through a local proxy that executes them in real time (2-3s per call), injects the current conversation context as a rich system prompt before each session, and surfaces a dark canvas-based animated orb that reacts to audio amplitude. That pattern should be brought into Trinity natively.

Acceptance Criteria

  • Voice sessions use Gemini Live (real-time bidirectional WebSocket), replacing the current backend voice proxy
  • Tool calls work during a voice conversation — the agent can execute its declared tools (e.g. search, file ops) and continue speaking with the result; the orb shows a visual "thinking" state during tool execution
  • Before a voice session starts, the current chat session context (last N messages) is packaged into the Gemini system prompt so the voice session feels continuous with the text chat — not a fresh start
  • The voice overlay is replaced with a full-screen animated orb: dark background, particle/smoke canvas animation that reacts to audio amplitude (louder = larger / brighter), distinct visual states for idle / listening / speaking / tool-calling
  • Orb state transitions are smooth (no jarring cuts between states)
  • Microphone mute and end-call controls remain accessible over the orb
  • Voice transcript entries continue to be saved to the persistent chat session
  • API key for Gemini Live is sourced from the platform's existing `GEMINI_API_KEY` / `GOOGLE_API_KEY` env var (no new credential surface)

Technical Notes

Reference architecture (Cornelius voice-mode skill):

[User speaks]
  → Gemini Live WebSocket (gemini-2.0-flash-live)
    → function_declarations declared in session setup
      → on tool_call event: proxy POSTs to backend tool handler
        → backend executes tool, returns JSON
      → tool_response sent back to Gemini Live session
    → Gemini continues speaking with result
  → canvas orb animates to audio amplitude via AnalyserNode

Key files to change:

  • src/frontend/src/composables/useVoiceSession.js — replace WS protocol; add tool-call message handling; accept primeContext param
  • src/frontend/src/components/chat/VoiceOverlay.vue — replace with canvas-based orb; keep mute/end controls as overlays
  • src/backend/routers/voice.py (or equivalent) — add Gemini Live session initialisation endpoint that accepts system-prompt context; add tool-call relay endpoint
  • src/frontend/src/utils/audio.js — add AnalyserNode amplitude extraction for orb reactivity

Prompt injection: on voice start, the frontend sends the last ~10 chat messages (or a summary) to the backend, which builds a Gemini system prompt combining the agent's base CLAUDE.md / template instructions + conversation summary + voice behaviour hints (concise, one question at a time).

Tool call routing: Gemini Live emits toolCall events mid-stream; the frontend should POST these to POST /api/agents/{name}/voice/tool which executes them against the agent container (same mechanism as the regular chat tool-call path) and returns the result for the toolResponse message.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions