mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
f6cc2bb0cb030e5c8c3324a96e6f9a0daf264ff9
340 Commits
-
Emit live hook prompts before raw-event filtering (#17189)
# What Project raw Stop-hook prompt response items into typed v2 hookPrompt item-completed notifications before applying the raw-response-event filter. Keep ordinary raw response items filtered for normal subscribers; only the existing hookPrompt bridge runs on the filtered raw-item path. # Why Blocked Stop hooks record their continuation instruction as a raw model-history user item. Normal v2 desktop subscribers do not opt into raw response events, so the app-server listener filtered that raw item before the existing hookPrompt translator could emit the typed live item/completed notification. As a result, the hook-prompt bubble only appeared after thread history was reloaded.
Abhinav ·
2026-04-09 19:48:21 -07:00 -
[mcp] Expand tool search to custom MCPs. (#16944)
- [x] Expand tool search to custom MCPs. - [x] Rename several variables/fields to be more generic. Updated tool & server name lifecycles: **Raw Identity** ToolInfo.server_name is raw MCP server name. ToolInfo.tool.name is raw MCP tool name. MCP calls route back to raw via parse_tool_name() returning (tool.server_name, tool.tool.name). mcpServerStatus/list now groups by raw server and keys tools by Tool.name: mod.rs:599 App-server just forwards that grouped raw snapshot: codex_message_processor.rs:5245 **Callable Names** On list-tools, we create provisional callable_namespace / callable_name: mcp_connection_manager.rs:1556 For non-app MCP, provisional callable name starts as raw tool name. For codex-apps, provisional callable name is sanitized and strips connector name/id prefix; namespace includes connector name. Then qualify_tools() sanitizes callable namespace + name to ASCII alnum / _ only: mcp_tool_names.rs:128 Note: this is stricter than Responses API. Hyphen is currently replaced with _ for code-mode compatibility. **Collision Handling** We do initially collapse example-server and example_server to the same base. Then qualify_tools() detects distinct raw namespace identities behind the same sanitized namespace and appends a hash to the callable namespace: mcp_tool_names.rs:137 Same idea for tool-name collisions: hash suffix goes on callable tool name. Final list_all_tools() map key is callable_namespace + callable_name: mcp_connection_manager.rs:769 **Direct Model Tools** Direct MCP tool declarations use the full qualified sanitized key as the Responses function name. The raw rmcp Tool is converted but renamed for model exposure. **Tool Search / Deferred** Tool search result namespace = final ToolInfo.callable_namespace: tool_search.rs:85 Tool search result nested name = final ToolInfo.callable_name: tool_search.rs:86 Deferred tool handler is registered as "{namespace}:{name}": tool_registry_plan.rs:248 When a function call comes back, core recombines namespace + name, looks up the full qualified key, and gets the raw server/tool for MCP execution: codex.rs:4353 **Separate Legacy Snapshot** collect_mcp_snapshot_from_manager_with_detail() still returns a map keyed by qualified callable name. mcpServerStatus/list no longer uses that; it uses McpServerStatusSnapshot, which is raw-inventory shaped.Matthew Zeng ·
2026-04-09 13:34:52 -07:00 -
app-server: Use shared receivers for app-server message processors (#17256)
We do not rely on the mutability here, so express it in the type system.
Ruslan Nigmatullin ·
2026-04-09 19:53:50 +00:00 -
Forward app-server turn clientMetadata to Responses (#16009)
## Summary App-server v2 already receives turn-scoped `clientMetadata`, but the Rust app-server was dropping it before the outbound Responses request. This change keeps the fix lightweight by threading that metadata through the existing turn-metadata path rather than inventing a new transport. ## What we're trying to do and why We want turn-scoped metadata from the app-server protocol layer, especially fields like Hermes/GAAS run IDs, to survive all the way to the actual Responses API request so it is visible in downstream websocket request logging and analytics. The specific bug was: - app-server protocol uses camelCase `clientMetadata` - Responses transport already has an existing turn metadata carrier: `x-codex-turn-metadata` - websocket transport already rewrites that header into `request.request_body.client_metadata["x-codex-turn-metadata"]` - but the Rust app-server never parsed or stored `clientMetadata`, so nothing from the app-server request was making it into that existing path This PR fixes that without adding a new header or a second metadata channel. ## How we did it ### Protocol surface - Add optional `clientMetadata` to v2 `TurnStartParams` and `TurnSteerParams` - Regenerate the JSON schema / TypeScript fixtures - Update app-server docs to describe the field and its behavior ### Runtime plumbing - Add a dedicated core op for app-server user input carrying turn-scoped metadata: `Op::UserInputWithClientMetadata` - Wire `turn/start` and `turn/steer` through that op / signature path instead of dropping the metadata at the message-processor boundary - Store the metadata in `TurnMetadataState` ### Transport behavior - Reuse the existing serialized `x-codex-turn-metadata` payload - Merge the new app-server `clientMetadata` into that JSON additively - Do **not** replace built-in reserved fields already present in the turn metadata payload - Keep websocket behavior unchanged at the outer shape level: it still sends only `client_metadata["x-codex-turn-metadata"]`, but that JSON string now contains the merged fields - Keep HTTP fallback behavior unchanged except that the existing `x-codex-turn-metadata` header now includes the merged fields too ### Request shape before / after Before, a websocket `response.create` looked like: ```json { "type": "response.create", "client_metadata": { "x-codex-turn-metadata": "{\"session_id\":\"...\",\"turn_id\":\"...\"}" } } ``` Even if the app-server caller supplied `clientMetadata`, it was not represented there. After, the same request shape is preserved, but the serialized payload now includes the new turn-scoped fields: ```json { "type": "response.create", "client_metadata": { "x-codex-turn-metadata": "{\"session_id\":\"...\",\"turn_id\":\"...\",\"fiber_run_id\":\"fiber-start-123\",\"origin\":\"gaas\"}" } } ``` ## Validation ### Targeted tests added / updated - protocol round-trip coverage for `clientMetadata` on `turn/start` and `turn/steer` - protocol round-trip coverage for `Op::UserInputWithClientMetadata` - `TurnMetadataState` merge test proving client metadata is added without overwriting reserved built-in fields - websocket request-shape test proving outbound `response.create` contains merged metadata inside `client_metadata["x-codex-turn-metadata"]` - app-server integration tests proving: - `turn/start` forwards `clientMetadata` into the outbound Responses request path - websocket warmup + real turn request both behave correctly - `turn/steer` updates the follow-up request metadata ### Commands run - `just write-app-server-schema` - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-protocol` - `cargo test -p codex-core turn_metadata_state_merges_client_metadata_without_replacing_reserved_fields --lib` - `cargo test -p codex-core --test all responses_websocket_preserves_custom_turn_metadata_fields` - `cargo test -p codex-app-server --test all client_metadata` - `cargo test -p codex-app-server --test all turn_start_forwards_client_metadata_to_responses_websocket_request_body_v2 -- --nocapture` - `just fmt` - `just fix -p codex-core -p codex-protocol -p codex-app-server-protocol -p codex-app-server` - `just fix -p codex-exec -p codex-tui-app-server` - `just argument-comment-lint` ### Full suite note `cargo test` in `codex-rs` still fails in: - `suite::v2::turn_interrupt::turn_interrupt_resolves_pending_command_approval_request` I verified that same failure on a clean detached `HEAD` worktree with an isolated `CARGO_TARGET_DIR`, so it is not caused by this patch.neil-oai ·
2026-04-09 11:52:37 -07:00 -
chore: merge name and title (#17116)
Merge title and name concept to leverage the sqlite title column and have more efficient queries --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-04-09 18:44:26 +01: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 -
Use AbsolutePathBuf for exec cwd plumbing (#17063)
## Summary - Carry `AbsolutePathBuf` through tool cwd parsing/resolution instead of resolving workdirs to raw `PathBuf`s. - Type exec/sandbox request cwd fields as `AbsolutePathBuf` through `ExecParams`, `ExecRequest`, `SandboxCommand`, and unified exec runtime requests. - Keep `PathBuf` conversions at external/event boundaries and update existing tests/fixtures for the typed cwd. ## Validation - `cargo check -p codex-core --tests` - `cargo check -p codex-sandboxing --tests` - `cargo test -p codex-sandboxing` - `cargo test -p codex-core --lib tools::handlers::` - `just fix -p codex-sandboxing` - `just fix -p codex-core` - `just fmt` Full `codex-core` test suite was not run locally; per repo guidance I kept local validation targeted.
pakrym-oai ·
2026-04-08 10:54:12 -07:00 -
Support anyOf and enum in JsonSchema (#16875)
This brings us into better alignment with the JSON schema subset that is supported in <https://developers.openai.com/api/docs/guides/structured-outputs#supported-schemas>, and also allows us to render richer function signatures in code mode (e.g., anyOf{null, OtherObjectType})
Vivian Fang ·
2026-04-08 01:07:55 -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 -
Dylan Hurd ·
2026-04-07 15:18:34 -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 -
feat: /feedback cascade (#16442)
Example here: https://openai.sentry.io/issues/7380240430/?project=4510195390611458&query=019d498f-bec4-7ba2-96d2-612b1e4507df&referrer=issue-stream
jif-oai ·
2026-04-07 12:47:37 +01:00 -
Honor null thread instructions (#16964)
- Treat explicit null thread instructions as a blank-slate override while preserving omitted-field fallback behavior. - Preserve null through rollout resume/fork and keep explicit empty strings distinct. - Add app-server v2 start/fork coverage for the tri-state instruction params.
Ahmed Ibrahim ·
2026-04-07 04:10:19 +00:00 -
[mcp] Support MCP Apps part 1. (#16082)
- [x] Add `mcpResource/read` method to read mcp resource.
Matthew Zeng ·
2026-04-06 19:17:14 -07:00 -
Ruslan Nigmatullin ·
2026-04-06 18:04:00 -07:00 -
Refactor config types into a separate crate (#16962)
Move config types into a separate crate because their macros expand into a lot of new code.
pakrym-oai ·
2026-04-07 00:32:41 +00:00 -
Speed up /mcp inventory listing (#16831)
Addresses #16244 This was a performance regression introduced when we moved the TUI on top of the app server API. Problem: `/mcp` rebuilt a full MCP inventory through `mcpServerStatus/list`, including resources and resource templates that made the TUI wait on slow inventory probes. Solution: add a lightweight `detail` mode to `mcpServerStatus/list`, have `/mcp` request tools-and-auth only, and cover the fast path with app-server and TUI tests. Testing: Confirmed slow (multi-second) response prior to change and immediate response after change. I considered two options: 1. Change the existing `mcpServerStatus/list` API to accept an optional "details" parameter so callers can request only a subset of the information. 2. Add a separate `mcpServer/list` API that returns only the servers, tools, and auth but omits the resources. I chose option 1, but option 2 is also a reasonable approach.
Eric Traut ·
2026-04-06 16:27:02 -07:00 -
[codex-analytics] add protocol-native turn timestamps (#16638)
--- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16638). * #16870 * #16706 * #16659 * #16641 * #16640 * __->__ #16638
rhan-oai ·
2026-04-06 16:22:59 -07:00 -
feat: refresh non-curated cache from plugin list. (#16191)
1. Use versions for non-curated plugin (defined in plugin.json) for cache refresh 2. Trigger refresh from plugin/list roots
xl-openai ·
2026-04-06 15:40:00 -07:00 -
Revert "[codex-backend] Make thread metadata updates tolerate pending backfill" (#16923)
Reverts openai/codex#16877
joeytrasatti-openai ·
2026-04-06 21:25:05 +00:00 -
[codex-backend] Make thread metadata updates tolerate pending backfill (#16877)
### Summary Fix `thread/metadata/update` so it can still patch stored thread metadata when the list/backfill-gated `get_state_db(...)` path is unavailable. What was happening: - The app logs showed `thread/metadata/update` failing with `sqlite state db unavailable for thread ...`. - This was not isolated to one bad thread. Once the failure started for a user, branch metadata updates failed 100% of the time for that user. - Reports were staggered across users, which points at local app-server / local SQLite state rather than one global server-side failure. - Turns could still start immediately after the metadata update failed, which suggests the thread itself was valid and the failure was in the metadata endpoint DB-handle path. The fix: - Keep using the loaded thread state DB and the normal `get_state_db(...)` fallback first. - If that still returns `None`, open `StateRuntime::init(...)` directly for this targeted metadata update path. - Log the direct state runtime init error if that final fallback also fails, so future reports have the real DB-open cause instead of only the generic unavailable error. - Add a regression test where the DB exists but backfill is not complete, and verify `thread/metadata/update` can still repair the stored rollout thread and patch `gitInfo`. Relevant context / suspect PRs: - #16434 changed state DB startup to run auto-vacuum / incremental vacuum. This is the most suspicious timing match for per-user, staggered local SQLite availability failures. - #16433 dropped the old log table from the state DB, also near the timing window. - #13280 introduced this endpoint and made it rely on SQLite for git metadata without resuming the thread. - #14859 and #14888 added/consumed persisted model + reasoning effort metadata. I checked these because of the new thread metadata fields, but this failure happens before the endpoint reaches thread-row update/load logic, so they seem less likely as the direct cause. ### Testing - `cargo fmt -- --config imports_granularity=Item` completed; local stable rustfmt emitted warnings that `imports_granularity` is unstable - `cargo test -p codex-app-server thread_metadata_update` - `git diff --check`
joeytrasatti-openai ·
2026-04-06 13:07:19 -04:00 -
[codex-analytics] subagent analytics (#15915)
- creates custom event that emits subagent thread analytics from core - wires client metadata (`product_client_id, client_name, client_version`), through from app-server - creates `created_at `timestamp in core - subagent analytics are behind `FeatureFlag::GeneralAnalytics` PR stack - [[telemetry] thread events #15690](https://github.com/openai/codex/pull/15690) - --> [[telemetry] subagent events #15915](https://github.com/openai/codex/pull/15915) - [[telemetry] turn events #15591](https://github.com/openai/codex/pull/15591) - [[telemetry] steer events #15697](https://github.com/openai/codex/pull/15697) - [[telemetry] queued prompt data #15804](https://github.com/openai/codex/pull/15804) Notes: - core does not spawn a subagent thread for compact, but represented in mapping for consistency `INFO | 2026-04-01 13:08:12 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:399 | Tracked codex_thread_initialized event params={'thread_id': '019d4aa9-233b-70f2-a958-c3dbae1e30fa', 'product_surface': 'codex', 'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name': 'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process', 'experimental_api_enabled': None}, 'runtime': {'codex_rs_version': '0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0', 'runtime_arch': 'aarch64'}, 'model': 'gpt-5.3-codex', 'ephemeral': False, 'initialization_mode': 'new', 'created_at': 1775074091, 'thread_source': 'subagent', 'subagent_source': 'thread_spawn', 'parent_thread_id': '019d4aa8-51ec-77e3-bafb-2c1b8e29e385'} | ` `INFO | 2026-04-01 13:08:41 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:399 | Tracked codex_thread_initialized event params={'thread_id': '019d4aa9-94e3-75f1-8864-ff8ad0e55e1e', 'product_surface': 'codex', 'app_server_client': {'product_client_id': 'CODEX_CLI', 'client_name': 'codex-tui', 'client_version': '0.0.0', 'rpc_transport': 'in_process', 'experimental_api_enabled': None}, 'runtime': {'codex_rs_version': '0.0.0', 'runtime_os': 'macos', 'runtime_os_version': '26.4.0', 'runtime_arch': 'aarch64'}, 'model': 'gpt-5.3-codex', 'ephemeral': False, 'initialization_mode': 'new', 'created_at': 1775074120, 'thread_source': 'subagent', 'subagent_source': 'review', 'parent_thread_id': None} | ` --------- Co-authored-by: jif-oai <jif@openai.com> Co-authored-by: Michael Bolin <mbolin@openai.com>
rhan-oai ·
2026-04-04 11:06:43 -07:00 -
Fix Windows Bazel app-server trust tests (#16711)
## Why Extracted from [#16528](https://github.com/openai/codex/pull/16528) so the Windows Bazel app-server test failures can be reviewed independently from the rest of that PR. This PR targets: - `suite::v2::thread_shell_command::thread_shell_command_runs_as_standalone_turn_and_persists_history` - `suite::v2::thread_start::thread_start_with_elevated_sandbox_trusts_project_and_followup_loads_project_config` - `suite::v2::thread_start::thread_start_with_nested_git_cwd_trusts_repo_root` There were two Windows-specific assumptions baked into those tests and the underlying trust lookup: - project trust keys were persisted and looked up using raw path strings, but Bazel's Windows test environment can surface canonicalized paths with `\\?\` / UNC prefixes or normalized symlink/junction targets, so follow-up `thread/start` requests no longer matched the project entry that had just been written - `item/commandExecution/outputDelta` assertions compared exact trailing line endings even though shell output chunk boundaries and CRLF handling can differ on Windows, and Bazel made that timing-sensitive mismatch visible There was also one behavior bug separate from the assertion cleanup: `thread/start` decided whether to persist trust from the final resolved sandbox policy, but on Windows an explicit `workspace-write` request may be downgraded to `read-only`. That incorrectly skipped writing trust even though the request had asked to elevate the project, so the new logic also keys off the requested sandbox mode. ## What - Canonicalize project trust keys when persisting/loading `[projects]` entries, while still accepting legacy raw keys for existing configs. - Persist project trust when `thread/start` explicitly requests `workspace-write` or `danger-full-access`, even if the resolved policy is later downgraded on Windows. - Make the Windows app-server tests compare persisted trust paths and command output deltas in a path/newline-normalized way. ## Verification - Existing app-server v2 tests cover the three failing Windows Bazel cases above.
Michael Bolin ·
2026-04-03 21:41:25 +00:00 -
Add remote --cd forwarding for app-server sessions (#16700)
Addresses #16124 Problem: `codex --remote --cd <path>` canonicalized the path locally and then omitted it from remote thread lifecycle requests, so remote-only working directories failed or were ignored. Solution: Keep remote startup on the local cwd, forward explicit `--cd` values verbatim to `thread/start`, `thread/resume`, and `thread/fork`, and cover the behavior with `codex-tui` tests. Testing: I manually tested `--remote --cd` with both absolute and relative paths and validated correct behavior. --- Update based on code review feedback: Problem: Remote `--cd` was forwarded to `thread/resume` and `thread/fork`, but not to `thread/list` lookups, so `--resume --last` and picker flows could select a session from the wrong cwd; relative cwd filters also failed against stored absolute paths. Solution: Apply explicit remote `--cd` to `thread/list` lookups for `--last` and picker flows, normalize relative cwd filters on the app-server before exact matching, and document/test the behavior.
Eric Traut ·
2026-04-03 11:26:45 -07:00 -
Fix MCP tool listing for hyphenated server names (#16674)
Addresses #16671 and #14927 Problem: `mcpServerStatus/list` rebuilt MCP tool groups from sanitized tool prefixes but looked them up by unsanitized server names, so hyphenated servers rendered as having no tools in `/mcp`. This was reported as a regression when the TUI switched to use the app server. Solution: Build each server's tool map using the original server name's sanitized prefix, include effective runtime MCP servers in the status response, and add a regression test for hyphenated server names.
Eric Traut ·
2026-04-03 09:05:50 -07:00 -
remove temporary ownership re-exports (#16626)
Stacked on #16508. This removes the temporary `codex-core` / `codex-login` re-export shims from the ownership split and rewrites callsites to import directly from `codex-model-provider-info`, `codex-models-manager`, `codex-api`, `codex-protocol`, `codex-feedback`, and `codex-response-debug-context`. No behavior change intended; this is the mechanical import cleanup layer split out from the ownership move. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-03 00:33:34 -07:00 -
extract models manager and related ownership from core (#16508)
## Summary - split `models-manager` out of `core` and add `ModelsManagerConfig` plus `Config::to_models_manager_config()` so model metadata paths stop depending on `core::Config` - move login-owned/auth-owned code out of `core` into `codex-login`, move model provider config into `codex-model-provider-info`, move API bridge mapping into `codex-api`, move protocol-owned types/impls into `codex-protocol`, and move response debug helpers into a dedicated `response-debug-context` crate - move feedback tag emission into `codex-feedback`, relocate tests to the crates that now own the code, and keep broad temporary re-exports so this PR avoids a giant import-only rewrite ## Major moves and decisions - created `codex-models-manager` as the owner for model cache/catalog/config/model info logic, including the new `ModelsManagerConfig` struct - created `codex-model-provider-info` as the owner for provider config parsing/defaults and kept temporary `codex-login`/`codex-core` re-exports for old import paths - moved `api_bridge` error mapping + `CoreAuthProvider` into `codex-api`, while `codex-login::api_bridge` temporarily re-exports those symbols and keeps the `auth_provider_from_auth` wrapper - moved `auth_env_telemetry` and `provider_auth` ownership to `codex-login` - moved `CodexErr` ownership to `codex-protocol::error`, plus `StreamOutput`, `bytes_to_string_smart`, and network policy helpers to protocol-owned modules - created `codex-response-debug-context` for `extract_response_debug_context`, `telemetry_transport_error_message`, and related response-debug plumbing instead of leaving that behavior in `core` - moved `FeedbackRequestTags`, `emit_feedback_request_tags`, and `emit_feedback_request_tags_with_auth_env` to `codex-feedback` - deferred removal of temporary re-exports and the mechanical import rewrites to a stacked follow-up PR so this PR stays reviewable ## Test moves - moved auth refresh coverage from `core/tests/suite/auth_refresh.rs` to `login/tests/suite/auth_refresh.rs` - moved text encoding coverage from `core/tests/suite/text_encoding_fix.rs` to `protocol/src/exec_output_tests.rs` - moved model info override coverage from `core/tests/suite/model_info_overrides.rs` to `models-manager/src/model_info_overrides_tests.rs` --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-04-02 23:00:02 -07:00 -
Auto-trust cwd on thread start (#16492)
- Persist trusted cwd state during thread/start when the resolved sandbox is elevated. - Add app-server coverage for trusted root resolution and confirm turn/start does not mutate trust.
Ahmed Ibrahim ·
2026-04-03 00:02:56 +00:00 -
Fix fork source display in /status (expose forked_from_id in app server) (#16596)
Addresses #16560 Problem: `/status` stopped showing the source thread id in forked TUI sessions after the app-server migration. Solution: Carry fork source ids through app-server v2 thread data and the TUI session adapter, and update TUI fixtures so `/status` matches the old TUI behavior.
Eric Traut ·
2026-04-02 14:05:29 -07:00 -
[codex] Remove codex-core config type shim (#16529)
## Why This finishes the config-type move out of `codex-core` by removing the temporary compatibility shim in `codex_core::config::types`. Callers now depend on `codex-config` directly, which keeps these config model types owned by the config crate instead of re-expanding `codex-core` as a transitive API surface. ## What Changed - Removed the `codex-rs/core/src/config/types.rs` re-export shim and the `core::config::ApprovalsReviewer` re-export. - Updated `codex-core`, `codex-cli`, `codex-tui`, `codex-app-server`, `codex-mcp-server`, and `codex-linux-sandbox` call sites to import `codex_config::types` directly. - Added explicit `codex-config` dependencies to downstream crates that previously relied on the `codex-core` re-export. - Regenerated `codex-rs/core/config.schema.json` after updating the config docs path reference.
Michael Bolin ·
2026-04-02 01:19:44 -07:00 -
core: remove cross-crate re-exports from lib.rs (#16512)
## Why `codex-core` was re-exporting APIs owned by sibling `codex-*` crates, which made downstream crates depend on `codex-core` as a proxy module instead of the actual owner crate. Removing those forwards makes crate boundaries explicit and lets leaf crates drop unnecessary `codex-core` dependencies. In this PR, this reduces the dependency on `codex-core` to `codex-login` in the following files: ``` codex-rs/backend-client/Cargo.toml codex-rs/mcp-server/tests/common/Cargo.toml ``` ## What - Remove `codex-rs/core/src/lib.rs` re-exports for symbols owned by `codex-login`, `codex-mcp`, `codex-rollout`, `codex-analytics`, `codex-protocol`, `codex-shell-command`, `codex-sandboxing`, `codex-tools`, and `codex-utils-path`. - Delete the `default_client` forwarding shim in `codex-rs/core`. - Update in-crate and downstream callsites to import directly from the owning `codex-*` crate. - Add direct Cargo dependencies where callsites now target the owner crate, and remove `codex-core` from `codex-rs/backend-client`.
Michael Bolin ·
2026-04-01 23:06:24 -07:00 -
core: use codex-mcp APIs directly (#16510)
## Why `codex-mcp` already owns the shared MCP API surface, including `auth`, `McpConfig`, `CODEX_APPS_MCP_SERVER_NAME`, and tool-name helpers in [`codex-rs/codex-mcp/src/mcp/mod.rs`](https://github.com/openai/codex/blob/f61e85dbfb5373cde6827d232ac8ea447c237e81/codex-rs/codex-mcp/src/mcp/mod.rs#L1-L35). Re-exporting that surface from `codex_core::mcp` gives downstream crates two import paths for the same API and hides the real crate dependency. This PR keeps `codex_core::mcp` focused on the local `McpManager` wrapper in [`codex-rs/core/src/mcp.rs`](https://github.com/openai/codex/blob/f61e85dbfb5373cde6827d232ac8ea447c237e81/codex-rs/core/src/mcp.rs#L13-L40) and makes consumers import shared MCP APIs from `codex_mcp` directly. ## What - Remove the `codex_mcp::mcp` re-export surface from `core/src/mcp.rs`. - Update `codex-core` internals plus `codex-app-server`, `codex-cli`, and `codex-tui` test code to import MCP APIs from `codex_mcp::mcp` directly. - Add explicit `codex-mcp` dependencies where those crates now use that API surface, and refresh `Cargo.lock`. ## Verification - `just bazel-lock-check` - `cargo test -p codex-core -p codex-cli -p codex-tui` - `codex-cli` passed. - `codex-core` still fails five unrelated config tests in `core/src/config/config_tests.rs` (`approvals_reviewer_*` and `smart_approvals_alias_*`). - A broader `cargo test -p codex-core -p codex-app-server -p codex-cli -p codex-tui` run previously hung in `codex-app-server` test `in_process_start_uses_requested_session_source_for_thread_start`.
Michael Bolin ·
2026-04-01 21:55:22 -07:00 -
Extract MCP into codex-mcp crate (#15919)
- Split MCP runtime/server code out of `codex-core` into the new `codex-mcp` crate. New/moved public structs/types include `McpConfig`, `McpConnectionManager`, `ToolInfo`, `ToolPluginProvenance`, `CodexAppsToolsCacheKey`, and the `McpManager` API (`codex_mcp::mcp::McpManager` plus the `codex_core::mcp::McpManager` wrapper/shim). New/moved functions include `with_codex_apps_mcp`, `configured_mcp_servers`, `effective_mcp_servers`, `collect_mcp_snapshot`, `collect_mcp_snapshot_from_manager`, `qualified_mcp_tool_name_prefix`, and the MCP auth/skill-dependency helpers. Why: this creates a focused MCP crate boundary and shrinks `codex-core` without forcing every consumer to migrate in the same PR. - Move MCP server config schema and persistence into `codex-config`. New/moved structs/enums include `AppToolApproval`, `McpServerToolConfig`, `McpServerConfig`, `RawMcpServerConfig`, `McpServerTransportConfig`, `McpServerDisabledReason`, and `codex_config::ConfigEditsBuilder`. New/moved functions include `load_global_mcp_servers` and `ConfigEditsBuilder::replace_mcp_servers`/`apply`. Why: MCP TOML parsing/editing is config ownership, and this keeps config validation/round-tripping (including per-tool approval overrides and inline bearer-token rejection) in the config crate instead of `codex-core`. - Rewire `codex-core`, app-server, and plugin call sites onto the new crates. Updated `Config::to_mcp_config(&self, plugins_manager)`, `codex-rs/core/src/mcp.rs`, `codex-rs/core/src/connectors.rs`, `codex-rs/core/src/codex.rs`, `CodexMessageProcessor::list_mcp_server_status_task`, and `utils/plugins/src/mcp_connector.rs` to build/pass the new MCP config/runtime types. Why: plugin-provided MCP servers still merge with user-configured servers, and runtime auth (`CodexAuth`) is threaded into `with_codex_apps_mcp` / `collect_mcp_snapshot` explicitly so `McpConfig` stays config-only.
Ahmed Ibrahim ·
2026-04-01 19:03:26 -07:00 -
[codex-analytics] thread events (#15690)
- add event for thread initialization - thread/start, thread/fork, thread/resume - feature flagged behind `FeatureFlag::GeneralAnalytics` - does not yet support threads started by subagents PR stack: - --> [[telemetry] thread events #15690](https://github.com/openai/codex/pull/15690) - [[telemetry] subagent events #15915](https://github.com/openai/codex/pull/15915) - [[telemetry] turn events #15591](https://github.com/openai/codex/pull/15591) - [[telemetry] steer events #15697](https://github.com/openai/codex/pull/15697) - [[telemetry] queued prompt data #15804](https://github.com/openai/codex/pull/15804) Sample extracted logs in Codex-backend ``` INFO | 2026-03-29 16:39:37 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:398 | Tracked analytics event codex_thread_initialized thread_id=019d3bf7-9f5f-7f82-9877-6d48d1052531 product_surface=codex product_client_id=CODEX_CLI client_name=codex-tui client_version=0.0.0 rpc_transport=in_process experimental_api_enabled=True codex_rs_version=0.0.0 runtime_os=macos runtime_os_version=26.4.0 runtime_arch=aarch64 model=gpt-5.3-codex ephemeral=False thread_source=user initialization_mode=new subagent_source=None parent_thread_id=None created_at=1774827577 | INFO | 2026-03-29 16:45:46 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:398 | Tracked analytics event codex_thread_initialized thread_id=019d3b84-5731-79d0-9b3b-9c6efe5f5066 product_surface=codex product_client_id=CODEX_CLI client_name=codex-tui client_version=0.0.0 rpc_transport=in_process experimental_api_enabled=True codex_rs_version=0.0.0 runtime_os=macos runtime_os_version=26.4.0 runtime_arch=aarch64 model=gpt-5.3-codex ephemeral=False thread_source=user initialization_mode=resumed subagent_source=None parent_thread_id=None created_at=1774820022 | INFO | 2026-03-29 16:45:49 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:398 | Tracked analytics event codex_thread_initialized thread_id=019d3bfd-4cd6-7c12-a13e-48cef02e8c4d product_surface=codex product_client_id=CODEX_CLI client_name=codex-tui client_version=0.0.0 rpc_transport=in_process experimental_api_enabled=True codex_rs_version=0.0.0 runtime_os=macos runtime_os_version=26.4.0 runtime_arch=aarch64 model=gpt-5.3-codex ephemeral=False thread_source=user initialization_mode=forked subagent_source=None parent_thread_id=None created_at=1774827949 | INFO | 2026-03-29 17:20:29 | codex_backend.routers.analytics_events | analytics_events.track_analytics_events:398 | Tracked analytics event codex_thread_initialized thread_id=019d3c1d-0412-7ed2-ad24-c9c0881a36b0 product_surface=codex product_client_id=CODEX_SERVICE_EXEC client_name=codex_exec client_version=0.0.0 rpc_transport=in_process experimental_api_enabled=True codex_rs_version=0.0.0 runtime_os=macos runtime_os_version=26.4.0 runtime_arch=aarch64 model=gpt-5.3-codex ephemeral=False thread_source=user initialization_mode=new subagent_source=None parent_thread_id=None created_at=1774830027 | ``` Notes - `product_client_id` gets canonicalized in codex-backend - subagent threads are addressed in a following pr
rhan-oai ·
2026-03-31 12:16:44 -07:00 -
auth: let AuthManager own external bearer auth (#16287)
## Summary `AuthManager` and `UnauthorizedRecovery` already own token resolution and staged `401` recovery. The missing piece for provider auth was a bearer-only mode that still fit that design, instead of pushing a second auth abstraction into `codex-core`. This PR keeps the design centered on `AuthManager`: it teaches `codex-login` how to own external bearer auth directly so later provider work can keep calling `AuthManager.auth()` and `UnauthorizedRecovery`. ## Motivation This is the middle layer for #15189. The intended design is still: - `AuthManager` encapsulates token storage and refresh - `UnauthorizedRecovery` powers staged `401` recovery - all request tokens go through `AuthManager.auth()` This PR makes that possible for provider-backed bearer tokens by adding a bearer-only auth mode inside `AuthManager` instead of building parallel request-auth plumbing in `core`. ## What Changed - move `ModelProviderAuthInfo` into `codex-protocol` so `core` and `login` share one config shape - add `login/src/auth/external_bearer.rs`, which runs the configured command, caches the bearer token in memory, and refreshes it after `401` - add `AuthManager::external_bearer_only(...)` for provider-scoped request paths that should use command-backed bearer auth without mutating the shared OpenAI auth manager - add `AuthManager::shared_with_external_chatgpt_auth_refresher(...)` and rename the other `AuthManager` helpers that only apply to external ChatGPT auth so the ChatGPT-only path is explicit at the call site - keep external ChatGPT refresh behavior unchanged while ensuring bearer-only external auth never persists to `auth.json` ## Testing - `cargo test -p codex-login` - `cargo test -p codex-protocol` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/16287). * #16288 * __->__ #16287
Michael Bolin ·
2026-03-31 01:26:17 -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 -
Add ChatGPT device-code login to app server (#15525)
## Problem App-server clients could only initiate ChatGPT login through the browser callback flow, even though the shared login crate already supports device-code auth. That left VS Code, Codex App, and other app-server clients without a first-class way to use the existing device-code backend when browser redirects are brittle or when the client UX wants to own the login ceremony. ## Mental model This change adds a second ChatGPT login start path to app-server: clients can now call `account/login/start` with `type: "chatgptDeviceCode"`. App-server immediately returns a `loginId` plus the device-code UX payload (`verificationUrl` and `userCode`), then completes the login asynchronously in the background using the existing `codex_login` polling flow. Successful device-code login still resolves to ordinary `chatgpt` auth, and completion continues to flow through the existing `account/login/completed` and `account/updated` notifications. ## Non-goals This does not introduce a new auth mode, a new account shape, or a device-code eligibility discovery API. It also does not add automatic fallback to browser login in core; clients remain responsible for choosing when to request device code and whether to retry with a different UX if the backend/admin policy rejects it. ## Tradeoffs We intentionally keep `login_chatgpt_common` as a local validation helper instead of turning it into a capability probe. Device-code eligibility is checked by actually calling `request_device_code`, which means policy-disabled cases surface as an immediate request error rather than an async completion event. We also keep the active-login state machine minimal: browser and device-code logins share the same public cancel contract, but device-code cancellation is implemented with a local cancel token rather than a larger cross-crate refactor. ## Architecture The protocol grows a new `chatgptDeviceCode` request/response variant in app-server v2. On the server side, the new handler reuses the existing ChatGPT login precondition checks, calls `request_device_code`, returns the device-code payload, and then spawns a background task that waits on either cancellation or `complete_device_code_login`. On success, it reuses the existing auth reload and cloud-requirements refresh path before emitting `account/login/completed` success and `account/updated`. On failure or cancellation, it emits only `account/login/completed` failure. The existing `account/login/cancel { loginId }` contract remains unchanged and now works for both browser and device-code attempts. ## Tests Added protocol serialization coverage for the new request/response variant, plus app-server tests for device-code success, failure, cancel, and start-time rejection behavior. Existing browser ChatGPT login coverage remains in place to show that the callback-based flow is unchanged.daniel-oai ·
2026-03-27 00:27:15 -07:00 -
codex-tools: extract shared tool schema parsing (#15923)
## Why `parse_tool_input_schema` and the supporting `JsonSchema` model were living in `core/src/tools/spec.rs`, but they already serve callers outside `codex-core`. Keeping that shared schema parsing logic inside `codex-core` makes the crate boundary harder to reason about and works against the guidance in `AGENTS.md` to avoid growing `codex-core` when reusable code can live elsewhere. This change takes the first extraction step by moving the schema parsing primitive into its own crate while keeping the rest of the tool-spec assembly in `codex-core`. ## What changed - added a new `codex-tools` crate under `codex-rs/tools` - moved the shared tool input schema model and sanitizer/parser into `tools/src/json_schema.rs` - kept `tools/src/lib.rs` exports-only, with the module-level unit tests split into `json_schema_tests.rs` - updated `codex-core` to use `codex-tools::JsonSchema` and re-export `parse_tool_input_schema` - updated `codex-app-server` dynamic tool validation to depend on `codex-tools` directly instead of reaching through `codex-core` - wired the new crate into the Cargo workspace and Bazel build graph
Michael Bolin ·
2026-03-27 00:03:35 +00:00 -
fix: fix old system bubblewrap compatibility without falling back to vendored bwrap (#15693)
Fixes #15283. ## Summary Older system bubblewrap builds reject `--argv0`, which makes our Linux sandbox fail before the helper can re-exec. This PR keeps using system `/usr/bin/bwrap` whenever it exists and only falls back to vendored bwrap when the system binary is missing. That matters on stricter AppArmor hosts, where the distro bwrap package also provides the policy setup needed for user namespaces. For old system bwrap, we avoid `--argv0` instead of switching binaries: - pass the sandbox helper a full-path `argv0`, - keep the existing `current_exe() + --argv0` path when the selected launcher supports it, - otherwise omit `--argv0` and re-exec through the helper's own `argv[0]` path, whose basename still dispatches as `codex-linux-sandbox`. Also updates the launcher/warning tests and docs so they match the new behavior: present-but-old system bwrap uses the compatibility path, and only absent system bwrap falls back to vendored. ### Validation 1. Install Ubuntu 20.04 in a VM 2. Compile codex and run without bubblewrap installed - see a warning about falling back to the vendored bwrap 3. Install bwrap and verify version is 0.4.0 without `argv0` support 4. run codex and use apply_patch tool without errors <img width="802" height="631" alt="Screenshot 2026-03-25 at 11 48 36 PM" src="https://github.com/user-attachments/assets/77248a29-aa38-4d7c-9833-496ec6a458b8" /> <img width="807" height="634" alt="Screenshot 2026-03-25 at 11 47 32 PM" src="https://github.com/user-attachments/assets/5af8b850-a466-489b-95a6-455b76b5050f" /> <img width="812" height="635" alt="Screenshot 2026-03-25 at 11 45 45 PM" src="https://github.com/user-attachments/assets/438074f0-8435-4274-a667-332efdd5cb57" /> <img width="801" height="623" alt="Screenshot 2026-03-25 at 11 43 56 PM" src="https://github.com/user-attachments/assets/0dc8d3f5-e8cf-4218-b4b4-a4f7d9bf02e3" /> --------- Co-authored-by: Michael Bolin <mbolin@openai.com>
viyatb-oai ·
2026-03-25 23:51:39 -07:00 -
Avoid duplicate auth refreshes in
getAuthStatus(#15798)I've seen several intermittent failures of `get_auth_status_returns_token_after_proactive_refresh_recovery` today. I investigated, and I found a couple of issues. First, `getAuthStatus(refreshToken=true)` could refresh twice in one request: once via `refresh_token_if_requested()` and again via the proactive refresh path inside `auth_manager.auth()`. In the permanent-failure case this produced an extra `/oauth/token` call and made the app-server auth tests flaky. Use `auth_cached()` after an explicit refresh request so the handler reuses the post-refresh auth state instead of immediately re-entering proactive refresh logic. Keep the existing proactive path for `refreshToken=false`. Second, serialize auth refresh attempts in `AuthManager` have a startup/request race. One proactive refresh could already be in flight while a `getAuthStatus(refreshToken=false)` request entered `auth().await`, causing a second `/oauth/token` call before the first failure or refresh result had been recorded. Guarding the refresh flow with a single async lock makes concurrent callers share one refresh result, which prevents duplicate refreshes and stabilizes the proactive-refresh auth tests.
Eric Traut ·
2026-03-25 16:03:53 -06:00 -
Extract codex-core-skills crate (#15749)
## Summary - move skill loading and management into codex-core-skills - leave codex-core with the thin integration layer and shared wiring ## Testing - CI --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-25 12:57:42 -07:00 -
Use AbsolutePathBuf for cwd state (#15710)
Migrate `cwd` and related session/config state to `AbsolutePathBuf` so downstream consumers consistently see absolute working directories. Add test-only `.abs()` helpers for `Path`, `PathBuf`, and `TempDir`, and update branch-local tests to use them instead of `AbsolutePathBuf::try_from(...)`. For the remaining TUI/app-server snapshot coverage that renders absolute cwd values, keep the snapshots unchanged and skip the Windows-only cases where the platform-specific absolute path layout differs.
pakrym-oai ·
2026-03-25 16:02:22 +00:00 -
[app-server] Add a method to override feature flags. (#15601)
- [x] Add a method to override feature flags globally and not just thread level.
Matthew Zeng ·
2026-03-25 02:27:00 +00:00 -
app-server: add filesystem watch support (#14533)
### Summary Add the v2 app-server filesystem watch RPCs and notifications, wire them through the message processor, and implement connection-scoped watches with notify-backed change delivery. This also updates the schema fixtures, app-server documentation, and the v2 integration coverage for watch and unwatch behavior. This allows clients to efficiently watch for filesystem updates, e.g. to react on branch changes. ### Testing - exercise watch lifecycles for directory changes, atomic file replacement, missing-file targets, and unwatch cleanup
Ruslan Nigmatullin ·
2026-03-24 15:52:13 -07:00 -
tui_app_server: cancel active login before Ctrl+C exit (#15673)
## Summary Fixes slow `Ctrl+C` exit from the ChatGPT browser-login screen in `tui_app_server`. ## Root cause Onboarding-level `Ctrl+C` quit bypassed the auth widget's cancel path. That let the active ChatGPT login keep running, and in-process app-server shutdown then waited on the stale login attempt before finishing. ## Changes - Extract a shared `cancel_active_attempt()` path in the auth widget - Use that path from onboarding-level `Ctrl+C` before exiting the TUI - Add focused tests for canceling browser-login and device-code attempts - Add app-server shutdown cleanup that explicitly drops any active login before draining background work
Eric Traut ·
2026-03-24 15:11:43 -06:00 -
Move git utilities into a dedicated crate (#15564)
- create `codex-git-utils` and move the shared git helpers into it with file moves preserved for diff readability - move the `GitInfo` helpers out of `core` so stacked rollout work can depend on the shared crate without carrying its own git info module --------- Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com> Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-24 13:26:23 -07:00 -
chore: stop app-server auth refresh storms after permanent token failure (#15530)
built from #14256. PR description from @etraut-openai: This PR addresses a hole in [PR 11802](https://github.com/openai/codex/pull/11802). The previous PR assumed that app server clients would respond to token refresh failures by presenting the user with an error ("you must log in again") and then not making further attempts to call network endpoints using the expired token. While they do present the user with this error, they don't prevent further attempts to call network endpoints and can repeatedly call `getAuthStatus(refreshToken=true)` resulting in many failed calls to the token refresh endpoint. There are three solutions I considered here: 1. Change the getAuthStatus app server call to return a null auth if the caller specified "refreshToken" on input and the refresh attempt fails. This will cause clients to immediately log out the user and return them to the log in screen. This is a really bad user experience. It's also a breaking change in the app server contract that could break third-party clients. 2. Augment the getAuthStatus app server call to return an additional field that indicates the state of "token could not be refreshed". This is a non-breaking change to the app server API, but it requires non-trivial changes for all clients to properly handle this new field properly. 3. Change the getAuthStatus implementation to handle the case where a token refresh fails by marking the AuthManager's in-memory access and refresh tokens as "poisoned" so it they are no longer used. This is the simplest fix that requires no client changes. I chose option 3. Here's Codex's explanation of this change: When an app-server client asks `getAuthStatus(refreshToken=true)`, we may try to refresh a stale ChatGPT access token. If that refresh fails permanently (for example `refresh_token_reused`, expired, or revoked), the old behavior was bad in two ways: 1. We kept the in-memory auth snapshot alive as if it were still usable. 2. Later auth checks could retry refresh again and again, creating a storm of doomed `/oauth/token` requests and repeatedly surfacing the same failure. This is especially painful for app-server clients because they poll auth status and can keep driving the refresh path without any real chance of recovery. This change makes permanent refresh failures terminal for the current managed auth snapshot without changing the app-server API contract. What changed: - `AuthManager` now poisons the current managed auth snapshot in memory after a permanent refresh failure, keyed to the unchanged `AuthDotJson`. - Once poisoned, later refresh attempts for that same snapshot fail fast locally without calling the auth service again. - The poison is cleared automatically when auth materially changes, such as a new login, logout, or reload of different auth state from storage. - `getAuthStatus(includeToken=true)` now omits `authToken` after a permanent refresh failure instead of handing out the stale cached bearer token. This keeps the current auth method visible to clients, avoids forcing an immediate logout flow, and stops repeated refresh attempts for credentials that cannot recover. --------- Co-authored-by: Eric Traut <etraut@openai.com>
Celia Chen ·
2026-03-24 12:39:58 -07:00 -
xl-openai ·
2026-03-24 11:47:23 -07:00 -
app-server: Add back pressure and batching to
command/exec(#15547)* Add `OutgoingMessageSender::send_server_notification_to_connection_and_wait` which returns only once message is written to websocket (or failed to do so) * Use this mechanism to apply back pressure to stdout/stderr streams of processes spawned by `command/exec`, to limit them to at most one message in-memory at a time * Use back pressure signal to also batch smaller chunks into ≈64KiB ones This should make commands execution more robust over high-latency/low-throughput networks
Ruslan Nigmatullin ·
2026-03-24 11:35:51 -07:00 -
Finish moving codex exec to app-server (#15424)
This PR completes the conversion of non-interactive `codex exec` to use app server rather than directly using core events and methods. ### Summary - move `codex-exec` off exec-owned `AuthManager` and `ThreadManager` state - route exec bootstrap, resume, and auth refresh through existing app-server paths - replace legacy `codex/event/*` decoding in exec with typed app-server notification handling - update human and JSONL exec output adapters to translate existing app-server notifications only - clean up "app server client" layer by eliminating support for legacy notifications; this is no longer needed - remove exposure of `authManager` and `threadManager` from "app server client" layer ### Testing - `exec` has pretty extensive unit and integration tests already, and these all pass - In addition, I asked Codex to put together a comprehensive manual set of tests to cover all of the `codex exec` functionality (including command-line options), and it successfully generated and ran these tests
Eric Traut ·
2026-03-24 08:51:32 -06:00