Skip to content

fix(openai realtime): keep derived capabilities in sync with updateOptions - #2323

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
enshrine-avionics-denudesfrom
decimal-hector-talked
Open

fix(openai realtime): keep derived capabilities in sync with updateOptions#2323
rosetta-livekit-bot[bot] wants to merge 1 commit into
enshrine-avionics-denudesfrom
decimal-hector-talked

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Ports livekit/agents#6943 to the JS OpenAI Realtime implementation.

Summary

  • derive turn-taking and transcription capabilities from current model options
  • keep independent per-session capabilities synchronized while preserving model/session isolation
  • propagate model option updates to active sessions and preserve the source warning behavior
  • add the three source regression tests and a minor changeset for the new public update/session capability APIs

Source diff coverage

Source diff coverage
Source file Classification Target coverage
livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/realtime/realtime_model.py Adapted plugins/openai/src/realtime/realtime_model.ts; camelCase and JS OpenAI wire types are used for the shared capability derivation, model/session updateOptions, active-session propagation, warning, and per-session capability copy. agents/src/llm/realtime.ts adds the prerequisite default session capability getter that already exists in Python but was absent in JS.
tests/test_realtime/test_openai_realtime_model.py Adapted plugins/openai/src/realtime/realtime_model.test.ts; all three tests added by #6943 are ported to Vitest using the existing task stub instead of Python SimpleNamespace.

No source files were not applicable.

Validation

  • pnpm test agents: 112 files passed, 1522 tests passed, 5 skipped
  • env -u OPENAI_API_KEY pnpm test plugins/openai: 5 files passed, 2 skipped; 75 tests passed, 7 skipped
  • pnpm test plugins/openai/src/realtime/realtime_model.test.ts: 50 tests passed
  • pnpm build: 40 workspace tasks passed
  • pnpm --filter @livekit/agents-plugin-openai build: passed
  • changed-file ESLint: passed with two pre-existing warnings
  • cue-cli: live OpenAI Realtime text turn passed after updateOptions disabled server turn taking; assistant framework event resolved in 812 ms

Package-wide lint was run for both touched packages. It remains blocked by existing repository formatting failures (184 findings in @livekit/agents, 15 in the OpenAI plugin) under the available Node 20/pnpm 9 environment; the repository declares pnpm 11, which requires Node 22 and cannot run here.


Ported from livekit/agents#6943

Original PR description

Problem

capabilities.turn_detection and capabilities.user_transcription come from constructor options, but update_options changed those options and left the capabilities alone.
A model switched to create_response=False does client-side turn taking (#6642), and the stale capability still reports that the server owns the turn.
AgentActivity then refuses allow_interruptions=False, and _resolve_rt_turn_detection_enabled selects the wrong mode for endpointing and for realtime-session reuse across a handoff.
Turn detection is also per session, because session(turn_detection_disabled=True) switches it off for one session, but the only capabilities object was on the model.

Fix

One function now derives server-side turn taking, and both the constructor and update_options call it, so the two cannot drift apart again.
RealtimeSession keeps its own capabilities copy and updates it from its own update_options.
One session can now hand turn taking to the client while the model and its other sessions stay unchanged.
The function also carries the interrupt_response warning, which update_options did not give before.

The turn_detection_disabled branch in the session constructor has no unit test, because a real session opens a websocket in __init__.

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner August 22, 2026 05:28
@changeset-bot

changeset-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 932a46e

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

This PR includes changesets to release 39 packages
Name Type
@livekit/agents Major
@livekit/agents-plugin-openai Major
@livekit/agents-plugin-anam Major
@livekit/agents-plugin-anthropic Major
@livekit/agents-plugin-assemblyai Major
@livekit/agents-plugin-azure Major
@livekit/agents-plugin-baseten Major
@livekit/agents-plugin-bey Major
@livekit/agents-plugin-cartesia Major
@livekit/agents-plugin-cerebras Major
@livekit/agents-plugin-deepgram Major
@livekit/agents-plugin-did Major
@livekit/agents-plugin-elevenlabs Major
@livekit/agents-plugin-fishaudio Major
@livekit/agents-plugin-google Major
@livekit/agents-plugin-hedra Major
@livekit/agents-plugin-hume Major
@livekit/agents-plugin-inworld Major
@livekit/agents-plugin-krisp Major
@livekit/agents-plugin-lemonslice Major
@livekit/agents-plugin-liveavatar Major
@livekit/agents-plugin-livekit Major
@livekit/agents-plugin-minimax Major
@livekit/agents-plugin-mistral Major
@livekit/agents-plugin-mistralai Major
@livekit/agents-plugin-neuphonic Major
@livekit/agents-plugin-perplexity Major
@livekit/agents-plugin-phonic Major
@livekit/agents-plugin-protoface Major
@livekit/agents-plugin-resemble Major
@livekit/agents-plugin-rime Major
@livekit/agents-plugin-runway Major
@livekit/agents-plugin-sarvam Major
@livekit/agents-plugin-silero Major
@livekit/agents-plugin-soniox Major
@livekit/agents-plugin-tavus Major
@livekit/agents-plugins-test Major
@livekit/agents-plugin-trugen Major
@livekit/agents-plugin-xai Major

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

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from longcw August 22, 2026 05:29

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review. (Configure)

Open in Devin Review

Comment on lines +402 to +407
session.updateOptions({
...options,
turnDetection:
options.turnDetection !== undefined ? this._options.turnDetection : undefined,
inputAudioTranscription: this._options.inputAudioTranscription,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Model option updates overwrite per-session transcription config

updateOptions gates turnDetection behind options.turnDetection !== undefined when forwarding to sessions but forwards inputAudioTranscription unconditionally as this._options.inputAudioTranscription. Any model-level update, even one changing only voice, then resets every session's transcription setting and userTranscription capability to the model's value, discarding session-specific customization.

Suggested change
session.updateOptions({
...options,
turnDetection:
options.turnDetection !== undefined ? this._options.turnDetection : undefined,
inputAudioTranscription: this._options.inputAudioTranscription,
});
session.updateOptions({
...options,
turnDetection:
options.turnDetection !== undefined ? this._options.turnDetection : undefined,
inputAudioTranscription:
options.inputAudioTranscription !== undefined
? this._options.inputAudioTranscription
: undefined,
});
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

0 participants