Skip to content

Reuse Codex OAuth for OpenAI Realtime voice#100671

Merged
steipete merged 1 commit into
mainfrom
fix/openai-realtime-codex-oauth
Jul 6, 2026
Merged

Reuse Codex OAuth for OpenAI Realtime voice#100671
steipete merged 1 commit into
mainfrom
fix/openai-realtime-codex-oauth

Conversation

@steipete

@steipete steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • allow OpenAI Realtime voice to fall back to an existing openai OAuth profile or external Codex login
  • keep configured keys, API-key profiles, and OPENAI_API_KEY ahead of OAuth, including fail-closed behavior for unresolved keys
  • carry runtime auth ordering into Discord realtime bridges and update Realtime/Talk documentation

Verification

  • live WebRTC: Codex OAuth minted an ephemeral client secret; HTTP 201; answer SDP applied; audio negotiated; data channel opened; peer connected
  • live native bridge: OpenClaw reached session.created and session.updated over the Realtime WebSocket with Codex OAuth
  • pnpm exec vitest run extensions/openai/realtime-voice-provider.test.ts --reporter=dot (63 passed)
  • node scripts/run-vitest.mjs run --config test/vitest/vitest.e2e.config.ts extensions/discord/src/voice/manager.e2e.test.ts -t "uses agent-proxy realtime voice by default" --reporter=dot (1 passed)
  • pnpm exec tsc --noEmit --project extensions/openai/tsconfig.json
  • pnpm exec oxfmt --check ... on all changed files
  • structured autoreview: clean

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord extensions: openai size: M maintainer Maintainer-authored PR labels Jul 6, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 312de7de40

ℹ️ 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".

provider: "openai",
cfg: params.cfg,
profileTypes: ["oauth"],
includeExternalCliAuth: true,

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.

P2 Badge Honor pinned Codex OAuth profile ids

When a user has the legacy Codex profile pinned in auth.order.openai (for example openai:codex-cli), this lookup only scopes external CLI discovery by provider. The Codex overlay is therefore created as openai:default, while resolveAuthProfileOrder treats a configured order as a hard constraint, so the overlaid profile is filtered out and Realtime still reports missing auth despite a valid Codex login. This is the same config shape the Discord bridge test now threads through; pass the ordered profile id/preferred profile into discovery or normalize the legacy Codex id before resolving OAuth.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 6, 2026, 2:58 AM ET / 06:58 UTC.

Summary
The PR expands OpenAI Realtime voice auth to use API-key sources first and then fall back to OpenAI/Codex OAuth, threads runtime config into the Discord realtime bridge, and updates Realtime/Talk documentation and tests.

PR surface: Source +26, Tests +92, Docs +2. Total +120 across 7 files.

Reproducibility: yes. source inspection gives a high-confidence reproduction path: configure auth.order.openai with openai:codex-cli, have only an external Codex OAuth login available, then start OpenAI Realtime voice so provider-scoped discovery creates openai:default and auth-order filtering removes it.

Review metrics: 1 noteworthy metric.

  • Realtime auth fallback surfaces: 2 expanded paths. Both browser client-secret minting and native WebSocket bridge auth now depend on the same OAuth fallback and must preserve configured profile order.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦞 diamond lobster
Patch quality: 🦪 silver shellfish
Result: blocked by patch quality or review findings.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Fix pinned openai:codex-cli profile-order fallback and add a regression test that uses the real provider-auth/external-cli ordering path.
  • [P2] Make the maintainer-visible Realtime OAuth contract explicit before merge if automatic OAuth fallback is the intended product behavior.

Risk before merge

  • [P1] Merging as-is can leave users with auth.order.openai: ["openai:codex-cli"] unable to use an otherwise valid Codex OAuth login for Realtime voice, because the runtime overlay is created as openai:default and then filtered by the configured order.
  • [P2] The PR intentionally expands OpenAI Realtime credential selection from API-key-only sources to OAuth fallback, so maintainers should treat auth precedence, billing expectations, and upgrade behavior as compatibility-sensitive before merge.

Maintainer options:

  1. Fix pinned-profile compatibility first (recommended)
    Pass the configured or preferred Codex OAuth profile id through external CLI discovery, or normalize openai:codex-cli, and add regression coverage before merge.
  2. Accept the auth-order limitation
    Maintainers could intentionally accept that only default Codex overlays work, but that would make a documented/orderable legacy profile shape fail at runtime.
  3. Pause for Realtime auth contract decision
    If OAuth-backed Realtime should not be automatic, pause or close the PR until the desired product contract is decided.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Preserve ordered legacy Codex OAuth profile ids in OpenAI Realtime OAuth fallback by threading the preferred profile id into external CLI discovery or normalizing `openai:codex-cli`, then add a regression test that exercises provider-auth/external-cli resolution with `auth.order.openai: ["openai:codex-cli"]`.

Next step before merge

  • [P2] Maintainer review is needed because the PR changes the Realtime auth contract and still needs a narrow pinned-profile fix before it can be considered merge-ready.

Maintainer decision needed

  • Question: Should OpenAI Realtime voice officially accept Codex/OpenAI OAuth fallback after API-key sources, once pinned legacy profile ids are preserved?
  • Rationale: The PR changes a previously documented API-key-only Realtime path into an OAuth fallback path, which affects provider auth precedence and user billing expectations; the line-level bug is fixable, but the permanent product contract should be explicit.
  • Likely owner: joshavant — The current API-key-only Realtime behavior appears to come from their merged auth change, so they are the clearest owner for whether this contract should change.
  • Options:
    • Accept OAuth fallback after compatibility fix (recommended): Keep the PR direction, require the pinned-profile repair and regression coverage, then merge after normal CI/proof review.
    • Keep Realtime API-key-only: Close or rewrite the PR to preserve the current documented Platform API-key contract and direct OAuth users to a separate product discussion.
    • Make OAuth opt-in: Add an explicit setting or setup path for OAuth-backed Realtime instead of automatic fallback, trading compatibility for extra configuration surface.

Security
Cleared: The diff expands auth routing but does not add dependencies, workflows, package scripts, token exposure, or a concrete supply-chain/security-boundary regression; the remaining concerns are functional auth compatibility risks.

Review findings

  • [P2] Honor pinned Codex OAuth profiles — extensions/openai/realtime-voice-provider.ts:414-418
Review details

Best possible solution:

Land the OAuth fallback only after the provider-auth path preserves pinned legacy Codex profile ids and the tests prove both default Codex OAuth and ordered openai:codex-cli upgrade behavior.

Do we have a high-confidence way to reproduce the issue?

Yes, source inspection gives a high-confidence reproduction path: configure auth.order.openai with openai:codex-cli, have only an external Codex OAuth login available, then start OpenAI Realtime voice so provider-scoped discovery creates openai:default and auth-order filtering removes it.

Is this the best way to solve the issue?

No, not yet: reusing Codex OAuth is a maintainable direction only if the provider-auth fallback preserves the user's configured profile id or normalizes the legacy Codex id before order filtering.

Full review comments:

  • [P2] Honor pinned Codex OAuth profiles — extensions/openai/realtime-voice-provider.ts:414-418
    This OAuth fallback only asks external CLI discovery for the openai provider, so Codex is overlaid as openai:default. With auth.order.openai: ["openai:codex-cli"], resolveAuthProfileOrder treats that configured order as a hard filter and drops the overlaid profile, leaving Realtime to report missing auth despite a valid Codex login. Please pass the ordered/preferred profile id into discovery or normalize the legacy Codex id before resolving OAuth, and cover that real provider-auth path in a regression test.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 9dfd9324f2ec.

Label changes

Label changes:

  • add P1: The PR touches user-facing OpenAI Realtime/Talk and Discord voice auth, and the remaining bug can still block a valid Codex OAuth setup at first use.
  • add merge-risk: 🚨 compatibility: The patch changes an existing Realtime API-key-only contract into automatic OAuth fallback and must preserve upgrade behavior for ordered legacy profiles.
  • add merge-risk: 🚨 auth-provider: The changed code controls credential source precedence and external Codex OAuth profile routing for OpenAI Realtime sessions.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live WebRTC and native Realtime bridge output showing Codex OAuth minting a client secret, connecting audio/data channel paths, and receiving Realtime session events.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦞 diamond lobster and patch quality is 🦪 silver shellfish.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body includes after-fix live WebRTC and native Realtime bridge output showing Codex OAuth minting a client secret, connecting audio/data channel paths, and receiving Realtime session events.

Label justifications:

  • P1: The PR touches user-facing OpenAI Realtime/Talk and Discord voice auth, and the remaining bug can still block a valid Codex OAuth setup at first use.
  • merge-risk: 🚨 compatibility: The patch changes an existing Realtime API-key-only contract into automatic OAuth fallback and must preserve upgrade behavior for ordered legacy profiles.
  • merge-risk: 🚨 auth-provider: The changed code controls credential source precedence and external Codex OAuth profile routing for OpenAI Realtime sessions.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦞 diamond lobster and patch quality is 🦪 silver shellfish.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body includes after-fix live WebRTC and native Realtime bridge output showing Codex OAuth minting a client secret, connecting audio/data channel paths, and receiving Realtime session events.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live WebRTC and native Realtime bridge output showing Codex OAuth minting a client secret, connecting audio/data channel paths, and receiving Realtime session events.
Evidence reviewed

PR surface:

Source +26, Tests +92, Docs +2. Total +120 across 7 files.

View PR surface stats
Area Files Added Removed Net
Source 2 41 15 +26
Tests 2 135 43 +92
Docs 3 32 30 +2
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 7 208 88 +120

Acceptance criteria:

  • [P1] Inspect auth.order.openai: ["openai:codex-cli"] with only external Codex OAuth available and confirm OpenAI Realtime resolves that OAuth token.
  • [P2] Run focused OpenAI realtime voice provider tests covering API-key precedence, default Codex OAuth fallback, and pinned legacy Codex OAuth fallback.
  • [P1] Run the Discord realtime bridge test that proves cfg/auth order reaches the provider bridge.

What I checked:

  • PR OAuth fallback call lacks preferred profile scope: The new OAuth fallback asks provider auth for openai OAuth profiles with includeExternalCliAuth: true, but it does not pass an ordered or preferred profile id, so external Codex discovery is only provider-scoped at the changed call site. (extensions/openai/realtime-voice-provider.ts:414, a36b45581e3c)
  • Provider auth discovery does not forward profile ids: Current main's provider-auth helper calls externalCliDiscoveryForProviderAuth with provider, cfg, and prompt settings only; it then applies auth-order filtering afterwards, so a configured order can exclude any differently named runtime overlay. (src/plugin-sdk/provider-auth.ts:194, 9dfd9324f2ec)
  • Codex external CLI can honor requested legacy ids if scoped: The external CLI sync layer knows the default Codex profile id is openai:default, the legacy id is openai:codex-cli, and listScopedExternalCliProfileIds returns matching requested ids when supplied, which is the path this PR currently does not use. (src/agents/auth-profiles/external-cli-sync.ts:119, 9dfd9324f2ec)
  • Configured auth order is a hard filter: resolveAuthProfileOrder prefers explicit configured provider order and only has a narrow stored-order drift fallback, so auth.order.openai: ["openai:codex-cli"] will not automatically accept a provider-scoped openai:default overlay. (src/agents/auth-profiles/order.ts:54, 9dfd9324f2ec)
  • Discord path now carries cfg into the bridge: The PR correctly passes this.params.cfg from Discord realtime voice sessions into createRealtimeVoiceBridgeSession, which makes auth ordering visible to the OpenAI bridge and is why the pinned-order case matters for the changed path. (extensions/discord/src/voice/realtime.ts:500, a36b45581e3c)
  • Codex OAuth source contract inspected: Sibling Codex source shows ChatGPT/Codex auth stores OAuth tokens and CodexAuth::get_token() returns an access token for ChatGPT token modes, matching OpenClaw's external CLI credential import path for openai OAuth. (../codex/codex-rs/login/src/auth/manager.rs:58, d1749cfccd6f)

Likely related people:

  • joshavant: Auth and docs history for OpenAI realtime voice points to the merged API-key requirement change that this PR is now revisiting. (role: introduced current realtime auth behavior; confidence: high; commits: 9fdd56da2106; files: extensions/openai/realtime-voice-provider.ts, extensions/openai/realtime-voice-provider.test.ts, docs/providers/openai.md)
  • vincentkoc: Recent history shows work across OpenAI realtime provider behavior, external auth profiles, and Discord realtime voice paths that intersect this PR's changed surfaces. (role: recent auth and realtime area contributor; confidence: high; commits: 8ec5e06c7e82, bc7c2baa7625, 305a4438d44e; files: extensions/openai/realtime-voice-provider.ts, src/plugin-sdk/provider-auth.ts, src/agents/auth-profiles/external-cli-sync.ts)
  • steipete: Prior merged OpenAI provider identity/refactor work touches the provider naming and OpenAI/Codex consolidation area, beyond this PR's authorship. (role: adjacent provider identity contributor; confidence: medium; commits: 4c33aaa6e04b, d92b3b5959f0; files: extensions/openai/realtime-voice-provider.ts, docs/providers/openai.md)
  • 100yenadmin: Git history shows external CLI auth hardening near the credential discovery path used by this PR's OAuth fallback. (role: adjacent external CLI auth contributor; confidence: medium; commits: 46598a120fcd; files: src/agents/auth-profiles/external-cli-sync.ts, src/agents/cli-credentials.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@steipete
steipete force-pushed the fix/openai-realtime-codex-oauth branch from 312de7d to a36b455 Compare July 6, 2026 06:51
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 6, 2026
@steipete
steipete force-pushed the fix/openai-realtime-codex-oauth branch from a36b455 to e6d56b1 Compare July 6, 2026 07:07
@steipete
steipete force-pushed the fix/openai-realtime-codex-oauth branch from e6d56b1 to 3f4771f Compare July 6, 2026 07:08
@steipete
steipete merged commit d7d19a3 into main Jul 6, 2026
37 checks passed
@steipete
steipete deleted the fix/openai-realtime-codex-oauth branch July 6, 2026 07:08

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3f4771fb63

ℹ️ 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".

cfg: this.config.cfg,
});
return this.resolveApiKeyConnectionParams(apiKey, model);
return this.resolveApiKeyConnectionParams(authToken, model);

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.

P2 Badge Mint a realtime client secret for OAuth WebSocket auth

When the selected credential is an openai OAuth/Codex profile, requireOpenAIRealtimePlatformAuthToken can return the raw OAuth access token, but this line still opens the native backend WebSocket as if that token were a standard Platform API key. OpenAI's Realtime WebSocket guide documents server-to-server WebSocket auth with an API key, while this repo's transcription OAuth path first mints a Realtime client secret before using OAuth (extensions/openai/realtime-transcription-provider.ts:146-158). As a result, Voice Call, Discord voice, Google Meet, and gateway-relay sessions that rely only on Codex OAuth will advertise as configured but fail the backend WebSocket auth; mint and use a Realtime client secret for the OAuth branch instead of passing the OAuth token directly here.

Useful? React with 👍 / 👎.

vincentkoc added a commit to zhangqueping/openclaw that referenced this pull request Jul 6, 2026
* origin/main:
  fix(ci): restore gateway architecture and lint gates (openclaw#100703)
  fix(openai): reuse Codex auth for realtime voice (openclaw#100671)
  perf(test): avoid provider runtime in auth doctor unit test
  docs(android): credit landed app improvements (openclaw#100702)
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 6, 2026
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord docs Improvements or additions to documentation extensions: openai maintainer Maintainer-authored PR merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: M status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants