Skip to content

fix(realtime): preserve base URL routing components - #2567

Open
HAYDEN-OAI wants to merge 1 commit into
mainfrom
dev/hayden/autoimprove-realtime-base-url-path
Open

fix(realtime): preserve base URL routing components#2567
HAYDEN-OAI wants to merge 1 commit into
mainfrom
dev/hayden/autoimprove-realtime-base-url-path

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

Fix Realtime endpoint construction when a custom baseURL contains routing query parameters or a fragment.

  • Append realtime to the parsed URL pathname in both stable and beta Realtime helpers.
  • Preserve routing queries, repeated query values, and escaped path segments; remove fragments before opening the WebSocket.
  • Keep the existing Azure GA path/query normalization, explicit session-parameter precedence, and custom buildRealtimeURL callback behavior unchanged.

Reproduction

Given baseURL: 'https://example.com/v1?route=tenant', string concatenation currently puts the endpoint suffix inside the routing parameter:

Before: wss://example.com/v1?route=tenant%2Frealtime&model=gpt-realtime
After:  wss://example.com/v1/realtime?route=tenant&model=gpt-realtime

The old URL requests the wrong path and corrupts the routing value. A fragment in the base URL likewise absorbs the endpoint suffix and leaves a fragment on the WebSocket URL. Both public native-WebSocket and Node ws wrappers use these helpers.

Regression coverage

Add 21 cases covering query-bearing base URLs with and without trailing slashes, root paths, encoded path segments, repeated routing parameters, fragments, transcription intent, and stable/beta public constructors and asynchronous sideband factories with rotating credentials. Nineteen cases fail before the fix; the two query-free controls already pass.

Validation

  • 178 focused Realtime tests passed.
  • Full local suite: 7,030 handwritten tests, 556 generated tests, and 12 snapshots passed.
  • Formatting, lint, root typechecking, build, and published source checks with TypeScript 4.9 and 6 passed.
  • 84 offline checks through built public native-WebSocket exports passed across Node 22.0.0, 24.20.0, and 26.7.0, each in CommonJS and ESM. These capture actual constructor arguments with synthetic credentials; they do not make live API connections.
  • Full CI passed on this commit: Node 22/24/26 test matrix, packed-package checks on Node 22/24, exact Node 22.0 X.509 compatibility fixture, all 14 ecosystem fixtures, build, lint, and performance benchmarks.
  • Adversarial self-review and independent review covered security, compatibility, URL edge cases, and regression coverage; no unresolved findings.

Scope is four handwritten files only. Generated HTTP-client URL construction, dependencies, and CI policies are unchanged.

@HAYDEN-OAI
HAYDEN-OAI requested a review from a team as a code owner September 2, 2026 00:13
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T00:14:45.473007Z c6cf815 PR opened
🔒 Security Review Completed 2026-09-02T00:16:08.640211Z c6cf815 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@openai-sdks

openai-sdks Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 9.907s for Node SDK PR #2567.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 166ms
tests/chat-completions-create.test.ts ✅ Passed 218ms
tests/chat-completions-stream.test.ts ✅ Passed 208ms
tests/files-content-binary.test.ts ✅ Passed 121ms
tests/files-create-multipart.test.ts ✅ Passed 130ms
tests/files-list-pagination.test.ts ✅ Passed 135ms
tests/initialize-config.test.ts ✅ Passed 121ms
tests/instance-isolation.test.ts ✅ Passed 118ms
tests/models-list.test.ts ✅ Passed 142ms
tests/responses-background-lifecycle.test.ts ✅ Passed 230ms
tests/responses-body-method-errors.test.ts ✅ Passed 276ms
tests/responses-cancel-timeout.test.ts ✅ Passed 207ms
tests/responses-cancel.test.ts ✅ Passed 201ms
tests/responses-compact-retries.test.ts ✅ Passed 223ms
tests/responses-compact.test.ts ✅ Passed 215ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 101ms
tests/responses-create-advanced.test.ts ✅ Passed 181ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.137s
tests/responses-create-errors.test.ts ✅ Passed 190ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 187ms
tests/responses-create-retries.test.ts ✅ Passed 266ms
tests/responses-create-stream-failures.test.ts ✅ Passed 180ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.159s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.411s
tests/responses-create-stream.test.ts ✅ Passed 103ms
tests/responses-create-terminal-states.test.ts ✅ Passed 195ms
tests/responses-create-timeout.test.ts ✅ Passed 237ms
tests/responses-create.test.ts ✅ Passed 151ms
tests/responses-delete.test.ts ✅ Passed 125ms
tests/responses-input-items-errors.test.ts ✅ Passed 182ms
tests/responses-input-items-list.test.ts ✅ Passed 174ms
tests/responses-input-items-options.test.ts ✅ Passed 105ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 230ms
tests/responses-input-tokens-count.test.ts ✅ Passed 219ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.03s
tests/responses-not-found-errors.test.ts ✅ Passed 229ms
tests/responses-parse.test.ts ✅ Passed 185ms
tests/responses-retrieve-retries.test.ts ✅ Passed 255ms
tests/responses-retrieve.test.ts ✅ Passed 203ms
tests/responses-stored-method-errors.test.ts ✅ Passed 559ms
tests/retry-behavior.test.ts ✅ Passed 3.04s
tests/sdk-error-shape.test.ts ✅ Passed 237ms

View OkTest run #33574413077

SDK merge (eac82ebd9b81) · head (c6cf81556ebb) · base (82c5b2def367) · OkTest (2b1bdfd25e98)

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Castiron custom code

✅ No new custom-code files detected.

32 mixed files remain; 0 existing customizations changed.

Compared 82c5b2def367c6cf81556ebb. Generated baselines verified.

32 existing customizations unchanged
  • api.md
  • scripts/castiron/README.md
  • scripts/castiron/custom_code_report.py
  • scripts/castiron/test_custom_code_report.py
  • src/client.ts
  • src/resources/audio/transcriptions.ts
  • src/resources/audio/translations.ts
  • src/resources/beta/assistants.ts
  • src/resources/beta/beta.ts
  • src/resources/beta/index.ts
  • src/resources/beta/responses/internal-base.ts
  • src/resources/beta/responses/responses.ts
  • src/resources/beta/threads/index.ts
  • src/resources/beta/threads/runs/index.ts
  • src/resources/beta/threads/runs/runs.ts
  • src/resources/beta/threads/threads.ts
  • src/resources/chat/completions/completions.ts
  • src/resources/chat/completions/index.ts
  • src/resources/conversations/index.ts
  • src/resources/embeddings.ts
  • src/resources/files.ts
  • src/resources/fine-tuning/checkpoints/permissions.ts
  • src/resources/images.ts
  • src/resources/responses/internal-base.ts
  • src/resources/responses/responses.ts
  • src/resources/skills/skills.ts
  • src/resources/skills/versions/versions.ts
  • src/resources/vector-stores/file-batches.ts
  • src/resources/vector-stores/files.ts
  • src/resources/webhooks/index.ts
  • src/resources/webhooks/webhooks.ts
  • tests/lib/data-residency.test.ts

A changed generated baseline means this report cannot reliably identify which handwritten lines changed.

Inspect the custom-code diff

Download the exact patch produced by this run (requires repository access):

gh run download 33574452304 --repo openai/openai-node \
  --name castiron-custom-code-33574452304-1 --dir /tmp/castiron-custom-code-33574452304-1
git apply --stat /tmp/castiron-custom-code-33574452304-1/custom-code.patch
cat /tmp/castiron-custom-code-33574452304-1/custom-code.patch

Or reproduce it from an SDK checkout containing the vendored reporter:

git fetch --no-tags origin 82c5b2def367f88d9c05c83b23dfb78ac6b9f25c c6cf81556ebb38a20fa011c3ed20849dc3d72bcb
python3 scripts/castiron/custom_code_report.py report \
  --base 82c5b2def367f88d9c05c83b23dfb78ac6b9f25c \
  --head c6cf81556ebb38a20fa011c3ed20849dc3d72bcb --fetch --require-head-hash --public \
  --out /tmp/castiron-custom-code-c6cf81556ebb
cat /tmp/castiron-custom-code-c6cf81556ebb/custom-code.patch

This is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR.

Full report and patch

@sylvesterkaczmarek sylvesterkaczmarek left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the stable and beta URL builders against the routing/precedence boundaries here. Parsing baseURL before appending the endpoint keeps the pathname mutation separate from the query and fragment, so routing parameters are no longer absorbed into the /realtime suffix. Assigning through URL.pathname also preserves the encoded path cases covered by the regression matrix.

The later searchParams.set(...) calls still give explicit session parameters (model, call_id, intent) precedence over same-named values from the base URL while leaving unrelated and repeated routing parameters intact. The Azure path remains intentionally separate: it normalizes /v1, clears the inherited search, and then applies its GA parameters. Clearing hash for both paths is also correct before opening the WebSocket.

The browser/Node and stable/beta constructor coverage exercises the public call paths rather than only the helper. I don't see a blocking URL-construction regression in the current head.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the exact head. The pathname-based construction preserves routing queries, repeated values, encoded path segments, and explicit session-parameter precedence while stripping fragments; Azure and custom callback behavior remain intact. Focused Realtime tests passed locally (178), root typechecking passed, and CI is green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants