Merge main into PR #621 (ChatGPT OAuth for Realtime voice)

Resolve conflicts with the voice-core captions, panel resize and MCP
panel key changes by keeping both sides.
This commit is contained in:
Sameh Khamis committed 2026-10-08 11:00:54 -07:00
commit fb1596d2f1
244 files changed
+40846 -1558

No files matched your search

+15
View File
@@ -10,6 +10,7 @@ import {
OPENAI_REALTIME_REASONING_DEFAULT,
OPENAI_REALTIME_CONTEXT_TOKENS_DEFAULT,
OPENAI_REALTIME_CONTEXT_RETENTION_DEFAULT,
OPENAI_REALTIME_TRANSCRIBE_MODEL_DEFAULT,
} from './constants.js';
import { realtimeInstructions } from './instructions.js';
import { GEV_REALTIME_TOOLS } from './tools.js';
@@ -264,6 +265,14 @@ function createRealtimeTokenHandler({
OPENAI_REALTIME_CONTEXT_RETENTION_DEFAULT,
),
);
// User captions for the voice card. Billed separately from the session.
const transcribeModel =
process.env.OPENAI_REALTIME_TRANSCRIBE_MODEL ||
OPENAI_REALTIME_TRANSCRIBE_MODEL_DEFAULT;
const transcription =
transcribeModel.toLowerCase() === 'off'
? {}
: { transcription: { model: transcribeModel } };
const sessionConfig = {
session: {
type: 'realtime',
@@ -279,6 +288,7 @@ function createRealtimeTokenHandler({
audio: {
input: {
noise_reduction: { type: 'near_field' },
...transcription,
turn_detection: {
type: 'semantic_vad',
eagerness: 'low',
@@ -318,6 +328,11 @@ function createRealtimeTokenHandler({
'X-GEV-Voice-Auth',
authMode === 'oauth' ? 'codex-oauth' : 'env',
);
// Captions are billed separately; the client meters them with this id.
res.setHeader(
'X-GEV-Voice-Transcribe-Model',
transcription.transcription ? transcribeModel : 'off',
);
if (requestedTier && !isKnownVoiceTier(requestedTier)) {
res.setHeader('X-GEV-Voice-Tier-Fallback', '1');
}