Skip to content

fix: support GA transcription-type sessions in POST /v1/realtime/client_secrets#5092

Open
Shaik-Sirajuddin wants to merge 2 commits into
maximhq:devfrom
Shaik-Sirajuddin:worktree-realtime-ga-transcription-fix
Open

fix: support GA transcription-type sessions in POST /v1/realtime/client_secrets#5092
Shaik-Sirajuddin wants to merge 2 commits into
maximhq:devfrom
Shaik-Sirajuddin:worktree-realtime-ga-transcription-fix

Conversation

@Shaik-Sirajuddin

@Shaik-Sirajuddin Shaik-Sirajuddin commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

POST /v1/realtime/client_secrets mints both full realtime sessions and GA transcription-only sessions (session.type: "transcription"), but model extraction only checked session.model — the transcription schema has no such field, only session.audio.input.transcription.model. Every transcription-type request 400'd; confirmed live against real OpenAI.

Changes

  • ExtractRealtimeClientSecretModel falls back to the nested transcription model when session.model is absent.
  • Added schemas.IsGATranscriptionSessionBody, a single classifier shared by extraction and both normalization layers (handler + provider), so they can't disagree on the same body. Explicit session.type wins when present; otherwise session.model/legacy root model beat the structural fallback, so a full session with transcription enabled as a sibling feature is never misclassified.
  • Writes the model into the correct nested slot for transcription sessions instead of a bogus top-level session.model; the alias-resolution rewrite does the same.
  • A first pass introduced its own classification bugs, caught by codex --yolo review and fixed in a follow-up commit.

Type of change

  • Bug fix

How to test

cd core && go test ./schemas/... ./providers/openai/... ./providers/azure/...
cd ../transports/bifrost-http && go test ./handlers/...

Also live-verified against real OpenAI's platform API using the openai Python SDK (and curl): minted a real GA transcription-session client_secret, and confirmed the regression scenario (full session + transcription sibling) keeps type: "realtime" and the correct model.

Breaking changes

  • No

…crets

POST /v1/realtime/client_secrets mints both full realtime sessions
(session.model set) and transcription-only sessions
(session.type=="transcription", RealtimeTranscriptionSessionCreateRequestGA)
through the same endpoint. The transcription-session schema has no
top-level session.model at all - the model lives only at
session.audio.input.transcription.model - so every such request 400'd
with "session.model or model is required", confirmed live against
real OpenAI.

- ExtractRealtimeClientSecretModel now falls back to
  session.audio.input.transcription.model when session.model is absent.
- normalizeRealtimeClientSecretsRequest detects a transcription-shaped
  session (explicit type, or inferred from the audio.input.transcription
  shape with no model set) and writes the resolved model into the
  nested slot instead of adding a bogus top-level session.model that
  isn't part of this schema, and sets type="transcription" instead of
  defaulting to "realtime".
- The handler's alias-resolution rewrite (fires when a virtual key
  alias changes the routing model after key selection) now also
  targets the nested slot for transcription-shaped sessions - it
  previously only rewrote session.model, so an alias change would
  silently not reach transcription sessions.
…review

codex --yolo review of the previous commit found 4 real bugs, all
verified end-to-end and against real OpenAI:

- Critical: a full realtime session using the legacy top-level "model"
  field, with live input-audio transcription enabled as a completely
  standard sibling feature, had its model extraction hijacked by the
  nested transcription model and got silently reclassified as
  transcription-only - losing the real conversational model entirely.
  Root cause: the GA-nested extraction fallback ran before the legacy
  root-model fallback.
- The transcription-type write branch never deleted a pre-existing
  stray session.model, leaking an un-stripped, schema-invalid field
  upstream.
- The structural fallback classifier checked key presence instead of
  non-null, so an explicit audio.input.transcription: null (used to
  disable transcription on a full session) was misread as enabling it.
- The handler's alias-resolution pass and the provider's normalization
  pass used two different, independently-written classification
  heuristics that could disagree on the same body.

Fixes all four by consolidating classification into a single exported
function, schemas.IsGATranscriptionSessionBody, used by extraction and
both normalization layers so they cannot diverge. Priority: explicit
session.type is authoritative when present (it's the schema's actual
discriminator); only when absent do session.model / legacy root model
take precedence over the audio.input.transcription structural
fallback - a full session must never be reclassified just because it
also enables transcription as a sibling feature.

Added regression tests for all 4 findings at each layer (schema
extraction, provider normalization, handler end-to-end), and
re-verified live against real OpenAI that both the GA transcription
path and the exact regression scenario now behave correctly.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

GA transcription-only realtime sessions now extract and rewrite models from session.audio.input.transcription.model. Full realtime sessions retain root-model behavior, while OpenAI normalization defaults and removes session fields according to the detected session shape.

Changes

GA transcription session handling

Layer / File(s) Summary
Session classification and model extraction
core/schemas/realtime_client_secrets.go, core/schemas/realtime_client_secrets_test.go
Adds GA transcription-shape detection and nested model extraction with explicit handling for null, legacy, and full realtime session fields.
Handler model resolution and nested rewriting
transports/bifrost-http/handlers/realtime_client_secrets.go, transports/bifrost-http/handlers/realtime_client_secrets_test.go
Resolves nested transcription models and rewrites them during alias normalization while preserving root models for full realtime sessions.
OpenAI provider normalization
core/providers/openai/realtime.go, core/providers/openai/realtime_test.go
Writes normalized models into nested transcription configuration, removes stale top-level session models, and applies transcription or realtime defaults by session shape.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant HTTPHandler
  participant RealtimeSchemas
  participant OpenAIProvider
  Client->>HTTPHandler: Submit realtime client-secret request
  HTTPHandler->>RealtimeSchemas: Classify session and extract model
  RealtimeSchemas-->>HTTPHandler: Resolved provider and model
  HTTPHandler->>HTTPHandler: Rewrite nested transcription model
  HTTPHandler->>OpenAIProvider: Normalize session request
  OpenAIProvider-->>HTTPHandler: Normalized realtime session
Loading

Possibly related PRs

  • maximhq/bifrost#3334: Both changes modify OpenAI realtime client-secret normalization around nested transcription model handling.

Suggested reviewers: akshaydeo, danpiths, roroghost17, Pratham-Mishra04

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: GA transcription-type session support for POST /v1/realtime/client_secrets.
Description check ✅ Passed The description covers the main summary, changes, type, testing, and breaking-changes sections; only some optional template sections are omitted.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • The classifier is shared across the parsing and normalization paths.
  • The tests cover the main shape conflicts between full realtime sessions and transcription-only sessions.

Important Files Changed

Filename Overview
core/schemas/realtime_client_secrets.go Adds nested GA transcription model extraction and a shared session-shape classifier.
core/providers/openai/realtime.go Updates provider normalization to preserve the transcription-session wire shape and write the model into the nested transcription field.
transports/bifrost-http/handlers/realtime_client_secrets.go Updates handler normalization and alias rewrites to use the shared classifier and nested transcription model path.
core/providers/openai/realtime_test.go Adds provider normalization coverage for GA transcription sessions and full realtime sessions with transcription sibling config.
core/schemas/realtime_client_secrets_test.go Adds extraction and classification coverage for GA transcription and full realtime request shapes.
transports/bifrost-http/handlers/realtime_client_secrets_test.go Adds handler and two-pass normalization tests for transcription sessions and alias rewrites.

Reviews (1): Last reviewed commit: "fix: correct GA transcription-session cl..." | Re-trigger Greptile

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