mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
75a08def9808ed5b77b458d09c2fe99f2b52c433
99 Commits
-
[codex] Require model for standalone web search (#25131)
## Why The standalone `/v1/alpha/search` request now requires a `model`, but the `web.run` extension currently omits it. Adds `model` to extension `ToolCall` invocation. Follow-up to #23823. ## What changed - Make `SearchRequest.model` required. - Expose the effective per-turn model on extension tool calls and pass it in standalone web-search requests. - Assert the model is forwarded in the app-server round-trip test. ## Testing - `just test -p codex-api -p codex-tools -p codex-web-search-extension -p codex-memories-extension -p codex-goal-extension` - `just test -p codex-core -E 'test(passes_turn_fields_and_scoped_turn_item_emitter_to_extension_call)'` - `just test -p codex-app-server -E 'test(standalone_web_search_round_trips_encrypted_output)'`
sayan-oai ·
2026-05-29 12:03:04 -07:00 -
Add typed Images client to codex-api (#23989)
## Why Standalone image generation needs a typed `codex-api` client surface for the Codex image proxy routes before the harness and model-facing tool layers are wired in. ## What changed - Added `ImagesClient` support for JSON `images/generations` and `images/edits` requests. - Added typed request and response shapes for generation, JSON edit image URLs, image metadata, and base64 image outputs. - Kept generation model slugs open-ended while requiring the generation model field that the downstream endpoint expects. - Exported the new client and image types from `codex-api`. - Added coverage for generation and edit wire shapes, extra response metadata that the client ignores, and malformed image responses missing `data`. ## Validation - `cargo test -p codex-api` - `just fix -p codex-api` - `just fmt` - `git diff --check main`
Won Park ·
2026-05-22 14:10:55 -07:00 -
[codex] Fix realtime v1 websocket compatibility (#23771)
## Why Realtime v1 websocket sessions now expect a slightly different boundary shape for text input, completed input transcripts, and connection headers. Codex was still using the older shape, so some v1 text appends could be rejected before the existing conversation flow could handle them. ## What changed - Send v1 user text items with `input_text` content - Accept v1 turn-marked input transcript events as completed transcripts - Add the v1 alpha header only for v1 realtime sessions - Cover the outbound text shape, transcript parsing, and versioned headers ## Test plan - `cargo test -p codex-api endpoint::realtime_websocket::methods::tests` - `cargo test -p codex-core quicksilver_alpha_header`
guinness-oai ·
2026-05-20 16:03:51 -07:00 -
add standalone websearch api client (#23655)
add standalone web search request types and a `codex-api` client ahead of the extension-contributed search tool. this adds typed commands/settings and opaque encrypted output handling for the new standalone search flow. the endpoint types are close to finalized but may still shift slightly as that API settles.
sayan-oai ·
2026-05-20 11:38:21 -07:00 -
Add timeout for remote compaction requests (#23451)
## Why Remote compaction currently sends a unary `POST /responses/compact` and waits for the full response before replacing history or emitting the completed `ContextCompaction` item. Unlike normal `/responses` streaming requests, this unary compact request had no timeout boundary. If the backend accepts the request and then stalls before returning a body, the existing request retry policy never sees a transport error, so the compact turn can remain stuck after the started item with no completion or actionable error. That matches the reported hang shape in issues such as #18363, where logs show `responses/compact` was posted but no corresponding compact completion followed. A bounded request timeout gives the existing retry policy a concrete timeout error to retry instead of letting the user sit indefinitely on automatic context compaction. ## What - Add a request timeout to legacy `/responses/compact` calls. - Size that timeout from the provider stream idle timeout with a conservative multiplier, so the default compact attempt gets 20 minutes rather than the 5 minute stream idle window. - Map API transport timeouts to a request timeout error instead of the child-process timeout message. ## Testing - Not run (per request; CI will cover).
jif-oai ·
2026-05-20 11:56:00 +02:00 -
feat(cli): add codex doctor diagnostics (#22336)
## Why Users and support need a single command that captures the local Codex runtime, configuration, auth, terminal, network, and state shape without asking the user to know which diagnostic depth to choose first. `codex doctor` now runs the useful checks by default and makes the detailed human output the default because the command is usually run when someone already needs context. The command also targets concrete support failure modes we have seen while iterating on the design: - update-target mismatches like #21956, where the installed package manager target can differ from the running executable - terminal and multiplexer issues that depend on `TERM`, tmux/zellij state, color handling, and TTY metadata - provider-specific HTTP/WebSocket connectivity, including ChatGPT WebSocket handshakes and API-key/provider endpoint reachability - local state/log SQLite integrity problems and large rollout directories - feedback reports that need an attached, redacted diagnostic snapshot without asking the user to run a second command ## What Changed - Adds `codex doctor` as a grouped CLI diagnostic report with default detailed output and `--summary` for the compact view. - Adds stable report sections for Environment, Configuration, Updates, Connectivity, and Background Server, plus a top Notes block that promotes anomalies such as available updates, large rollout directories, optional MCP issues, and mixed auth signals. - Adds runtime provenance, install consistency, bundled/system search readiness, terminal/multiplexer metadata, `config.toml` parse status, auth mode details, sandbox details, feature flag summaries, update cache/latest-version state, app-server daemon state, SQLite integrity checks, rollout statistics, and provider-aware network diagnostics. - Adds ChatGPT WebSocket diagnostics that report the negotiated HTTP upgrade as `HTTP 101 Switching Protocols` and include timeout, DNS, auth, and provider context in detailed output. - Makes reachability provider-aware: API-key OpenAI setups check the API endpoint, ChatGPT auth checks the ChatGPT path, and custom/AWS/local providers check configured HTTP endpoints when available. - Adds structured, redacted JSON output where `checks` is keyed by check id and `details` is a key/value object for support tooling. - Integrates doctor with feedback uploads by attaching a best-effort `codex-doctor-report.json` report and adding derived Sentry tags for overall status and failing/warning checks. - Updates the TUI feedback consent copy so users can see that the doctor report is included when logs/diagnostics are uploaded. - Updates the CLI bug issue template to ask reporters for `codex doctor --json` and render pasted reports as JSON. ## Example Output The examples below are sanitized from local smoke runs with `--no-color` so the structure is reviewable in plain text. ### `codex doctor` ```text Codex Doctor v0.0.0 · macos-aarch64 Notes ↑ updates 0.130.0 available (current 0.0.0, dismissed 0.128.0) ⚠ rollouts 1,526 active files · 2.53 GB on disk ⚠ mcp MCP configuration has optional issues ⚠ auth mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode ───────────────────────────────────────────────────────────── Environment ✓ runtime local debug build version 0.0.0 install method other commit unknown executable ~/code/codex.fcoury-doct…x-rs/target/debug/codex ✓ install consistent context other managed by npm: no · bun: no · package root — PATH entries (2) ~/.local/share/mise/installs/node/24/bin/codex ~/.local/share/mise/shims/codex ✓ search ripgrep 15.1.0 (system, `rg`) ✓ terminal Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color terminal Ghostty TERM_PROGRAM ghostty terminal version 1.3.2-main-+b0f827665 TERM xterm-256color multiplexer tmux 3.6a tmux extended-keys on tmux allow-passthrough on tmux set-clipboard on ✓ state databases healthy CODEX_HOME ~/.codex (dir) state DB ~/.codex/state_5.sqlite (file) · integrity ok log DB ~/.codex/logs_2.sqlite (file) · integrity ok active rollouts 1,526 files · 2.53 GB (avg 1.70 MB) archived rollouts 8 files · 3.84 MB (avg 491.11 KB) Configuration ✓ config loaded model gpt-5.5 · openai cwd ~/code/codex.fcoury-doctor/codex-rs config.toml ~/.codex/config.toml config.toml parse ok MCP servers 1 feature flags 36 enabled · 7 overridden (full list with --all) overrides code_mode, code_mode_only, memories, chronicle, goals, remote_control, prevent_idle_sleep ✓ auth auth is configured auth storage mode File auth file ~/.codex/auth.json auth env vars present OPENAI_API_KEY stored auth mode chatgpt stored API key false stored ChatGPT tokens true stored agent identity false ⚠ mcp MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server. configured servers 1 disabled servers 0 streamable_http servers 1 optional reachability openaiDeveloperDocs: https://developers.openai.com/mcp (HEAD connect failed; GET connect failed) ✓ sandbox restricted fs + restricted network · approval OnRequest approval policy OnRequest filesystem sandbox restricted network sandbox restricted Connectivity ✓ network network-related environment looks readable ✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout model provider openai provider name OpenAI wire API responses supports websockets true connect timeout 15000 ms auth mode chatgpt endpoint wss://chatgpt.com/backend-api/<redacted> DNS 2 IPv4, 2 IPv6, first IPv6 handshake result HTTP 101 Switching Protocols ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration. reachability mode API key auth openai API https://api.openai.com/v1 connect failed (required) Background Server ○ app-server not running (ephemeral mode) ───────────────────────────────────────────────────────────── 11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed --summary compact output --all expand truncated lists --json redacted report ``` ### `codex doctor --summary` ```text Codex Doctor v0.0.0 · macos-aarch64 Notes ↑ updates 0.130.0 available (current 0.0.0, dismissed 0.128.0) ⚠ rollouts 1,526 active files · 2.53 GB on disk ⚠ mcp MCP configuration has optional issues ⚠ auth mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode ───────────────────────────────────────────────────────────── Environment ✓ runtime local debug build ✓ install consistent ✓ search ripgrep 15.1.0 (system, `rg`) ✓ terminal Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color ✓ state databases healthy Configuration ✓ config loaded ✓ auth auth is configured ⚠ mcp MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server. ✓ sandbox restricted fs + restricted network · approval OnRequest Updates ✓ updates update configuration is locally consistent Connectivity ✓ network network-related environment looks readable ✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration. Background Server ○ app-server not running (ephemeral mode) ───────────────────────────────────────────────────────────── 11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed Run codex doctor without --summary for detailed diagnostics. --all expand truncated lists --json redacted report ``` ### `codex doctor --json` shape ```json { "schema_version": 1, "overall_status": "fail", "checks": { "runtime.provenance": { "id": "runtime.provenance", "category": "Environment", "status": "ok", "summary": "local debug build", "details": { "version": "0.0.0", "install method": "other", "commit": "unknown" } }, "sandbox.helpers": { "id": "sandbox.helpers", "category": "Configuration", "status": "ok", "summary": "restricted fs + restricted network · approval OnRequest", "details": { "approval policy": "OnRequest", "filesystem sandbox": "restricted", "network sandbox": "restricted" } } } } ``` ### `/feedback` new sentry attachment <img width="938" height="798" alt="CleanShot 2026-05-13 at 15 36 14" src="https://github.com/user-attachments/assets/715e62e0-d7b4-4fea-a35a-fd5d5d33c4c0" /> ### New section in CLI issue template <img width="1164" height="435" alt="CleanShot 2026-05-13 at 15 47 24" src="https://github.com/user-attachments/assets/9081dc25-a28c-4afa-8ba1-e299c2b4031d" /> ## How to Test 1. Run `cargo run --bin codex -- doctor --no-color`. 2. Confirm the detailed report is the default and includes promoted Notes, grouped sections, terminal details, state DB integrity, rollout stats, provider reachability, WebSocket diagnostics, and app-server status. 3. Run `cargo run --bin codex -- doctor --summary --no-color`. 4. Confirm the compact view keeps the same sections and summary counts but omits detailed key/value rows. 5. Run `cargo run --bin codex -- doctor --json`. 6. Confirm the output is redacted JSON, `checks` is an object keyed by check id, and each check's `details` is a key/value object. 7. Preview the CLI bug issue template and confirm the `Codex doctor report` field appears after the terminal field, asks for `codex doctor --json`, and renders pasted output as JSON. 8. Start a feedback flow that includes logs. 9. Confirm the upload consent copy lists `codex-doctor-report.json` alongside the log attachments. Targeted tests: - `cargo test -p codex-cli doctor` - `cargo test -p codex-app-server doctor_report_tags_summarize_status_counts` - `cargo test -p codex-feedback` - `cargo test -p codex-tui feedback_view` - `just argument-comment-lint` - `git diff --check`
Felipe Coury ·
2026-05-13 21:23:19 +00:00 -
[codex] Add response.processed websocket request (#21284)
## Summary - Add a `response.processed` websocket request payload and sender for Responses API websockets. - Send `response.processed` from `try_run_sampling_request` after a response completes, local turn processing succeeds, and the session-owned feature flag is enabled. - Add websocket coverage for both enabled and disabled feature-flag behavior. ## Validation - `just fmt` - `cargo test -p codex-core response_processed` - `cargo test -p codex-api responses_websocket` - `cargo test -p codex-features responses_websocket_response_processed_is_under_development` - `git diff --check` - `just fix -p codex-api -p codex-core -p codex-features` - `git diff --check origin/main...HEAD`
pakrym-oai ·
2026-05-06 09:58:46 -07:00 -
feat: add
session_id(#20437)## Summary Related to https://openai.slack.com/archives/C095U48JNL9/p1777537279707449 TLDR: We update the meaning of session ids and thread ids: * thread_id stays as now * session_id become a shared id between every thread under a /root thread (i.e. every sub-agent share the same session id) This PR introduces an explicit `SessionId` and threads it through the protocol/client boundary so `session_id` and `thread_id` can diverge when they need to, while preserving compatibility for older serialized `session_configured` events. --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-06 10:48:37 +02:00 -
Bound websocket request sends with idle timeout (#20751)
## Why We saw Responses websocket sessions recover only after a long quiet period when the server had already logged the websocket as disconnected. The normal connect path is already bounded by `websocket_connect_timeout_ms`, but the first request send on an established websocket reused only the receive-side idle timeout after the write completed. If the socket write/pump stalls, the client can sit in `ws_stream.send(...)` without reaching the existing receive timeout.
pakrym-oai ·
2026-05-01 23:33:32 -07:00 -
realtime: rename provider session ids (#20361)
## Summary Codex is repurposing `session` to mean a thread group, so the realtime provider session id should no longer use `session_id` / `sessionId` in Codex-facing protocol payloads. This PR renames that provider-specific field to `realtime_session_id` / `realtimeSessionId` and intentionally breaks clients that still send the old field names. ## What Changed - Renamed realtime provider session fields in `ConversationStartParams`, `RealtimeConversationStartedEvent`, and `RealtimeEvent::SessionUpdated`. - Renamed app-server v2 realtime request and notification fields to `realtimeSessionId`. - Removed legacy serde aliases for `session_id` / `sessionId`; clients must send the new names. - Propagated the rename through core realtime startup, app-server adapters, codex-api websocket handling, and TUI realtime state. - Regenerated app-server protocol schema/TypeScript outputs and updated app-server README examples. - Kept upstream Realtime API concepts unchanged: provider `session.id` parsing and `x-session-id` headers still use the upstream wire names. ## Testing - CI is running on the latest pushed commit. - Earlier local verification on this PR: - `cargo test -p codex-protocol` - `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-core realtime_conversation` - `cargo test -p codex-app-server-protocol` - `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-app-server realtime_conversation` - attempted `CODEX_SKIP_VENDORED_BWRAP=1 cargo test -p codex-tui` (local linker bus error while linking the test binary) --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-30 13:39:48 +03:00 -
[rollout-trace] Include x-request-id in rollout trace. (#20066)
## Why Rollout traces need an identifier that can be used to correlate a Codex inference with upstream Responses API, proxy, and engine logs. The reduced trace model already exposed `upstream_request_id`, but it was being populated from the Responses API `response.id`. That value is useful for `previous_response_id` chaining, but it is not the transport request id that upstream systems key on. This PR separates those concepts so trace consumers can reliably answer both questions: - which Responses API response did this inference produce? - which upstream request handled it? ## Structure The change keeps the upstream request id at the same lifecycle level as the provider stream: - `codex-api` captures the `x-request-id` HTTP response header when the SSE stream is created and exposes it on `ResponseStream`. Fixture and websocket streams set the field to `None` because they do not have that HTTP response header. - `codex-core` carries that stream-level id into `InferenceTraceAttempt` when recording terminal stream outcomes. Completed, failed, cancelled, dropped-stream, and pre-response error paths all record the id when it is available. - `rollout-trace` now records both identifiers in raw terminal inference events and response payloads: `response_id` for the Responses API `response.id`, and `upstream_request_id` for `x-request-id`. - The reducer stores both fields on `InferenceCall`. It also uses `response_id` for `previous_response_id` conversation linking, which removes the old accidental dependency on the misnamed `upstream_request_id` field. - Terminal inference reduction now consumes the full terminal payload (`InferenceCompleted`, `InferenceFailed`, or `InferenceCancelled`) in one place. That keeps status, partial payloads, response ids, and upstream request ids consistent across success, failure, cancellation, and late stream-mapper events. ## Why This Shape `x-request-id` is a property of the HTTP/provider response envelope, not an SSE event. Capturing it once in `codex-api` and plumbing it through terminal trace recording avoids trying to infer the value from stream contents, and it preserves the id even when the stream fails or is cancelled after only partial output. Keeping `response_id` separate from `upstream_request_id` also makes the reduced trace model less surprising: `response_id` remains the conversation-continuation id, while `upstream_request_id` is the operational correlation id for upstream debugging. ## Validation The PR updates trace and reducer coverage for: - reading `x-request-id` from SSE response headers; - storing the true upstream request id on completed inference calls; - preserving upstream request ids for cancelled and late-cancelled inference streams; - keeping `previous_response_id` reconstruction tied to `response_id` rather than transport request ids.
cassirer-openai ·
2026-04-28 21:11:17 +00:00 -
Add safety check notification and error handling (#19055)
Adds a new app-server notification that fires when a user account has been flagged for potential safety reasons.
Eric Traut ·
2026-04-22 22:24:12 -07:00 -
feat: add AWS SigV4 auth for OpenAI-compatible model providers (#17820)
## Summary Add first-class Amazon Bedrock Mantle provider support so Codex can keep using its existing Responses API transport with OpenAI-compatible AWS-hosted endpoints such as AOA/Mantle. This is needed for the AWS launch path, where provider traffic should authenticate with AWS credentials instead of OpenAI bearer credentials. Requests are authenticated immediately before transport send, so SigV4 signs the final method, URL, headers, and body bytes that `reqwest` will send. ## What Changed - Added a new `codex-aws-auth` crate for loading AWS SDK config, resolving credentials, and signing finalized HTTP requests with AWS SigV4. - Added a built-in `amazon-bedrock` provider that targets Bedrock Mantle Responses endpoints, defaults to `us-east-1`, supports region/profile overrides, disables WebSockets, and does not require OpenAI auth. - Added Amazon Bedrock auth resolution in `codex-model-provider`: prefer `AWS_BEARER_TOKEN_BEDROCK` when set, otherwise use AWS SDK credentials and SigV4 signing. - Added `AuthProvider::apply_auth` and `Request::prepare_body_for_send` so request-signing providers can sign the exact outbound request after JSON serialization/compression. - Determine the region by taking the `aws.region` config first (required for bearer token codepath), and fallback to SDK default region. ## Testing Amazon Bedrock Mantle Responses paths: - Built the local Codex binary with `cargo build`. - Verified the custom proxy-backed `aws` provider using `env_key = "AWS_BEARER_TOKEN_BEDROCK"` streamed raw `responses` output with `response.output_text.delta`, `response.completed`, and `mantle-env-ok`. - Verified a full `codex exec --profile aws` turn returned `mantle-env-ok`. - Confirmed the custom provider used the bearer env var, not AWS profile auth: bogus `AWS_PROFILE` still passed, empty env var failed locally, and malformed env var reached Mantle and failed with `401 invalid_api_key`. - Verified built-in `amazon-bedrock` with `AWS_BEARER_TOKEN_BEDROCK` set passed despite bogus AWS profiles, returning `amazon-bedrock-env-ok`. - Verified built-in `amazon-bedrock` SDK/SigV4 auth passed with `AWS_BEARER_TOKEN_BEDROCK` unset and temporary AWS session env credentials, returning `amazon-bedrock-sdk-env-ok`.
Celia Chen ·
2026-04-22 01:11:17 +00:00 -
chore: document intentional await-holding cases (#18423)
## Why This PR prepares the stack to enable Clippy await-holding lints that were left disabled in #18178. The mechanical lock-scope cleanup is handled separately; this PR is the documentation/configuration layer for the remaining await-across-guard sites. Without explicit annotations, reviewers and future maintainers cannot tell whether an await-holding warning is a real concurrency smell or an intentional serialization boundary. ## What changed - Configures `clippy.toml` so `await_holding_invalid_type` also covers `tokio::sync::{MutexGuard,RwLockReadGuard,RwLockWriteGuard}`. - Adds targeted `#[expect(clippy::await_holding_invalid_type, reason = ...)]` annotations for intentional async guard lifetimes. - Documents the main categories of intentional cases: active-turn state transitions that must remain atomic, session-owned MCP manager accesses, remote-control websocket serialization, JS REPL kernel/process serialization, OAuth persistence, external bearer token refresh serialization, and tests that intentionally serialize shared global or session-owned state. - For external bearer token refresh, documents the existing serialization boundary: holding `cached_token` across the provider command prevents concurrent cache misses from starting duplicate refresh commands, and the current behavior is small enough that an explicit expectation is easier to maintain than adding another synchronization primitive. ## Verification - `cargo clippy -p codex-login --all-targets` - `cargo clippy -p codex-connectors --all-targets` - `cargo clippy -p codex-core --all-targets` - The follow-up PR #18698 enables `await_holding_invalid_type` and `await_holding_lock` as workspace `deny` lints, so any undocumented remaining offender will fail Clippy. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18423). * #18698 * __->__ #18423
Michael Bolin ·
2026-04-20 22:41:54 -07:00 -
[codex] Send realtime transcript deltas on handoff (#18761)
## Summary - Track how many realtime transcript entries have already been attached to a background-agent handoff. - Attach only entries added since the previous handoff as `<transcript_delta>` instead of resending the accumulated transcript snapshot. - Update the realtime integration test so the second delegation carries only the second transcript delta. ## Validation - `just fmt` - `cargo test -p codex-api` - `cargo test -p codex-core inbound_handoff_request_sends_transcript_delta_after_each_handoff` - `cargo build -p codex-cli -p codex-app-server` ## Manual testing Built local debug binaries at: - `codex-rs/target/debug/codex` - `codex-rs/target/debug/codex-app-server`
guinness-oai ·
2026-04-20 16:46:15 -07:00 -
Add realtime silence tool (#18635)
## Summary Adds a second realtime v2 function tool, `remain_silent`, so the realtime model has an explicit non-speaking action when the collaboration mode or latest context says it should not answer aloud. This is stacked on #18597. ## Design - Advertise `remain_silent` alongside `background_agent` in realtime v2 conversational sessions. - Parse `remain_silent` function calls into a typed `RealtimeEvent::NoopRequested` event. - Have core answer that function call with an empty `function_call_output` and deliberately avoid `response.create`, so no follow-up realtime response is requested. - Keep the event hidden from app-server/TUI surfaces; it is operational plumbing, not user-visible conversation content.
guinness-oai ·
2026-04-20 15:43:20 -07:00 -
Update realtime handoff transcript handling (#18597)
## Summary This PR aims to improve integration between the realtime model and the codex agent by sharing more context with each other. In particular, we now share full realtime conversation transcript deltas in addition to the delegation message. realtime_conversation.rs now turns a handoff into: ``` <realtime_delegation> <input>...</input> <transcript_delta>...</transcript_delta> </realtime_delegation> ``` ## Implementation notes The transcript is accumulated in the realtime websocket layer as parsed realtime events arrive. When a background-agent handoff is requested, the current transcript snapshot is copied onto the handoff event and then serialized by `realtime_conversation.rs` into the hidden realtime delegation envelope that Codex receives as user-turn context. For Realtime V2, the session now explicitly enables input audio transcription, and the parser handles the relevant input/output transcript completion events so the snapshot includes both user speech and realtime model responses. The delegation `<input>` remains the actual handoff request, while `<transcript_delta>` carries the surrounding conversation history for context. Reviewers should note that the transcript payload is intended for Codex context sharing, not UI rendering. The realtime delegation envelope should stay hidden from the user-facing transcript surface, while still being included in the background-agent turn so Codex can answer with the same conversational context the realtime model had.
guinness-oai ·
2026-04-20 14:04:09 -07:00 -
refactor: use cloneable async channels for shared receivers (#18398)
This is the first mechanical cleanup in a stack whose higher-level goal is to enable Clippy coverage for async guards held across `.await` points. The follow-up commits enable Clippy's [`await_holding_lock`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock) lint and the configurable [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type) lint for Tokio guard types. This PR handles the cases where the underlying issue is not protected shared mutable state, but a `tokio::sync::mpsc::UnboundedReceiver` wrapped in `Arc<Mutex<_>>` so cloned owners can call `recv().await`. Using a mutex for that shape forces the receiver lock guard to live across `.await`. Switching these paths to `async-channel` gives us cloneable `Receiver`s, so each owner can hold a receiver handle directly and await messages without an async mutex guard. ## What changed - In `codex-rs/code-mode`, replace the turn-message `mpsc::UnboundedSender`/`UnboundedReceiver` plus `Arc<Mutex<Receiver>>` with `async_channel::Sender`/`Receiver`. - In `codex-rs/codex-api`, replace the realtime websocket event receiver with an `async_channel::Receiver`, allowing `RealtimeWebsocketEvents` clones to receive without locking. - Add `async-channel` as a dependency for `codex-code-mode` and `codex-api`, and update `Cargo.lock`. ## Verification - The split stack was verified at the final lint-enabling head with `just clippy`.
Michael Bolin ·
2026-04-17 15:20:30 -07:00 -
feat: add opt-in provider runtime abstraction (#17713)
## Summary - Add `codex-model-provider` as the runtime home for model-provider behavior that does not belong in `codex-core`, `codex-login`, or `codex-api`. - The new crate wraps configured `ModelProviderInfo` in a `ModelProvider` trait object that can resolve the API provider config, provider-scoped auth manager, and request auth provider for each call. - This centralizes provider auth behavior in one place today, and gives us an extension point for future provider-specific auth, model listing, request setup, and related runtime behavior. ## Tests Ran tests manually to make sure that provider auth under different configs still work as expected. --------- Co-authored-by: pakrym-oai <pakrym@openai.com>
Celia Chen ·
2026-04-17 02:27:45 +00:00 -
[codex] Update realtime V2 VAD silence delay and 1.5 prompt (#18092)
## Summary - set the realtime v2 server VAD silence delay to 500ms - update the default realtime 1.5 backend prompt to the v4 text - keep the session payload and prompt rendering tests aligned with those changes ## Why - the VAD change gives the voice path a longer pause before ending the user's turn - the prompt change makes the default bundled realtime prompt match the current v4 content ## Validation - `cargo +1.93.0 test -p codex-core realtime_prompt --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml` - `CARGO_TARGET_DIR=/tmp/codex-pr-v4-target cargo +1.93.0 test -p codex-api realtime_v2_session_update_includes_background_agent_tool_and_handoff_output_item --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml` - `CARGO_TARGET_DIR=/tmp/codex-pr-v4-target cargo +1.93.0 test -p codex-app-server --test all 'suite::v2::realtime_conversation::realtime_webrtc_start_emits_sdp_notification' --manifest-path /tmp/codex-realtime-v2-vad-prompt-v4/codex-rs/Cargo.toml -- --exact`
bxie-openai ·
2026-04-16 14:30:57 -07:00 -
Clarify realtime v2 context and handoff messages (#17896)
## Summary - wrap realtime startup context in `<startup_context>...</startup_context>` tags - prefix V2 mirrored user text and relayed backend text with `[USER]` / `[BACKEND]` - remove the V2 progress suffix and replace the final V2 handoff output with a short completion acknowledgement while preserving the existing V1 wrapper ## Testing - cargo test -p codex-api realtime_v2_session_update_includes_background_agent_tool_and_handoff_output_item -- --exact - cargo test -p codex-app-server webrtc_v2_background_agent_ - cargo test -p codex-app-server webrtc_v2_text_input_is_ - cargo test -p codex-core conversation_user_text_turn_is_
bxie-openai ·
2026-04-15 16:26:20 -07:00 -
Refactor auth providers to mutate request headers (#17866)
## Summary - Move auth header construction into the `AuthProvider::add_auth_headers` contract. - Inline `CoreAuthProvider` header mutation in its provider impl and remove the shared header-map helper. - Update HTTP, websocket, file upload, sideband websocket, and test auth callsites to use the provider method. - Add direct coverage for `CoreAuthProvider` auth header mutation. ## Testing - `just fmt` - `cargo test -p codex-api` - `cargo test -p codex-core client::tests::auth_request_telemetry_context_tracks_attached_auth_and_retry_phase` - `cargo test -p codex-core` failed on unrelated/reproducible `tools::handlers::multi_agents::tests::multi_agent_v2_followup_task_interrupts_busy_child_without_losing_message` --------- Co-authored-by: Celia Chen <celia@openai.com>
pakrym-oai ·
2026-04-15 11:52:51 -07:00 -
Add realtime wire trace logs (#17838)
- Add trace-only wire logging for realtime websocket request/event text payloads and the WebRTC call SDP request. - Gate raw realtime logs behind `RUST_LOG=codex_api::realtime_websocket::wire=trace` so normal logs stay quiet. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-14 14:39:28 -07:00 -
Add realtime output modality and transcript events (#17701)
- Add outputModality to thread/realtime/start and wire text/audio output selection through app-server, core, API, and TUI.\n- Rename the realtime transcript delta notification and add a separate transcript done notification that forwards final text from item done without correlating it with deltas.
Ahmed Ibrahim ·
2026-04-14 00:13:13 -07:00 -
Log realtime call location (#17761)
Add a trace-level log for the realtime call Location header when decoding the call id.
Ahmed Ibrahim ·
2026-04-13 23:33:51 -07:00 -
change realtime tool description (#17699)
# External (non-OpenAI) Pull Request Requirements Before opening this Pull Request, please read the dedicated "Contributing" markdown file or your PR may be closed: https://github.com/openai/codex/blob/main/docs/contributing.md If your PR conforms to our contribution guidelines, replace this text with a detailed and high quality description of your changes. Include a link to a bug report or enhancement request.
Ahmed Ibrahim ·
2026-04-13 14:31:31 -07:00 -
Queue Realtime V2 response.create while active (#17306)
Builds on #17264. - queues Realtime V2 `response.create` while an active response is open, then flushes it after `response.done` or `response.cancelled` - requests `response.create` after background agent final output and steering acknowledgements - adds app-server integration coverage for all `response.create` paths Validation: - `just fmt` - `cargo check -p codex-app-server --tests` - `git diff --check` - CI green --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-10 09:09:13 -07:00 -
Rename Realtime V2 tool to background_agent (#17278)
Rename the Realtime V2 delegation tool and parser constant to background_agent, and update the tool description and fixtures to match. Validation: just fmt; cargo check -p codex-api; git diff --check --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-09 22:17:55 -07:00 -
Stop Realtime V2 response.done delegation (#17267)
Stop parsing Realtime V2 response completion as a Codex handoff; delegation stays tied to item completion.\n\nValidation: just fmt; git diff --check Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-09 17:17:49 -07:00 -
Add realtime voice selection (#17176)
- Add realtime voice selection for realtime/start. - Expose the supported v1/v2 voice lists and cover explicit, configured, default, and invalid voice paths.
Ahmed Ibrahim ·
2026-04-08 20:19:15 -07:00 -
Attach WebRTC realtime starts to sideband websocket (#17057)
Summary: - parse the realtime call Location header and join that call over the direct realtime WebSocket - keep WebRTC starts alive on the existing realtime conversation path Validation: - just fmt - git diff --check - cargo check -p codex-api - cargo check -p codex-core --tests - local cargo tests not run; relying on PR CI
Ahmed Ibrahim ·
2026-04-08 15:25:42 -07:00 -
Add WebRTC transport to realtime start (#16960)
Adds WebRTC startup to the experimental app-server `thread/realtime/start` method with an optional transport enum. The websocket path remains the default; WebRTC offers create the realtime session through the shared start flow and emit the answer SDP via `thread/realtime/sdp`. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-07 15:43:38 -07:00 -
[codex] reduce module visibility (#16978)
## Summary - reduce public module visibility across Rust crates, preferring private or crate-private modules with explicit crate-root public exports - update external call sites and tests to use the intended public crate APIs instead of reaching through module trees - add the module visibility guideline to AGENTS.md ## Validation - `cargo check --workspace --all-targets --message-format=short` passed before the final fix/format pass - `just fix` completed successfully - `just fmt` completed successfully - `git diff --check` passed
pakrym-oai ·
2026-04-07 08:03:35 -07:00 -
chore: clean up argument-comment lint and roll out all-target CI on macOS (#16054)
## Why `argument-comment-lint` was green in CI even though the repo still had many uncommented literal arguments. The main gap was target coverage: the repo wrapper did not force Cargo to inspect test-only call sites, so examples like the `latest_session_lookup_params(true, ...)` tests in `codex-rs/tui_app_server/src/lib.rs` never entered the blocking CI path. This change cleans up the existing backlog, makes the default repo lint path cover all Cargo targets, and starts rolling that stricter CI enforcement out on the platform where it is currently validated. ## What changed - mechanically fixed existing `argument-comment-lint` violations across the `codex-rs` workspace, including tests, examples, and benches - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` and `tools/argument-comment-lint/run.sh` so non-`--fix` runs default to `--all-targets` unless the caller explicitly narrows the target set - fixed both wrappers so forwarded cargo arguments after `--` are preserved with a single separator - documented the new default behavior in `tools/argument-comment-lint/README.md` - updated `rust-ci` so the macOS lint lane keeps the plain wrapper invocation and therefore enforces `--all-targets`, while Linux and Windows temporarily pass `-- --lib --bins` That temporary CI split keeps the stricter all-targets check where it is already cleaned up, while leaving room to finish the remaining Linux- and Windows-specific target-gated cleanup before enabling `--all-targets` on those runners. The Linux and Windows failures on the intermediate revision were caused by the wrapper forwarding bug, not by additional lint findings in those lanes. ## Validation - `bash -n tools/argument-comment-lint/run.sh` - `bash -n tools/argument-comment-lint/run-prebuilt-linter.sh` - shell-level wrapper forwarding check for `-- --lib --bins` - shell-level wrapper forwarding check for `-- --tests` - `just argument-comment-lint` - `cargo test` in `tools/argument-comment-lint` - `cargo test -p codex-terminal-detection` ## Follow-up - Clean up remaining Linux-only target-gated callsites, then switch the Linux lint lane back to the plain wrapper invocation. - Clean up remaining Windows-only target-gated callsites, then switch the Windows lint lane back to the plain wrapper invocation.
Michael Bolin ·
2026-03-27 19:00:44 -07:00 -
don't add transcript for v2 realtime (#15111)
# External (non-OpenAI) Pull Request Requirements Before opening this Pull Request, please read the dedicated "Contributing" markdown file or your PR may be closed: https://github.com/openai/codex/blob/main/docs/contributing.md If your PR conforms to our contribution guidelines, replace this text with a detailed and high quality description of your changes. Include a link to a bug report or enhancement request.
Ahmed Ibrahim ·
2026-03-18 15:54:13 -07:00 -
Add final message prefix to realtime handoff output (#15077)
- prefix realtime handoff output with the agent final message label for both realtime v1 and v2 - update realtime websocket and core expectations to match
Ahmed Ibrahim ·
2026-03-18 15:19:49 -07:00 -
[stack 2/4] Align main realtime v2 wire and runtime flow (#14830)
## Stack Position 2/4. Built on top of #14828. ## Base - #14828 ## Unblocks - #14829 - #14827 ## Scope - Port the realtime v2 wire parsing, session, app-server, and conversation runtime behavior onto the split websocket-method base. - Branch runtime behavior directly on the current realtime session kind instead of parser-derived flow flags. - Keep regression coverage in the existing e2e suites. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-16 21:38:07 -07:00 -
Apply argument comment lint across codex-rs (#14652)
## Why Once the repo-local lint exists, `codex-rs` needs to follow the checked-in convention and CI needs to keep it from drifting. This commit applies the fallback `/*param*/` style consistently across existing positional literal call sites without changing those APIs. The longer-term preference is still to avoid APIs that require comments by choosing clearer parameter types and call shapes. This PR is intentionally the mechanical follow-through for the places where the existing signatures stay in place. After rebasing onto newer `main`, the rollout also had to cover newly introduced `tui_app_server` call sites. That made it clear the first cut of the CI job was too expensive for the common path: it was spending almost as much time installing `cargo-dylint` and re-testing the lint crate as a representative test job spends running product tests. The CI update keeps the full workspace enforcement but trims that extra overhead from ordinary `codex-rs` PRs. ## What changed - keep a dedicated `argument_comment_lint` job in `rust-ci` - mechanically annotate remaining opaque positional literals across `codex-rs` with exact `/*param*/` comments, including the rebased `tui_app_server` call sites that now fall under the lint - keep the checked-in style aligned with the lint policy by using `/*param*/` and leaving string and char literals uncommented - cache `cargo-dylint`, `dylint-link`, and the relevant Cargo registry/git metadata in the lint job - split changed-path detection so the lint crate's own `cargo test` step runs only when `tools/argument-comment-lint/*` or `rust-ci.yml` changes - continue to run the repo wrapper over the `codex-rs` workspace, so product-code enforcement is unchanged Most of the code changes in this commit are intentionally mechanical comment rewrites or insertions driven by the lint itself. ## Verification - `./tools/argument-comment-lint/run.sh --workspace` - `cargo test -p codex-tui-app-server -p codex-tui` - parsed `.github/workflows/rust-ci.yml` locally with PyYAML --- * -> #14652 * #14651
Michael Bolin ·
2026-03-16 16:48:15 -07:00 -
[stack 1/4] Split realtime websocket methods by version (#14828)
## Stack Position 1/4. Base PR in the realtime stack. ## Base - `main` ## Unblocks - #14830 ## Scope - Split the realtime websocket request builders into `common`, `v1`, and `v2` modules. - Keep runtime behavior unchanged in this PR. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-16 16:00:59 -07:00 -
Add auth 401 observability to client bug reports (#14611)
CXC-392 [With 401](https://openai.sentry.io/issues/7333870443/?project=4510195390611458&query=019ce8f8-560c-7f10-a00a-c59553740674&referrer=issue-stream) <img width="1909" height="555" alt="401 auth tags in Sentry" src="https://github.com/user-attachments/assets/412ea950-61c4-4780-9697-15c270971ee3" /> - auth_401_*: preserved facts from the latest unauthorized response snapshot - auth_*: latest auth-related facts from the latest request attempt - auth_recovery_*: unauthorized recovery state and follow-up result Without 401 <img width="1917" height="522" alt="happy-path auth tags in Sentry" src="https://github.com/user-attachments/assets/3381ed28-8022-43b0-b6c0-623a630e679f" /> ###### Summary - Add client-visible 401 diagnostics for auth attachment, upstream auth classification, and 401 request id / cf-ray correlation. - Record unauthorized recovery mode, phase, outcome, and retry/follow-up status without changing auth behavior. - Surface the highest-signal auth and recovery fields on uploaded client bug reports so they are usable in Sentry. - Preserve original unauthorized evidence under `auth_401_*` while keeping follow-up result tags separate. ###### Rationale (from spec findings) - The dominant bucket needed proof of whether the client attached auth before send or upstream still classified the request as missing auth. - Client uploads needed to show whether unauthorized recovery ran and what the client tried next. - Request id and cf-ray needed to be preserved on the unauthorized response so server-side correlation is immediate. - The bug-report path needed the same auth evidence as the request telemetry path, otherwise the observability would not be operationally useful. ###### Scope - Add auth 401 and unauthorized-recovery observability in `codex-rs/core`, `codex-rs/codex-api`, and `codex-rs/otel`, including feedback-tag surfacing. - Keep auth semantics, refresh behavior, retry behavior, endpoint classification, and geo-denial follow-up work out of this PR. ###### Trade-offs - This exports only safe auth evidence: header presence/name, upstream auth classification, request ids, and recovery state. It does not export token values or raw upstream bodies. - This keeps websocket connection reuse as a transport clue because it can help distinguish stale reused sessions from fresh reconnects. - Misroute/base-url classification and geo-denial are intentionally deferred to a separate follow-up PR so this review stays focused on the dominant auth 401 bucket. ###### Client follow-up - PR 2 will add misroute/provider and geo-denial observability plus the matching feedback-tag surfacing. - A separate host/app-server PR should log auth-decision inputs so pre-send host auth state can be correlated with client request evidence. - `device_id` remains intentionally separate until there is a safe existing source on the feedback upload path. ###### Testing - `cargo test -p codex-core refresh_available_models_sorts_by_priority` - `cargo test -p codex-core emit_feedback_request_tags_` - `cargo test -p codex-core emit_feedback_auth_recovery_tags_` - `cargo test -p codex-core auth_request_telemetry_context_tracks_attached_auth_and_retry_phase` - `cargo test -p codex-core extract_response_debug_context_decodes_identity_headers` - `cargo test -p codex-core identity_auth_details` - `cargo test -p codex-core telemetry_error_messages_preserve_non_http_details` - `cargo test -p codex-core --all-features --no-run` - `cargo test -p codex-otel otel_export_routing_policy_routes_api_request_auth_observability` - `cargo test -p codex-otel otel_export_routing_policy_routes_websocket_connect_auth_observability` - `cargo test -p codex-otel otel_export_routing_policy_routes_websocket_request_transport_observability`
Colin Young ·
2026-03-14 15:38:51 -07:00 -
Use parser-specific realtime voice enum (#14636)
Model realtime session output voices with an enum and map by parser so v1 uses fathom and v2 uses alloy. Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-13 16:17:13 -07:00 -
Fix realtime transcription session.update tools payload (#14635)
Only attach session tools for Realtime v2 conversational sessions, and omit tools in transcription mode so realtime startup no longer fails with unknown parameter errors. Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-13 16:08:58 -07:00 -
feat(app-server, core): add more spans (#14479)
## Description This PR expands tracing coverage across app-server thread startup, core session initialization, and the Responses transport layer. It also gives core dispatch spans stable operation-specific names so traces are easier to follow than the old generic `submission_dispatch` spans. Also use `fmt::Display` for types that we serialize in traces so we send strings instead of rust types
Owen Lin ·
2026-03-13 13:16:33 -07:00 -
Add realtime transcription mode for websocket sessions (#14556)
- add experimental_realtime_ws_mode (conversational/transcription) and plumb it into realtime conversation session config - switch realtime websocket intent and session.update payload shape based on mode - update config schema and realtime/config tests --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-12 23:50:30 -07:00 -
Add codex tool support for realtime v2 handoff (#14554)
- Advertise a `codex` function tool in realtime v2 session updates. - Emit handoff replies as `function_call_output` items while keeping v1 behavior unchanged. - Split realtime event parsing into explicit v1/v2 modules with shared common helpers. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-12 23:30:02 -07:00 -
Add realtime v2 event parser behind feature flag (#14537)
- Add a feature-flagged realtime v2 parser on the existing websocket/session pipeline. - Wire parser selection from core feature flags and map the codex handoff tool-call path into existing handoff events. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-12 21:12:40 -07:00 -
client: extend custom CA handling across HTTPS and websocket clients (#14239)
## Stacked PRs This work is now effectively split across two steps: - #14178: add custom CA support for browser and device-code login flows, docs, and hermetic subprocess tests - #14239: extend that shared custom CA handling across Codex HTTPS clients and secure websocket TLS Note: #14240 was merged into this branch while it was stacked on top of this PR. This PR now subsumes that websocket follow-up and should be treated as the combined change. Builds on top of #14178. ## Problem Custom CA support landed first in the login path, but the real requirement is broader. Codex constructs outbound TLS clients in multiple places, and both HTTPS and secure websocket paths can fail behind enterprise TLS interception if they do not honor `CODEX_CA_CERTIFICATE` or `SSL_CERT_FILE` consistently. This PR broadens the shared custom-CA logic beyond login and applies the same policy to websocket TLS, so the enterprise-proxy story is no longer split between “HTTPS works” and “websockets still fail”. ## What This Delivers Custom CA support is no longer limited to login. Codex outbound HTTPS clients and secure websocket connections can now honor the same `CODEX_CA_CERTIFICATE` / `SSL_CERT_FILE` configuration, so enterprise proxy/intercept setups work more consistently end-to-end. For users and operators, nothing new needs to be configured beyond the same CA env vars introduced in #14178. The change is that more of Codex now respects them, including websocket-backed flows that were previously still using default trust roots. I also manually validated the proxy path locally with mitmproxy using: `CODEX_CA_CERTIFICATE=~/.mitmproxy/mitmproxy-ca-cert.pem HTTPS_PROXY=http://127.0.0.1:8080 just codex` with mitmproxy installed via `brew install mitmproxy` and configured as the macOS system proxy. ## Mental model `codex-client` is now the owner of shared custom-CA policy for outbound TLS client construction. Reqwest callers start from the builder configuration they already need, then pass that builder through `build_reqwest_client_with_custom_ca(...)`. Websocket callers ask the same module for a rustls client config when a custom CA bundle is configured. The env precedence is the same everywhere: - `CODEX_CA_CERTIFICATE` wins - otherwise fall back to `SSL_CERT_FILE` - otherwise use system roots The helper is intentionally narrow. It loads every usable certificate from the configured PEM bundle into the appropriate root store and returns either a configured transport or a typed error that explains what went wrong. ## Non-goals This does not add handshake-level integration tests against a live TLS endpoint. It does not validate that the configured bundle forms a meaningful certificate chain. It also does not try to force every transport in the repo through one abstraction; it extends the shared CA policy across the reqwest and websocket paths that actually needed it. ## Tradeoffs The main tradeoff is centralizing CA behavior in `codex-client` while still leaving adoption up to call sites. That keeps the implementation additive and reviewable, but it means the rule "outbound Codex TLS that should honor enterprise roots must use the shared helper" is still partly enforced socially rather than by types. For websockets, the shared helper only builds an explicit rustls config when a custom CA bundle is configured. When no override env var is set, websocket callers still use their ordinary default connector path. ## Architecture `codex-client::custom_ca` now owns CA bundle selection, PEM normalization, mixed-section parsing, certificate extraction, typed CA-loading errors, and optional rustls client-config construction for websocket TLS. The affected consumers now call into that shared helper directly rather than carrying login-local CA behavior: - backend-client - cloud-tasks - RMCP client paths that use `reqwest` - TUI voice HTTP paths - `codex-core` default reqwest client construction - `codex-api` websocket clients for both responses and realtime websocket connections The subprocess CA probe, env-sensitive integration tests, and shared PEM fixtures also live in `codex-client`, which is now the actual owner of the behavior they exercise. ## Observability The shared CA path logs: - which environment variable selected the bundle - which path was loaded - how many certificates were accepted - when `TRUSTED CERTIFICATE` labels were normalized - when CRLs were ignored - where client construction failed Returned errors remain user-facing and include the relevant env var, path, and remediation hint. That same error model now applies whether the failure surfaced while building a reqwest client or websocket TLS configuration. ## Tests Pure unit tests in `codex-client` cover env precedence and PEM normalization behavior. Real client construction remains in subprocess tests so the suite can control process env and avoid the macOS seatbelt panic path that motivated the hermetic test split. The subprocess coverage verifies: - `CODEX_CA_CERTIFICATE` precedence over `SSL_CERT_FILE` - fallback to `SSL_CERT_FILE` - single-cert and multi-cert bundles - malformed and empty-file errors - OpenSSL `TRUSTED CERTIFICATE` handling - CRL tolerance for well-formed CRL sections The websocket side is covered by the existing `codex-api` / `codex-core` websocket test suites plus the manual mitmproxy validation above. --------- Co-authored-by: Ivan Zakharchanka <3axap4eHko@gmail.com> Co-authored-by: Codex <noreply@openai.com>
Josh McKinney ·
2026-03-13 00:59:26 +00:00 -
Responses: set x-client-request-id as convesration_id when talking to responses (#14312)
Right now we're sending the header session_id to responses which is ignored/dropped. This sets a useful x-client-request-id to the conversation_id.
Channing Conger ·
2026-03-11 12:33:10 -07:00 -
Stabilize websocket response.failed error delivery (#14017)
## What changed - Drop failed websocket connections immediately after a terminal stream error instead of awaiting a graceful close handshake before forwarding the error to the caller. - Keep the success path and the closed-connection guard behavior unchanged. ## Why this fixes the flake - The failing integration test waits for the second websocket stream to surface the model error before issuing a follow-up request. - On slower runners, the old error path awaited `ws_stream.close().await` before sending the error downstream. If that close handshake stalled, the test kept waiting for an error that had already happened server-side and nextest timed it out. - Dropping the failed websocket immediately makes the terminal error observable right away and marks the session closed so the next request reconnects cleanly instead of depending on a best-effort close handshake. ## Code or test? - This is a production logic fix in `codex-api`. The existing websocket integration test already exercises the regression path.
Ahmed Ibrahim ·
2026-03-11 12:33:09 -07:00 -
Use realtime transcript for handoff context (#14132)
- collect input/output transcript deltas into active handoff transcript state - attach and clear that transcript on each handoff, and regenerate schema/tests
Ahmed Ibrahim ·
2026-03-09 22:30:03 -07:00