feat(realtime): add typed create_response helper to RealtimeSession#3722
feat(realtime): add typed create_response helper to RealtimeSession#3722Skyline-9 wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8eef197b9c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| response = ( | ||
| OpenAIRealtimeResponseCreateParams(**response_params) if response_params else None | ||
| ) | ||
| return OpenAIResponseCreateEvent(type="response.create", response=response) |
There was a problem hiding this comment.
When session.create_response() is called without instructions or metadata, this still passes response=None into the event constructor. Pydantic treats explicitly supplied None as a set field, so _send_raw_message(...exclude_unset=True) serializes it as "response": null rather than the minimal {"type":"response.create"} payload used by the existing raw path. For no-argument response creation, that can be rejected by the Realtime schema even though the helper is documented as equivalent to an empty response.create; construct the event without the response keyword when there are no params.
Useful? React with 👍 / 👎.
Omit the response field entirely when no per-response params are provided so the serialized payload is a bare response.create instead of {"response": null}, which the Realtime schema can reject.
|
@codex review |
8eef197 to
564ac50
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 564ac50d8a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| instructions: str | None = None | ||
| """Optional instructions that override the session instructions for this response only.""" | ||
|
|
||
| metadata: dict[str, Any] | None = None |
There was a problem hiding this comment.
Use string-valued response metadata
When a caller passes create_response(metadata={"turn": 1}) or any other non-string value, this new typed event says the value is valid and then forwards it unchanged into RealtimeResponseCreateParams; the Realtime API/OpenAI SDK schema defines response metadata as string key/value pairs, so typed callers do not get checker feedback and instead hit validation or API errors at runtime. Please match the API surface with dict[str, str] here and on the public RealtimeSession.create_response parameter.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 564ac50d8a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| instructions: str | None = None | ||
| """Optional instructions that override the session instructions for this response only.""" | ||
|
|
||
| metadata: dict[str, Any] | None = None |
There was a problem hiding this comment.
Narrow response metadata values to strings
The Realtime response-create payload this is converted into expects platform metadata as dict[str, str], but the new event type permits arbitrary values. In practice session.create_response(metadata={"turn": 1}) type-checks through this API and then fails during OpenAIRealtimeResponseCreateParams conversion before any event is sent; expose dict[str, str] here and in the session helper so invalid metadata is caught at the call site.
Useful? React with 👍 / 👎.
Summary
Adds a typed
RealtimeSession.create_response(*, instructions=None, metadata=None)helper so applications can request a model response with per-response overrides without hand-rolling a rawresponse.createmessage.Today the only way to trigger a response with custom
instructions/metadatais to send a raw protocol event through the low-level model escape hatch, which bypasses the SDK's response-create sequencing and is easy to get wrong (doubleresponse.create, "conversation already has an active response" errors). This adds a small, typed, well-sequenced entry point that mirrors the ergonomics of the rest of the realtime API (send_message,interrupt).What changed:
RealtimeSession.create_response(*, instructions, metadata)(keyword-only, appended afterinterrupt()so no existing API is reordered).RealtimeModelSendResponseCreatedataclass added to theRealtimeModelSendEventunion (optional fields, appended at the end of the union).OpenAIRealtimeWebSocketModel.send_eventroutes it through the existing response-create sequencer (_reserve_response_create_request(manual=True)+_start_response_create(..., manual=True)->wait_for_response_create_slot), so it cannot collide with an in-flight response and never emits a doubleresponse.create.instructions,metadata). With no arguments it serializes to a bareresponse.create(noresponseobject), viamodel_dump_json(exclude_unset=True).agents.realtime.__init__(__all__), consistent withRealtimeModelSendInterrupt; not added to the top-levelagentsnamespace.docs/realtime/guide.mddocuments thatinstructions/metadataare per-response overrides that do not mutate the agent.Test plan
tests/realtime/test_session.py,tests/realtime/test_openai_realtime.py, andtests/realtime/test_openai_realtime_conversions.py:create_responsedefers while a response is active and sends exactly oneresponse.createafter the active response completes (sequencer cooperation).response.create; only-instructionsomitsmetadata; conversion includes only provided fields.RealtimeModelSendResponseCreate.make format,make lint,make typecheck— passuv run pytest -k realtime— pass (307 passed, 1 skipped)make build-docs— passIssue number
N/A. Fits the broader direction of making the realtime API a typed first-class surface rather than requiring raw protocol messages. Happy to link a tracking issue if preferred.
Checks
.agents/skills/code-change-verification/scripts/run.shmake format,make lint,make typecheck, realtime tests, andmake build-docs)/reviewbefore submitting this PRCompatibility notes
Additive. Adding
RealtimeModelSendResponseCreateto theRealtimeModelSendEventunion means a third-partyRealtimeModel.send_eventimplementation gains a new union member it does not yet handle; the built-in OpenAI WebSocket/SIP models handle it. The dataclass fields are optional and appended at the end of the union, and the public method is keyword-only and appended after existing methods.