Repository navigation
feat(api): support backend-mediated Realtime WebRTC calls - #2469
Conversation
Castiron-Internal-PR: openai/openai-node-internal#79 Castiron-Source-SHA: 2871e2b19388f9a0ec13476d3ee31eeac98ec458 Castiron-Public-Base-SHA: a90581e
Castiron custom code✅ No new custom-code files detected. 32 mixed files remain; 0 existing customizations changed. Compared 32 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 32890174854 --repo openai/openai-node \
--name castiron-custom-code-32890174854-1 --dir /tmp/castiron-custom-code-32890174854-1
git apply --stat /tmp/castiron-custom-code-32890174854-1/custom-code.patch
cat /tmp/castiron-custom-code-32890174854-1/custom-code.patchOr reproduce it from an SDK checkout containing the vendored reporter: git fetch --no-tags origin a90581ed85f236a2440102fe64320f1831844b50 0917b92069c79776fa847331b43131f711245683
python3 scripts/castiron/custom_code_report.py report \
--base a90581ed85f236a2440102fe64320f1831844b50 \
--head 0917b92069c79776fa847331b43131f711245683 --fetch --require-head-hash --public \
--out /tmp/castiron-custom-code-0917b92069c7
cat /tmp/castiron-custom-code-0917b92069c7/custom-code.patchThis is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR. |
| describe('resource calls', () => { | ||
| // binary tests are currently broken | ||
| test.skip('create: required and optional params', async () => { | ||
| const response = await client.realtime.calls.create({ |
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0917b92069
ℹ️ 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".
| rawBodyField !== null && | ||
| Object.keys(body).length === 1 && | ||
| Object.prototype.hasOwnProperty.call(body, rawBodyField) |
There was a problem hiding this comment.
Keep project-API-key SDP calls multipart
When a caller uses a normal project API key and omits the optional session field—as in the new create({ sdp }) JSDoc example—this condition switches the request to raw application/sdp. The checked-in schema at api_reference/openapi.transformed.yml:16013-16019 reserves that alternative for authentication with a previously created ephemeral session token, whereas the multipart schema permits an omitted session. The ordinary minimal SDK call is therefore sent in the wrong authentication mode; default it to multipart or require an explicit raw/ephemeral selection instead of inferring the mode from object cardinality.
AGENTS.md reference: AGENTS.md:L12-L21
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I checked this against the live API with a normal project API key (not an ephemeral token). The proposed authentication restriction does not match the observed behavior: raw application/sdp works with project-key authentication.
With a valid WebRTC offer saved as offer.sdp and a project key in OPENAI_API_KEY, these requests both omit session:
# Raw SDP: 201 Created, SDP answer, and Location header.
curl -i 'https://api.openai.com/v1/realtime/calls?model=gpt-realtime' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/sdp' \
--data-binary @offer.sdp
# Multipart with only an SDP part: same successful result.
curl -i 'https://api.openai.com/v1/realtime/calls?model=gpt-realtime' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F 'sdp=<offer.sdp;type=application/sdp'Repeating both requests without ?model=gpt-realtime produces the same 400 / missing_model error:
| Format, session omitted | No model | Query model supplied |
|---|---|---|
| Raw SDP | 400 missing_model | 201 Created |
| Multipart | 400 missing_model | 201 Created |
The successful test calls were hung up afterward. To clean up a reproduction, POST to the call's Location URL with /hangup appended, using the same authorization.
So the minimal project-key example needs a model; changing its encoding to multipart does not fix that. The schema's ephemeral-token guidance should not be interpreted as an exclusive authentication requirement.
The JSDoc example is incomplete for project-key use because it supplies neither session configuration nor a query model. That is a documentation issue, not evidence that the raw request uses the wrong authentication mode. I don't think this finding warrants changing the encoder or adding an explicit ephemeral-auth selection.
jbeckwith-oai
left a comment
There was a problem hiding this comment.
Requesting changes for the existing P1 discussion at src/internal/multipart-encoding.ts:21. The documented minimal client.realtime.calls.create({ sdp }) with a normal project API key is encoded as raw application/sdp merely because optional session is absent. The checked-in API schema reserves the raw SDP alternative for an existing ephemeral session token; ordinary project-key backend calls must remain multipart even when session configuration is omitted. Default to typed multipart and expose raw SDP only for an explicitly selected ephemeral-auth flow. Existing inline discussion already captures this blocker.
Summary
Add
client.realtime.calls.createso server-side applications can exchange an SDP offer and optional session configuration for an SDP answer.This makes WebRTC signaling available through the SDK instead of requiring a handwritten HTTP request. The request preserves the API’s SDP and JSON content types, and the returned
Responseexposes the SDP answer for the browser.