Skip to content

fix(openai): include ?model= on Responses-API and realtime STT WebSocket URLs#1467

Open
enriqueespaillat-gyde wants to merge 1 commit into
livekit:mainfrom
enriqueespaillat-gyde:enrique/ws-url-model-param
Open

fix(openai): include ?model= on Responses-API and realtime STT WebSocket URLs#1467
enriqueespaillat-gyde wants to merge 1 commit into
livekit:mainfrom
enriqueespaillat-gyde:enrique/ws-url-model-param

Conversation

@enriqueespaillat-gyde
Copy link
Copy Markdown
Contributor

@enriqueespaillat-gyde enriqueespaillat-gyde commented May 12, 2026

Summary

Two of the OpenAI plugin's three WebSocket endpoints open the connection without a ?model= query parameter:

  • Responses-API LLM (plugins/openai/src/ws/llm.ts) — opens wss://.../responses with no model in the URL.
  • Realtime STT (plugins/openai/src/stt.ts) — opens wss://.../realtime?intent=transcription with no model in the URL.

The third endpoint — the conversational realtime API in plugins/openai/src/realtime/realtime_model.tsalready includes the model:

// Standard OpenAI: /realtime?model=<model>
queryParams['model'] = model;

This PR extends the same convention to the other two endpoints.

Why

OpenAI-compatible proxies route WebSocket connections at the HTTP upgrade — they don't (and generally can't) wait for and parse the first WS frame to discover which model the client wants. LiteLLM is the most concrete example: its realtime routing docs require ?model= on the upgrade URL (e.g., ws://0.0.0.0:4000/v1/realtime?model=openai-gpt-4o-realtime-audio) and reject the connection without it. Other OpenAI-compatible gateways (Cloudflare AI Gateway, Helicone, Portkey) have the same shape of constraint when they expose realtime endpoints.

OpenAI's own native endpoints accept and ignore the parameter — which is what makes the existing realtime_model.ts behavior safe today, and what makes this change a no-op for users hitting api.openai.com directly.

Changes

  • ws/llm.ts: extract buildResponsesWsUrl(baseURL, model), set ?model= on the URL.
  • stt.ts: extract buildRealtimeSttUrl(baseURL, model), set ?model= on the URL.
  • Unit tests for both URL builders covering OpenAI-direct, custom baseURL, trailing-slash and /v1-suffix handling.

Both helpers are @internal in JSDoc; they're exported only so the URL construction can be unit-tested without instantiating the full LLM/STT class. Happy to keep them module-private (matching processBaseURL in realtime_model.ts) if preferred — let me know.

Test plan

  • pnpm test plugins/openai/src/ws/url.test.ts plugins/openai/src/stt.test.ts — 12 passed, 1 skipped (the pre-existing integration test that requires OPENAI_API_KEY)
  • pnpm --filter @livekit/agents-plugin-openai build — clean
  • pnpm --filter @livekit/agents-plugin-openai lint — no new warnings
  • pnpm format:write — no changes outside touched files

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

…ket URLs

OpenAI-compatible gateways (LiteLLM, Cloudflare AI Gateway, Helicone,
Portkey, etc.) can only see the URL at the WebSocket upgrade — they
cannot read the subsequent `session.update` / `response.create` frame
to determine which backend to dial. The conversational endpoint in
`realtime/realtime_model.ts` already includes the model in the upgrade
URL; this aligns the Responses-API LLM and realtime STT paths with the
same convention. OpenAI's native endpoints accept and ignore the
parameter, so this is a no-op for direct connections.

- `ws/llm.ts`: extract `buildResponsesWsUrl()` and append `?model=`
- `stt.ts`: extract `buildRealtimeSttUrl()` and append `?model=`
- add unit tests for both URL builders
@enriqueespaillat-gyde enriqueespaillat-gyde force-pushed the enrique/ws-url-model-param branch from 53ddc8e to 7842d89 Compare May 12, 2026 12:58
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

🦋 Changeset detected

Latest commit: 7842d89

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 31 packages
Name Type
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-xai Patch
@livekit/agents Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugins-test Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant