Allow a custom base URL for OpenAI integrations - #6
Open
aldinsmajlovic wants to merge 1 commit into
Open
aldinsmajlovic wants to merge 1 commit into
aldinsmajlovic wants to merge 1 commit into
Conversation
The OpenAI (realtime) and OpenAI Cloud integrations get an optional Base URL. Blank keeps api.openai.com. When set, realtime speech-to-speech, realtime STT, TTS, the Assist bridge STT/TTS and the model list go to that server instead, so a self-hosted OpenAI Realtime-compatible server (or any OpenAI-compatible STT/TTS server) can back a pipeline. The realtime WebSocket URL is derived from the base URL. The API key is optional with a base URL, and the global OpenAI key is never sent to a custom server. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Aldin <smajlovicaldin52@gmail.com>
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.
The OpenAI (realtime) and OpenAI Cloud integrations get an optional Base URL field. Blank keeps today's behavior (api.openai.com). When it's set, these go to that server instead:
OpenAIRealtimeLLMService)OpenAIRealtimeSTTService) and TTS (OpenAITTSService)This lets a pipeline run against self-hosted OpenAI-compatible servers. Examples are an OpenAI Realtime-compatible speech-to-speech server such as huggingface/speech-to-speech, or local STT/TTS servers such as Speaches or Chatterbox. That gives fully local voice with barge-in, which the Local runtime bridge can't provide.
Details:
http://host:8000/v1becomesws://host:8000/v1/realtime,httpsbecomeswss, and a URL that already ends in/realtimeis kept as-is.openai_api_keyis never sent to a custom server.base_urlin the pinned Pipecat 1.4 (checked).Testing
tests/test_openai_base_url.py: URL mapping, key handling, and that other kinds ignorebase_url. The full suite passes (python -m unittest discover -s tests, 32 tests).serve(faster-whisper small.en on CPU, a local llama.cpp Qwen model over chat completions, a local OpenAI-compatible TTS). I built the service with this PR's_openai_realtime_serviceon the pinned Pipecat 1.4, using the default flow with a local OpenAI integration (base_url=http://127.0.0.1:8765/v1, no API key). Then I streamed two spoken utterances into it in real time: a request for a long story, and an interruption ("Stop. Never mind the story. What is two plus two?") 3 s into the answer. With the flow's Interrupt response enabled, the story was cut off about 1.1 s into the interruption and the assistant answered "2 plus 2 is 4.", with first audio about 2.3 s after the question ended.interrupt_response: false, the server correctly ignores speech during a response (it logsinterrupt_response disabled, ignoring). The answer to the interruption then queues behind the rest of the story. So local barge-in needs that flow toggle on, and the docs paragraph says so.The UI bundle (
app/ui/index.js) is rebuilt fromui-src.index.htmlis left at its current version stamp.🤖 Generated with Claude Code