Repository navigation
feat(api): Add Live API - #3846
Conversation
Castiron-Internal-PR: openai/openai-python-internal#83 Castiron-Source-SHA: 211418be997d8866419baaf4d6c966f1a93767d6 Castiron-Public-Base-SHA: 802b334
Castiron custom codeMixed files: 36 → 41 5 newly customized · 0 customizations removed · 0 existing customizations changed · 7 generated baselines changed Compared
31 existing customizations unchanged
A changed generated baseline means this report cannot reliably identify which handwritten lines changed. Inspect the custom-code diffDownload the exact patch produced by this run (requires repository access): gh run download 34506356297 --repo openai/openai-python \
--name castiron-custom-code-34506356297-1 --dir /tmp/castiron-custom-code-34506356297-1
git apply --stat /tmp/castiron-custom-code-34506356297-1/custom-code.patch
cat /tmp/castiron-custom-code-34506356297-1/custom-code.patchOr reproduce it from an SDK checkout containing the vendored reporter: git fetch --no-tags origin 802b334928d8f0c3e24e5fce15a0eaa1b28c61cd d3557967abc8c99100bc10838849cfb9be957c4b
python3 scripts/castiron/custom_code_report.py report \
--base 802b334928d8f0c3e24e5fce15a0eaa1b28c61cd \
--head d3557967abc8c99100bc10838849cfb9be957c4b --fetch --require-head-hash --public \
--out /tmp/castiron-custom-code-d3557967abc8
cat /tmp/castiron-custom-code-d3557967abc8/custom-code.patchThis is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
| with sync: | ||
| sync.push(text()) | ||
| raise ValueError("body") | ||
| assert sync._state.closed |
|
|
||
| chat: Chat = ChatProxy().__as_proxied__() | ||
| beta: Beta = BetaProxy().__as_proxied__() | ||
| live: Live = LiveProxy().__as_proxied__() |
| self._listeners_lock = threading.Lock() | ||
|
|
||
| @overload | ||
| def on(self, event_type: Literal["segment.updated"], handler: Callable[[TranscriptSegment], _ReturnT]) -> Self: ... |
| @overload | ||
| def on( | ||
| self, event_type: Literal["segment.closed"], handler: Callable[[TranscriptSegmentClosedEvent], _ReturnT] | ||
| ) -> Self: ... |
| @overload | ||
| def on( | ||
| self, event_type: Literal["segment.updated"] | ||
| ) -> Callable[[Callable[[TranscriptSegment], _ReturnT]], Callable[[TranscriptSegment], _ReturnT]]: ... |
| self, event_type: Literal["segment.closed"] | ||
| ) -> Callable[ | ||
| [Callable[[TranscriptSegmentClosedEvent], _ReturnT]], Callable[[TranscriptSegmentClosedEvent], _ReturnT] | ||
| ]: ... |
| @overload | ||
| def once( | ||
| self, event_type: Literal["segment.updated"], handler: Callable[[TranscriptSegment], _ReturnT] | ||
| ) -> Self: ... |
| @overload | ||
| def once( | ||
| self, event_type: Literal["segment.closed"], handler: Callable[[TranscriptSegmentClosedEvent], _ReturnT] | ||
| ) -> Self: ... |
| @overload | ||
| def once( | ||
| self, event_type: Literal["segment.updated"] | ||
| ) -> Callable[[Callable[[TranscriptSegment], _ReturnT]], Callable[[TranscriptSegment], _ReturnT]]: ... |
| self, event_type: Literal["segment.closed"] | ||
| ) -> Callable[ | ||
| [Callable[[TranscriptSegmentClosedEvent], _ReturnT]], Callable[[TranscriptSegmentClosedEvent], _ReturnT] | ||
| ]: ... |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3557967ab
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| then you can call `.parse_event(data)`. | ||
| """ | ||
| message = await self._connection.recv(decode=False) | ||
| log.debug(f"Received WebSocket message: %s", message) |
There was a problem hiding this comment.
Stop logging raw Live messages
When debug logging is enabled, every incoming frame is written verbatim, including user transcripts, reflected input audio, generated audio, and potentially sensitive response payloads. The same logging is duplicated in the sync, sideband, and fork connections, so these messages can persist customer data in application logs; log only sanitized metadata such as the event type.
AGENTS.md reference: AGENTS.md:L26-L30
Useful? React with 👍 / 👎.
| }, | ||
| extra_headers, | ||
| ), | ||
| **self.__websocket_connection_options, |
There was a problem hiding this comment.
Disable the WebSocket library's default message cap
When callers use the default connection options, this delegates to websockets without overriding its 1 MiB max_size, so a legitimate larger Live JSON or streaming event causes the transport to close with code 1009 before recv() can return it. The sync, sideband, and fork connection paths have the same default; supply max_size=None unless explicitly overridden, or otherwise process large messages without imposing a fixed rejection limit.
AGENTS.md reference: AGENTS.md:L114-L120
Useful? React with 👍 / 👎.
| SessionClosedEvent, | ||
| ErrorEvent, | ||
| InfoEvent, | ||
| ], |
There was a problem hiding this comment.
Include sideband-only events in ConnectServerEvent
For a sideband connection, the server can emit session.input_audio.append and the transport.dtmf.*, transport.ringing, transport.answered, and transport.failed events, but this union ends without those variants even though SidebandConnection.parse_event() uses it. Because loose union construction falls back to the first variant for an unknown discriminator, such an event can be returned as a malformed SessionStartedEvent rather than its actual typed model, breaking isinstance dispatch and typed access to fields such as audio or event.
Useful? React with 👍 / 👎.
| class AudioPCMU(TypedDict, total=False): | ||
| """Raw, mono G.711 μ-law audio for a Live WebSocket connection.""" | ||
|
|
||
| rate: Required[int] |
There was a problem hiding this comment.
Restrict G.711 sample rates to 8000 Hz
For callers configuring a primary Live WebSocket with PCMU or PCMA audio, these request types accept any integer even though the API contract and adjacent documentation allow only 8000 Hz; for example, a type-checked {"type": "audio/pcmu", "rate": 16000} request is serialized normally and then rejected by the server. Model the rate field as Literal[8000] for both G.711 variants, as is already done for the supported PCM rates.
Useful? React with 👍 / 👎.
TranscriptGrouperandAsyncTranscriptGrouperhelpers.