(
ws: WebSocketConnection,
fixtures: Fixture[],
journal: Journal,
defaults: {
latency: number;
chunkSize: number;
replaySpeed?: number;
model: string;
logger: Logger;
strict?: boolean;
requestTransform?: (req: ChatCompletionRequest) => ChatCompletionRequest;
testId?: string;
upgradeHeaders?: import("node:http").IncomingHttpHeaders;
},
)
| 300 | // ─── Main handler ─────────────────────────────────────────────────────────── |
| 301 | |
| 302 | export function handleWebSocketRealtime( |
| 303 | ws: WebSocketConnection, |
| 304 | fixtures: Fixture[], |
| 305 | journal: Journal, |
| 306 | defaults: { |
| 307 | latency: number; |
| 308 | chunkSize: number; |
| 309 | replaySpeed?: number; |
| 310 | model: string; |
| 311 | logger: Logger; |
| 312 | strict?: boolean; |
| 313 | requestTransform?: (req: ChatCompletionRequest) => ChatCompletionRequest; |
| 314 | testId?: string; |
| 315 | upgradeHeaders?: import("node:http").IncomingHttpHeaders; |
| 316 | }, |
| 317 | ): void { |
| 318 | const { logger } = defaults; |
| 319 | const sessionId = realtimeId("sess"); |
| 320 | |
| 321 | const isBeta = defaults.upgradeHeaders?.["openai-beta"] |
| 322 | ? String(defaults.upgradeHeaders["openai-beta"]).includes("realtime=v1") |
| 323 | : false; |
| 324 | |
| 325 | const session: SessionConfig = { |
| 326 | model: defaults.model, |
| 327 | modalities: ["text"], |
| 328 | instructions: "", |
| 329 | tools: [], |
| 330 | voice: null, |
| 331 | input_audio_format: null, |
| 332 | output_audio_format: null, |
| 333 | input_audio_noise_reduction: null, |
| 334 | input_audio_transcription: null, |
| 335 | turn_detection: null, |
| 336 | temperature: 0.8, |
| 337 | type: "conversation", |
| 338 | reasoning: null, |
| 339 | }; |
| 340 | |
| 341 | const conversationItems: RealtimeItem[] = []; |
| 342 | |
| 343 | // Send session.created immediately on connect (GA format — shim flattens for Beta) |
| 344 | sendEvent( |
| 345 | ws, |
| 346 | { |
| 347 | type: "session.created", |
| 348 | session: { |
| 349 | id: sessionId, |
| 350 | object: "realtime.session", |
| 351 | model: session.model, |
| 352 | expires_at: Math.floor(Date.now() / 1000) + 3600, |
| 353 | modalities: session.modalities, |
| 354 | instructions: session.instructions, |
| 355 | tools: session.tools, |
| 356 | tool_choice: "auto", |
| 357 | temperature: session.temperature, |
| 358 | max_response_output_tokens: "inf", |
| 359 | audio: { |
no test coverage detected
searching dependent graphs…