feat: BYO-LLM conversational voice mode — OpenAI-compatible endpoint + voice agent loop - #940
Open
andreolf wants to merge 1 commit into
Open
feat: BYO-LLM conversational voice mode — OpenAI-compatible endpoint + voice agent loop#940andreolf wants to merge 1 commit into
andreolf wants to merge 1 commit into
Conversation
- Add ConversationSettings ORM model (singleton pattern, same as CaptureSettings/GenerationSettings) with fields: enabled, llm_endpoint, llm_api_key, llm_model, system_prompt_prefix - Export ConversationSettings from database package - Add Pydantic models: ConversationSettingsResponse/Update, ConversationMessage, ConversationTurnRequest/Response - Add OpenAI-compatible LLM backend (backends/openai_compat_backend.py) using httpx; supports single-turn generate() and multi-turn generate_with_history() - Add voice agent loop (POST /conversation/turn): user message + history → external LLM with profile personality as system prompt → TTS via existing run_generation pipeline → returns assistant text + generation_id - Add settings endpoints (GET/PUT /settings/conversation) - Add useConversationSettings hook (optimistic updates, same pattern as useGenerationSettings) - Add ConversationPanel React component with chat bubbles, Send button, auto-play TTS via SSE polling, keyboard shortcut (Enter to send) - Add ConversationPage settings UI with endpoint/key/model/system-prompt fields and provider compatibility sidebar - Wire Conversation tab into settings nav and TanStack Router - Add Voice Chat tab to VoiceInspector (visible when conversation enabled) Compatible with: Ollama, LM Studio, OpenAI, any OpenAI-compatible API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Hi @andreolf — really nice work on this. I only spotted it after opening #947 / #948 today, which have some real overlap with the backend layer here:
Whichever one @jamiepine wants first, happy to rebase mine onto the shared backend rather than duplicating it. If this PR lands first I'll pick up your Also — I noticed you're using the multi-turn No rush from my side; happy to coordinate on whichever direction the maintainer prefers. |
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.
Summary
Turns Voicebox from a TTS studio into a local voice agent: connect any OpenAI-compatible LLM (Ollama, LM Studio, OpenAI, Anthropic, etc.), speak or type to it, and hear replies in a cloned voice — running entirely on your machine.
This is the text-LLM bridge that the roadmap lists as the stepping stone before end-to-end speech LLMs (Moshi, GLM-4-Voice). It reuses the entire existing generation pipeline unchanged.
What's new
Backend
ConversationSettingsORM singleton (same pattern asCaptureSettings) —enabled,llm_endpoint,llm_api_key,llm_model,system_prompt_prefixbackend/backends/openai_compat_backend.py—OpenAICompatLLMBackendviahttpx(already a dependency); implements bothgenerate()andgenerate_with_history()for multi-turn chatPOST /conversation/turn— validates settings → calls external LLM with the profile's personality as system prompt + conversation history → enqueues TTS via the existing background job pipeline → returnsassistant_text+generation_idimmediately (non-blocking, same pattern as/generate)GET /PUT /settings/conversation— settings CRUD, same pattern as captures/generation settingsFrontend
ConversationPanel.tsx— chat UI with user/assistant bubbles, Enter-to-send, polls SSE endpoint and auto-plays audio via the existing audio player storeConversationPage.tsx— settings page: enable toggle, endpoint URL, API key (password field), model name, system-prompt textarea, provider compatibility sidebar (Ollama · LM Studio · OpenAI · any compatible API)Compatibility
Works out of the box with any server that speaks
/v1/chat/completions:http://localhost:11434, no API keyhttp://localhost:1234, no API keyhttps://api.openai.com, API key requiredTest plan
ollama run llama3)🤖 Generated with Claude Code