Commit Graph
1592 Commits
Author SHA1 Message Date
Bryan Ashley 8604689ec5 Allow injecting the Codex Apps tools cache (#33113)
## What changed

- Accept a caller-provided `CodexAppsToolsCache` when constructing a `ThreadManager` and pass it through to the MCP manager.
- Add `ConnectorRuntimeManager::new_without_cache()` for an in-memory runtime that neither loads nor persists connector state on disk.
- Re-export `CodexAppsToolsCache` from `codex-core` and `codex-core-api` for embedders.

## Testing

- Verify that a cache-disabled connector runtime ignores existing disk state and publishes live tools without creating cache files.

GitOrigin-RevId: f52f4f27c425a8d84ad0d0987b30a6fc3c14d702
2026-07-14 17:10:04 +00:00
jif 4aa950d456 Use session IDs for prompt cache keys (#33035)
## What changed

- Default `prompt_cache_key` to the session ID from response metadata instead of the thread ID.
- Preserve explicit prompt cache key overrides.
- Verify that API-key-authenticated root and subagent requests use the same session-based cache key even though they have different thread IDs.

GitOrigin-RevId: cb1bf21a3cb8fa2c5083c5c6afd4829ff2adcf1f
2026-07-14 10:37:23 +00:00
pakrym-oai 393f64565a Scope runtime workspace roots to execution environments (#32952)
## Why

Multi-environment turns can run against different filesystems, so a single
thread-wide workspace-root list cannot accurately describe every selected
environment.

## What changed

- Add optional `runtimeWorkspaceRoots` to each app-server environment selection.
  Omitted roots default to that environment's `cwd`, while an empty list selects
  no roots.
- Carry environment-native roots through turn selection, model-visible context,
  permission materialization, and tool sandboxing.
- Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when
  constructing default environment selections; explicit selections use their
  own roots.

## Testing

- Cover thread and turn API defaults, overrides, empty roots, and schema
  round-tripping.
- Verify foreign roots remain model-visible and remote execution applies the
  target environment's roots before sandbox selection.

GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
2026-07-14 04:41:08 +00:00
richardopenai 80c6cd3014 Allow injecting the models manager into ThreadManager (#32911)
## Why

Embedding callers need to control whether model catalogs are persisted to disk.

## What changed

- Accept a shared models manager when constructing `ThreadManager` instead of always creating a cached manager internally.
- Add provider APIs for creating uncached model managers. OpenAI-compatible providers fetch on each `OnlineIfUncached` refresh without reading or writing `models_cache.json`.
- Keep existing app server, MCP server, sample, and test callers on the standard cached manager.

## Testing

- Verify an uncached manager fetches on every refresh.
- Verify an injected uncached manager controls thread refresh behavior and does not create `models_cache.json`.

GitOrigin-RevId: 8bb646054ecec4ccb865b2bf56249384916ea9db
2026-07-14 01:06:11 +00:00
Dylan Hurd 090f4de37b Route blocked network requests to their owning calls (#32897)
## Why

Policy-blocked proxy requests must terminate the corresponding active tool call and preserve the correct approval result, including when multiple calls are running concurrently.

## What changed

- Resolve a blocked request's execution ID to its registered active network call before recording the policy denial.
- Preserve an outcome already recorded for that call, and cancel the owning call after storing a new denial.

## Testing

Expand network approval integration coverage for Guardian and user decisions, permission hooks, persisted policy amendments, concurrent calls, timeouts, cancellations, and unattributed proxy requests.

GitOrigin-RevId: 961901bbc07cc498309453ec78cda1a56ab00a4b
2026-07-13 23:33:58 +00:00
Celia Chen 0877afbe85 Broaden remote compaction model fallback (#32881)
## Why

Compacting a resumed conversation can fail when its previous model is no longer
available. Some model-specific failures, such as a model-not-found response, are
not represented as invalid requests and therefore did not trigger the existing
fallback to the currently selected model.

## What changed

- Share a retry predicate between both remote compaction implementations.
- Fall back to the current model for invalid requests, unexpected statuses,
  context-window and usage-limit errors, server failures, and exhausted retries.

## Testing

Add an integration test that resumes a conversation whose previous model returns
model-not-found and verifies that compaction and the next turn use the renamed
model.

GitOrigin-RevId: c3857beae2ce79b50589deb13c2e59710ce14725
2026-07-13 21:54:04 +00:00
rhan-oai 60b9b551c1 Use model catalog policies for Guardian auto review (#32875)
## What changed

- Add an `auto_review.policy` field to model catalog messages.
- Use the selected Guardian model's catalog policy for review-session instructions, while preserving the precedence of `guardian_policy_config` and falling back to the built-in policy when neither is present.
- Preserve auto-review messages when model instruction overrides remove catalog instruction templates.

## Testing

- Cover configured-policy precedence, explicit empty catalog policies, catalog-message preservation, and propagation of the catalog policy into a prewarmed Guardian session.

GitOrigin-RevId: 26b61ae2958ea8325a64834dcf91f47e140d74b3
2026-07-13 21:25:28 +00:00
iceweasel-oai abbb8c569c Require the elevated Windows sandbox for network proxies (#32857)
## Why

Network proxy enforcement on Windows requires the elevated sandbox backend. Silently selecting that backend for an unelevated configuration makes the effective sandbox differ from the configured mode.

## What changed

- Reject enabled network proxy configurations on Windows unless managed requirements allow only the elevated sandbox and `windows.sandbox` resolves to `"elevated"`.
- Preserve the configured sandbox backend during execution and validate proxy compatibility at config loading, sandbox setup, and process launch boundaries.
- Defer this validation during cloud-config bootstrap so authoritative managed requirements can be loaded first.
- Do not start or expose disabled Windows proxies, and render transitions to disabled networking as `<network enabled="false"></network>`.

## Testing

- Cover Windows requirement and sandbox compatibility matrices, bootstrap behavior, backend selection, disabled proxy handling, and environment-context updates.

GitOrigin-RevId: bfa1dda98594e0db61883f8e7f65bd560e3453e6
2026-07-13 19:04:22 +00:00
jif 088239294a Restore V2 agent identities on root thread resume (#32837)
## Why

After a cold resume, a Multi-Agent V2 root thread must still be able to
address its persisted descendants even though their runtimes are not reopened
eagerly.

## What changed

- Restore metadata for open descendant agents when resuming a V2 root thread.
- Preserve each descendant's path, nickname, and role while leaving its runtime
  unloaded until a message targets it.
- Reuse the spawn metadata preparation path so restored identities retain the
  same reservation and naming checks as newly spawned agents.

## Testing

Added an end-to-end cold-resume test that follows up with a persisted agent by
name and verifies that the original agent thread is loaded on demand.

GitOrigin-RevId: a1663c1ae60eefadb948cd39f933cd3bbb49a492
2026-07-13 17:24:10 +00:00
jif 2e156cbe31 Avoid blocking thread startup on MCP OAuth discovery (#32825)
## Why

OAuth metadata discovery for an optional HTTP MCP server can stall, delaying
`thread/start` even though that server is not required.

## What changed

- Remove eager MCP authentication-status discovery from session and connection
  manager startup.
- When an MCP connection reports an authentication error, inspect configured and
  stored credentials locally to preserve login and reauthentication failure
  reasons without making another discovery request.
- Continue using server configuration directly for startup error messages and
  timeout hints.

## Testing

Add an app-server regression test with an optional HTTP MCP endpoint that accepts
a connection but never responds, and verify that `thread/start` completes without
waiting for its configured startup timeout.

GitOrigin-RevId: 56fe0188cc1ceaf746b0b65e8b7dd1fd2e13420d
2026-07-13 15:47:03 +00:00
jif 4ebc61c0f8 Make explicit multi-agent mode override proactive delegation (#32822)
## Why

After switching from proactive delegation to explicit-request-only mode, an
earlier proactive instruction can remain in the conversation context. The new
mode must clearly supersede that instruction.

## What changed

Update the explicit-request-only developer message to cancel earlier proactive
delegation instructions before requiring delegation to be explicitly requested
by the user, `AGENTS.md`, or a skill.

## Testing

Update the multi-agent mode integration test expectation for the explicit-mode
instruction emitted after a cold resume.

GitOrigin-RevId: 0a6d18f38ef82d29cf4f3bfcfd4ac84738a39598
2026-07-13 15:39:24 +00:00
Owen Lin 5c19155cbd Add ordinals to paginated rollout records (#32332)
## Why

Paginated thread history needs durable ordering so consumers can process a rollout suffix without rebuilding all earlier history.

## What changed

- Add optional, zero-based ordinals to `RolloutLine` records in paginated rollouts while leaving legacy rollout serialization unchanged.
- Continue ordinals from the last valid record when appending or resuming, including after gaps or an incomplete tail, and reject overflow without appending.
- Add a stateless `project_rollout_line` helper that maps canonical turn lifecycle and completed-item records into thread-history change sets.

## Testing

- Cover ordinal assignment, legacy compatibility, resume and tail recovery, overflow handling, and thread-history projection for completed, failed, and interrupted turns.

GitOrigin-RevId: 3a9bb6cd2a1f674a9f154342e96e9aa3d8330781
2026-07-11 04:15:42 +00:00
pakrym-oai c9d52de5ca Require prefixes for outbound response item IDs (#32312)
## What changed

- Add a `ResponseItemId` type that generates item-specific prefixes with UUIDv7 suffixes and use it across response items.
- Keep deserialization permissive for legacy histories, but omit empty or unprefixed item IDs from HTTP and WebSocket requests.
- Export the new type in the generated TypeScript protocol schema.

## Testing

- Cover prefixed ID generation, legacy deserialization, prefix recognition, and outbound request filtering.

GitOrigin-RevId: 0209fe430c826d0ae88bc4648652c4ebf390c4a4
2026-07-11 02:29:14 +00:00
Felipe Coury dffe1f02a3 Respect model support for reasoning summaries (#32290)
## What changed

- Add `supports_reasoning_summary_parameter` to model metadata, defaulting to
  `true` for backward compatibility.
- Omit `reasoning.summary` and its summary-delivery stream option when the
  selected model does not support the parameter.
- Apply the capability of the final selected model when a spawned agent uses a
  different model.

## Testing

- Cover unsupported models in regular requests and spawned-agent model
  overrides.

GitOrigin-RevId: 72b783799fc0685cef1501ef2dbf62d1308ceead
2026-07-10 23:39:21 +00:00
Owen Lin c4318c386d Include terminal errors in turn completion events (#32280)
## What changed

- Add an optional `error` payload to `TurnCompleteEvent` and omit it when a turn completes without an error.
- Preserve the full terminal `ErrorEvent` through the turn lifecycle so the completion event includes the same error details emitted separately by `EventMsg::Error`.

## Testing

- Extend the stream-error integration test to verify that `TurnCompleteEvent` contains the emitted error and that the next turn can still proceed.

GitOrigin-RevId: 8d32942a44132763076130102d8b89ab356d59d0
2026-07-10 22:04:03 +00:00
rhan-oai 09ccae2c07 Honor personality = "none" in model instructions (#32277)
## Why

Model catalog instructions can include a baked-in `# Personality` section. An
explicit `none` setting should omit that section instead of sending it as part
of the model's base instructions.

## What changed

- Pass the configured personality into the models manager.
- When personality support is enabled and the setting is explicitly `none`,
  remove the `# Personality` section through the next level-one heading from
  catalog base instructions and instruction templates.
- Preserve explicit `base_instructions` overrides and avoid warning when no
  personality was requested.

## Testing

Added unit and integration coverage for section removal, heading boundaries,
CRLF input, preserved configurations, and explicit base instructions.

GitOrigin-RevId: 452c88d3ac6001c2ac7d4fef269cd75dc239fa61
2026-07-10 21:39:56 +00:00
Dylan Hurd c0ea3c4d0a Remove the personality migration (#32274)
## What changed

- Stop the TUI and app server from inspecting existing sessions at startup to
  set `personality = "pragmatic"` automatically.
- Remove the migration marker, helper APIs, and associated tests.

GitOrigin-RevId: 9e963bf113aff21651696bbc463f2749ac0f510a
2026-07-10 21:24:03 +00:00
Owen Lin bca577d69a Include start times in terminal turn events (#32263)
## What changed

- Add an optional `started_at` Unix timestamp to `TurnCompleteEvent` and
  `TurnAbortedEvent`.
- Populate the timestamp from turn timing state when a turn completes or is
  aborted.
- Preserve the timestamp when synthesizing interrupted fork history and when
  importing external sessions.

## Testing

- Verify that interrupting a turn emits a `TurnAbortedEvent` with a start
  timestamp.

GitOrigin-RevId: 75b3911b95c060e5fc1843a5e293d8fe47377186
2026-07-10 20:25:03 +00:00
Tom 9993fb838a Improve Responses WebSocket timing telemetry (#32256)
## What changed

- Emit `responsesapi.websocket_timing` payloads as opt-in trace events with request context, while excluding them from diagnostic uploads and persisted logs by default.
- Preserve fractional-millisecond TBT values in telemetry histograms and runtime summaries, rounding only when formatting the TUI label.

## Testing

- Cover timing-log filtering, fractional TBT collection and display, and existing whole-millisecond duration behavior.

GitOrigin-RevId: 5f0a1c60c237abed17cc8b2d569ca77fbbc6ec41
2026-07-10 20:01:47 +00:00
Dylan Hurd 2da1b12822 Let permission hooks resolve strict auto-review requests (#32232)
## What changed

- Run permission-request hooks before routing approvals to the automated reviewer or user, including when `strict_auto_review` is enabled.
- Centralize approval resolution so hook, automated-reviewer, and user decisions share rejection handling and report the correct telemetry source.

## Testing

- Add an integration test showing that an allow hook can approve a shell command during strict auto-review without invoking the automated reviewer.

GitOrigin-RevId: 18e9d76baee6cbae9d35ae517250f2f82270a9d2
2026-07-10 18:12:27 +00:00
pakrym-oai 4472698728 Support pending remote environment registration (#32231)
## Why

Remote environment provisioning can finish after a thread starts, before an
exec-server WebSocket URL is available.

## What changed

- Add `EnvironmentManager::register_pending_environment` and a one-shot
  `PendingEnvironmentRegistration` handle that resolves to either a validated
  WebSocket URL or a terminal provisioning error.
- Let lazy remote exec-server clients wait for that result, while preserving
  reconnection behavior after a successful registration.
- Keep replacement registrations isolated so completing an older handle does
  not resolve the current environment with the same ID.

## Testing

Add coverage for successful connection and reconnection, provisioning and
dropped-registration failures, invalid URLs, replacement isolation, and the
deferred-executor startup flow.

GitOrigin-RevId: 5c05be2b72291b77a1f71176d7075b1ad63332a5
2026-07-10 18:08:35 +00:00
pakrym-oai c8dc8e5fd5 Propagate workspace roots to exec-server sandboxes (#32214)
## What changed

- Pass configured workspace roots from core to the exec server so filesystem and process sandbox permissions are materialized against the intended roots.
- Preserve an explicitly empty workspace-root list instead of treating the sandbox working directory as an implicit root.
- Initialize filesystem sandbox contexts with their working directory as the default workspace root.

## Testing

- Add end-to-end coverage for patch and command writes inside and outside workspace roots.
- Verify remote filesystem and process sandboxes do not grant access through an empty workspace-root list.

GitOrigin-RevId: 6684c8f7de50970b45a29e2a6323df954c96f9f6
2026-07-10 16:55:01 +00:00
pakrym-oai d2d00b6632 Always send reasoning parameters in Responses requests (#32206)
## What changed

- Build a reasoning payload for every Responses request and always include `reasoning.encrypted_content`.
- Remove `supports_reasoning_summaries` from model metadata and retire the `model_supports_reasoning_summaries` configuration override.
- Use configured or model-default reasoning effort without a capability gate, including for guardian reviews and tracing.

GitOrigin-RevId: 2c9f194a5d2d4d688a2235299e6358f82ab8e1ea
2026-07-10 16:11:58 +00:00
jif 6138909d6e Keep unified exec output collection bounded (#32150)
## Why

Unified exec can drain process output multiple times while waiting for a command. Collecting those drains into an uncapped buffer allows large commands to exceed the output collection limit.

## What changed

- Accumulate drained output through the capped head/tail buffer so collection remains bounded while preserving the beginning and end of the stream.
- Include a `... N bytes omitted ...` marker when the collection cap drops output.
- Calculate the original token estimate from all observed bytes and preserve omission metadata through truncation and sandbox-denial responses.

## Testing

- Cover repeated drains, previously omitted output, omission markers, and large-output summaries.

GitOrigin-RevId: c6e2efeb875ed8f35914365eab7431f25fd3484c
2026-07-10 12:22:04 +00:00
Channing Conger 8cf9a1b1f8 code-mode: fall back to using in process v8 if we fail to resolve external process (#31899)
## Why

Not every Codex distribution currently includes the
`codex-code-mode-host` companion binary. Enabling the process-host
feature should not make code mode unavailable on those surfaces while
packaging support is being completed.

## What changed

- Fall back to an in-process code-mode session only when spawning the
companion binary returns `io::ErrorKind::NotFound`.
- Keep permission, handshake, timeout, and other host failures visible
instead of silently falling back.
- Store the provider's owned-process/in-process choice as one
enum-backed state so later sessions reuse the fallback decision.
- Preserve the underlying spawn `io::Error` while retaining the host
path in the displayed error.
- Update provider, `CodeModeService`, and end-to-end coverage to verify
successful fallback execution.

## Test plan

- `just test -p codex-code-mode`
- `just test -p codex-core missing_process_host`
2026-07-09 14:40:10 -07:00
thomas 8347b8de21 [codex-apps] Filter optional file fields by tool schema (#31686)
## Summary

Codex Apps file parameters are exposed to the model as local paths,
uploaded at execution time, and rewritten into provided-file payloads
before the MCP tool call.

The rewrite currently includes the documented optional fields
`mime_type` and `file_name` for every file parameter. Apps with strict
schemas can reject those fields when they are not declared.

## Changes

- Derive the supported optional file fields from each
`openai/fileParams` parameter's raw input schema before replacing it
with the model-visible local-path schema.
- Always include `download_url` and `file_id`.
- Include `mime_type` and `file_name` only when that specific file
parameter's schema accepts them, including schemas that allow additional
properties.
- Handle scalar and array file parameters, including items-only arrays,
composed schemas, and local JSON Schema references.
- Preserve the existing restriction that only the host-owned Codex Apps
MCP server can use this upload path.

This supports tools with different file contracts in the same app: one
parameter can accept the optional fields while another remains strict.

## Validation

- `just test -p codex-mcp`
- `just test -p codex-core mcp_openai_file`
- `just test -p codex-core codex_apps_file_params_`
- `just fix -p codex-mcp`
- `just fix -p codex-core`
- `just fmt`
- `git diff --check`
- Manually verified in the Codex Electron app that:
  - a strict file schema receives only `download_url` and `file_id`
  - a rich file schema also receives `mime_type` and `file_name`

Related: #31330
2026-07-09 14:32:23 -07:00
raquel-openai b58952b0fa fix: forward originator to Codex Apps MCP (#31481)
## Summary
- Forward Codexs canonical `originator` header on ChatGPT-hosted Apps
and plugin-runtime MCP requests.
- Preserve the configured `X-OpenAI-Product-Sku` header.
- Cover originator-only and originator-plus-SKU configurations.

## Why
Sites project creation is logged downstream of Apps MCP. Production
validation found `CODEX_UNKNOWN_DEFAULT` project-created threads that
matched `codex_surface=desktop_app` and `originator=Codex Desktop` in
`fact_codex_cli`
([query](https://kepler.gateway.data-1.internal.api.openai.org/permalink/H_mVoVPqLQ0)).

The hosted Apps MCP configuration forwarded the product SKU but not
Codexs canonical originator, so codex-backend could not derive
`CODEX_DESKTOP_APP` for those tool calls.

## Validation
- `just fmt`
- `CARGO_HOME=/private/tmp/codex-cargo-home
CARGO_TARGET_DIR=/private/tmp/codex-target just test -p codex-mcp` (106
passed)
- `CARGO_HOME=/private/tmp/codex-cargo-home
CARGO_TARGET_DIR=/private/tmp/codex-target just fix -p codex-mcp`
2026-07-09 16:51:44 +00:00
sayan-oai a6b99ee5c4 code-mode: retain shared MCP types for deferred tools (#31745)
## Why

When MCP tools are deferred behind `tool_search`, Code mode keeps them
callable but omits their individual declarations from the initial `exec`
description. The shared MCP `CallToolResult` types were derived only
from directly rendered tools, so deferring every MCP tool also removed
the common response contract that models need to interpret MCP results.

This restores that contract without undoing the context savings from
deferred tool definitions. This is a follow-up to #29486.

## What changed

- Track deferred Code-mode tool definitions separately from directly
rendered definitions.
- Render the shared MCP type preamble when either direct or deferred MCP
tools are available.
- Keep deferred tool declarations out of the initial prompt.
- Add unit and integration coverage for deferred MCP tools.

## Testing

- `just test -p codex-code-mode-protocol`
- `just test -p codex-core
code_mode_only_guides_all_tools_search_and_calls_deferred_app_tools`
2026-07-09 08:17:13 -07:00
jif e8eb60092a perf(skills): reuse walk inventory for host loading (#31566)
## Why

CCA thread startup loads repository skills through the primary remote
environment. This still used the older host skill loader, which
recursively issued directory and metadata requests over the exec-server
connection. On a high-latency connection, one skill scan could turn into
hundreds of round trips.

Executor-selected skill roots already avoid this pattern: they use one
bounded filesystem walk, reuse the returned inventory, and overlap
independent reads.

## What changed

- Extract the URI-native walk inventory into a shared private discovery
module.
- Use that discovery path for both environment-owned and host/repository
skill roots.
- Reuse the walk inventory to avoid per-skill metadata existence checks
when the inventory is complete.
- Canonicalize host skill identities and parse skill files with bounded
concurrency.
- Prune hidden host directories during traversal, preserving visible
aliases and walk limits.
- Cache namespace probes by ancestor and keep all remote namespace reads
under the same concurrency bound.
- Keep safe metadata probes for incomplete walks, file symlinks, and
case aliases.

## Dependency

#31570 is now merged. It provides the optional `pruneHiddenDirectories`
walk flag used here. That flag defaults to false and is omitted when
disabled.

No other exec-server API changes are introduced.
2026-07-09 09:54:24 +01:00
3380969a29 Update models.json (#31684)
Automated update of models.json.

---------

Co-authored-by: sayan-oai <244841968+sayan-oai@users.noreply.github.com>
Co-authored-by: sayan-oai <sayan@openai.com>
2026-07-09 03:40:08 +00:00
Won Park a7c72aee8b Use the image generation extension by default (#31596) 2026-07-09 12:25:19 +09:00
Owen Lin 2342b2c2a6 feat(rollout): persist TurnItems for paginated thread rollouts (#30188)
## Description

This PR makes new threads with `history_mode = "paginated"` persist
`ItemCompleted(item: <turn_item>)` in their rollout JSONL file.

Legacy threads keep persisting the existing legacy events. Because the
format is selected per thread, a rollout is either legacy or paginated;
we do not need to support mixed rollouts containing both
representations.

This PR depends on [#31473](https://github.com/openai/codex/pull/31473).

## Why

Paginated thread history needs stable turn/item IDs and completed item
snapshots so the later SQLite projector can materialize appended rollout
JSONL without rebuilding the whole thread.

Keeping the legacy persistence policy unchanged avoids changing
historical rollouts or the readers that still consume them.

## What changed

- Made rollout filtering history-mode aware. Paginated threads keep
completed canonical `ItemCompleted` events and drop their redundant
legacy projections; legacy threads keep the existing event set.
- Made forks inherit the source thread history mode, so copied legacy
history is never filtered as paginated.
- Made paginated threads assign IDs to locally-created response items
even when `Feature::ItemIds` is off, and reject streamed output items
that arrive without server IDs.
- Updated legacy turn replay, rollout list/search, and SQLite metadata
extraction to understand completed canonical user-message items.
2026-07-08 19:55:03 -07:00
Michael Bolin 5892c7b69d model-provider: route model discovery through HTTP client factory (#31361) 2026-07-09 02:32:10 +00:00
stevenlee-oai 555aa79d5a [connectors] Refresh codex_apps /ps/mcp auth (#31486)
[Codex Thread
019f2408-dc59-79f2-b245-4c11debd1a61](https://codex-thread-link.openai.chatgpt-team.site/thread/019f2408-dc59-79f2-b245-4c11debd1a61)

## Why

Long-lived Codex sessions can outlive the ChatGPT bearer token that was
present when the MCP runtime started.

The Responses path already recovers from token expiration by refreshing
or reloading the shared `AuthManager`. The reserved `codex_apps`
hosted-plugin client did not observe that update: `McpConnectionManager`
built its `/ps/mcp` HTTP auth once from a `CodexAuth` snapshot, and
`auth_provider_from_auth` copied that snapshot bearer into a static
`BearerAuthProvider`.

After the copied bearer expired, `/ps/mcp` kept sending it even though
Responses had a newer token in the same `AuthManager`. The failure
occurred before downstream connector execution, so unrelated apps such
as Gmail, Slack, and Google Calendar could all fail with the same
transport-level `401 token_expired`.

This replaces
[openai/codex#29474](https://github.com/openai/codex/pull/29474), which
was closed for inactivity without being merged. A new long-lived-session
report reproduced the same simultaneous `/ps/mcp` expiry pattern across
unrelated apps.

## What changed

- Add an `AuthManager`-backed request-header provider in
`codex-model-provider`. It keeps an `Arc<AuthManager>` and reads
`auth_cached()` for each outbound request, so the next `/ps/mcp` call
sees a token refreshed by the existing Responses/auth-recovery flow.
- Scope that provider to the startup account, ChatGPT user, and
workspace identity. Same-identity token reloads are followed; an account
switch emits no ambient auth until account-scoped MCP state is rebuilt.
- Have `McpConnectionManager` construct the dynamic provider only for
the reserved `codex_apps` registration used by the hosted-plugin
`/ps/mcp` path.

| MCP path | Auth behavior after this change |
| --- | --- |
| Reserved `codex_apps` hosted-plugin `/ps/mcp` | Read current
same-identity auth from the shared `AuthManager` per request |
| `codex_apps` with `CODEX_CONNECTORS_TOKEN` | Keep the environment
bearer-token override |
| User-configured/direct MCP registrations | Keep their existing
configured auth path |

## Non-goals

- No plugin-service changes.
- No downstream Slack, Gmail, Calendar, or other connector
OAuth/link-refresh changes.
- No auth UI changes.
- No behavior change for user-configured/direct MCP registrations.
- No new `/ps/mcp`-initiated token refresh; this makes `/ps/mcp` observe
refreshes already performed through the shared `AuthManager`.

## Tests

- `just test -p codex-model-provider`
- Covers same-identity token reloads and refuses a changed startup
identity.
- `just test -p codex-mcp`
- `just test -p codex-core mcp_auth_refresh`
- Creates the reserved hosted-plugin `codex_apps` `/ps/mcp` client
before the shared `AuthManager` changes, updates that same manager
through its public external-auth path, performs a real `tools/call`, and
asserts the request uses the current bearer.
2026-07-08 21:46:11 -04:00
viyatb-oai 0746e8a345 [codex] Preserve reviewer when resuming threads (#30278)
## Why

A thread resumed without an explicit reviewer could pick up the reviewer
from the current config instead of preserving the reviewer already in
use by the thread. After an app restart, this meant a thread running
with auto review could silently switch back to user review, and the next
turn could continue under the wrong reviewer.

## What changed

Persist the effective reviewer with each turn and restore the latest
persisted value when the thread resumes. If the resume request
explicitly provides a reviewer, that value still takes precedence.

## Test plan

- Added a regression test that starts a thread with auto review, records
a turn, restarts with user review in config, resumes without an
override, and verifies that auto review is preserved.
- `just test -p codex-protocol`
- `just test -p codex-state`
- `just test -p codex-rollout`
- `just test -p codex-app-server
thread_resume_preserves_persisted_approvals_reviewer`
- Clippy for the affected crates
2026-07-09 00:58:28 +00:00
Adam Perry @ OpenAI 3fa90665fe test: add delayed exec-server transport (#31427)
## Why

Macrobenchmarks benefit from having a way to exercise remote-executor
latency without depending on Docker.

This is a very minimal first cut, if we find that simulating network
conditions is useful we can always expand this scope or switch to a more
robust network shaping approach.

## What

- add a package-local exec-server binary for Cargo and Bazel test
fixtures
- add a host-local WebSocket exec-server fixture and fixed-delay
interposer
- let TestAppServer route its auto environment through that delayed
WebSocket transport
- cover the delayed thread/start path through the public app-server API

## Stack

1. [#31425 test: add TestAppServer
builder](https://github.com/openai/codex/pull/31425)
2. [#31427 test: add delayed exec-server
transport](https://github.com/openai/codex/pull/31427)
3. [#31295 bench: add cold skill load
macrobenchmark](https://github.com/openai/codex/pull/31295)
4. [#31428 bench: add e2e benchmark
entrypoints](https://github.com/openai/codex/pull/31428)
5. [#31429 ci: smoke Bazel e2e
benchmarks](https://github.com/openai/codex/pull/31429)
2026-07-09 00:17:38 +00:00
b780738014 Update models.json (#21818)
Automated update of models.json.

---------

Co-authored-by: aibrahim-oai <219906144+aibrahim-oai@users.noreply.github.com>
Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
Co-authored-by: Sayan Sisodiya <sayan@openai.com>
2026-07-08 16:24:12 -07:00
jacobzhou-oai a09a7c41d8 [codex-apps] Omit internal fields from file payloads (#31330)
## Summary

Codex Apps file parameters are exposed to the model as local paths,
uploaded at execution time, and rewritten into provided-file payloads
before the MCP tool call.

The rewrite currently forwards two internal upload fields, `uri` and
`file_size_bytes`, even though they are not part of the documented app
file-reference shape. Strict app schemas can reject those extra fields
before execution.

## Changes

- Stop copying `uri` and `file_size_bytes` into app-facing MCP
arguments.
- Keep the internal `UploadedOpenAiFile` result unchanged.
- Preserve the existing `download_url`, `file_id`, `mime_type`, and
`file_name` behavior for scalar and array file inputs.
- Verify the MCP invocation and post-tool hook receive exactly the
documented four-field payload against an `additionalProperties: false`
schema.

This intentionally does not add schema inspection or change how
`openai/fileParams` names are discovered.

## Validation

- `just test -p codex-core mcp_openai_file` (6 passed)
- `just test -p codex-core codex_apps_file_params_` (2 passed)
- `just fix -p codex-core`
- `just fmt`
- `git diff --check`
2026-07-08 16:04:30 -07:00
Channing Conger c55cb4b363 code-mode: make all approvals trigger elicitation pause (#31650)
### summary

We want to pause code-mode from yielding back to the model when a
subcommand triggers an approval prompt. This means that all of these
previously inline blocking requests should also take out a
ElicitationService registration.

This also does some plumbing refactoring to request patch approval to
make it match the other `request_*_approval` methods in that it blocks
on the approval in the function instead of returning the oneshot
channel, this affords our ability to encapsulate the ElicitationService
registration via RAII.

Adds tests to confirm the blocking behavior for code_mode both in suite
tests and that the session holds them.
2026-07-08 15:27:04 -07:00
Michael Bolin e621d7df8c core: preserve Responses WebSockets with system proxy (#31441)
## Why

Responses WebSockets are the normal lower-latency transport for
WebSocket-capable providers. They must not bypass an OS-selected proxy
when `features.respect_system_proxy` is enabled, but disabling
WebSockets whenever the feature is enabled would impose a substantial
performance penalty.

Merged PR #31622 introduced the reusable proxy-aware WebSocket
transport. This PR makes the Responses API its first consumer so the
existing fast path uses the same effective proxy and trust policy as
HTTP.

## What changed

- Register `codex-websocket-client` as a workspace dependency and use it
from `codex-api`.
- Feed the shared crate’s route-independent `WebSocketConnection` into
the existing Responses message pump.
- Require a configured `HttpClientFactory` for normal Responses
WebSocket connections and the CLI doctor probe, so neither path can open
a connection without consulting the effective proxy policy.
- Pass the session factory from `core` and the effective configuration
factory from `doctor`.
- Add an end-to-end Responses test that enables `RespectSystemProxy`,
asserts the resolved policy, completes a turn over WebSocket, and
verifies the connection and request counts.
- Keep the existing Responses protocol handling, ping/pong pump, and
session-scoped HTTP fallback unchanged.

The DNS, proxy, TLS, custom-CA, and Happy Eyeballs implementation and
its transport tests live in merged PR #31622. This PR deliberately
contains only the Responses integration and does not duplicate that
transport code.

## Review guide

1. `codex-rs/codex-api/src/endpoint/responses_websocket.rs` constructs
the shared connector and adapts its uniform stream to the existing pump.
2. `codex-rs/core/src/client.rs` supplies the session-scoped factory for
production Responses connections.
3. `codex-rs/cli/src/doctor.rs` supplies the effective configuration
factory to the handshake probe.
4. `codex-rs/core/tests/suite/client_websockets.rs` covers the
enabled-feature path end to end.

## Test plan

- `cargo check --tests -p codex-api -p codex-core -p codex-cli`
- `just test -p codex-api`
- `just test -p codex-core
responses_websocket_streams_with_system_proxy_feature`
- `cargo shear`
- `just bazel-lock-check`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/31441).
* #31637
* #31431
* #31363
* #31362
* #31361
* __->__ #31441
2026-07-08 14:06:15 -07:00
Channing Conger 9c6715924b code-mode: move to hosted mode by default (#31500)
## Summary

  - Promote code_mode_host to stable and enable it by default.
- Preserve features.code_mode_host = false as an opt-out to the
in-process runtime.
  - Run core code-mode tests through the standalone host.
  - Keep explicit coverage for missing-host failures.
2026-07-08 11:06:58 -07:00
Owen Lin 23aac925e7 feat(core): emit canonical review mode items (#31473)
## Description

This PR moves review-mode markers onto canonical `TurnItem` lifecycle:

- `TurnItem::EnteredReviewMode`
- `TurnItem::ExitedReviewMode`

Core now emits `ItemStarted` / `ItemCompleted` for both. The completed
items map back into the existing `EnteredReviewMode` /
`ExitedReviewMode` events, so raw core event consumers and legacy
rollout persistence keep seeing the old events.

This is the compatibility layer needed before paginated rollouts persist
review markers as `ItemCompleted(TurnItem)`.

## Why

Review markers were one of the remaining app-server thread items created
directly from legacy events. Giving them canonical items lets paginated
history persist stable turn/item IDs without changing legacy rollouts.

## What changed

- Added canonical review-mode `TurnItem`s and switched review flow to
emit their lifecycle.
- Added completed-item → legacy review event mappings with stable
turn/item IDs.
- Switched app-server live notifications to the generic canonical item
path and kept legacy replay compatible with old payloads.
- Updated `ThreadHistoryBuilder` to replay canonical review items even
though review turns still do not emit `TurnStarted`.
2026-07-08 09:59:50 -07:00
jif 0bbea86a6a Stabilize shared rollout budget test (#31587)
## Why

`subagent_usage_draws_from_the_shared_budget` intermittently fails even
when the shared-budget behavior is correct. `ResponseMock` records a
request before the custom Wiremock predicate is checked, so the
follow-up mock can also contain unrelated requests. In a [recent Windows
ARM64 run](https://github.com/openai/codex/actions/runs/28916285431),
`single_request()` saw all seven requests from the scenario.

## What changed

Select the request containing the follow-up user prompt before making
assertions. The test still requires exactly one matching follow-up
request and still checks that the root sees 50 tokens remaining after
the child uses its share.

This is test-only. Shared-budget behavior and the common response-mock
helper are unchanged.
2026-07-08 16:10:28 +01:00
jif f17a57b7d5 Stabilize remote compaction parity against dynamic skill catalogs (#31585)
## Why

The remote compaction parity test compares legacy and v2 sessions
created with separate temporary homes. Those sessions can discover
different model-visible skill catalogs, so the request comparison can
fail even when the compaction and service-tier behavior matches.

This is the most frequent retry-saved full-CI failure in the recent
JUnit history.

## What changed

Normalize only the contents of `<skills_instructions>` before comparing
the captured requests. The opening and closing tags remain in the
comparison, so the test still catches a missing or misplaced skills
block.

The service-tier, compacted input, follow-up request, and
replacement-history assertions are unchanged. A focused normalizer test
covers the new behavior.

## Scope

This is test-only. It does not change runtime compaction or skill
behavior. Exact skill-catalog rendering remains covered by the dedicated
skills tests.
2026-07-08 15:59:36 +01:00
jif 8dfd3975f5 Stabilize encrypted MAv2 spawn request test (#31586)
## Why

The encrypted MAv2 spawn test often reads the parent follow-up request
before the child has sent its first request. The response mock records
candidate requests before applying its specific matcher, so the test can
see an empty `agent_message` list even though delivery happens a moment
later.

## What changed

Wait for the recorded child request that contains `agent_message`, using
the same short bounded polling pattern already used in this test module.
The exact encrypted payload and communication-log assertions stay
unchanged.

This is test-only: it does not add product delays, loosen the assertion,
or change multi-agent behavior. No follow-up is expected.
2026-07-08 15:59:04 +01:00
lt-oaiandpakrym-oai 8784de445e [codex] Add externally provided Codex auth (#31274)
## Summary

Add an in-memory externally provided Codex auth snapshot with explicit
runtime capabilities, installed through the existing `ExternalAuth`
provider path.

## Testing

- `just fmt-check`
- `cargo test -p codex-login --lib externally_provided_auth`
- `cargo test -p codex-core --lib
external_auth_snapshot_is_installed_from_runtime_config`
- `cargo test -p codex-model-provider --lib external_auth`
- `cargo test -p codex-mcp-extension --test hosted_apps_mcp
hosted_apps_mcp_accepts_external_provided_codex_auth`
- `cargo check -p codex-app-server -p codex-core-api -p
codex-thread-manager-sample`

---------

Co-authored-by: pakrym-oai <pakrym@openai.com>
2026-07-07 17:43:19 -07:00
Winston Howes 07d631875e Use canonical indexed web access field (#31289)
## Summary

- Rename the hosted web-search wire field to the canonical
`indexed_web_access` spelling.
- Preserve existing indexed-search behavior.

## Rollout

Merge and release only after server support for `indexed_web_access` is
fully deployed.

## Testing

- `just fmt`
- `just test -p codex-tools
web_search_tool_spec_serializes_expected_wire_shape`
- Blocking CI passed, including indexed web-search integration coverage.
2026-07-07 16:17:12 -07:00
Celia Chen 172ab264bd fix: retry rejected previous-model compaction with selected model (#30319)
## Why

Pre-sampling compaction intentionally uses the previous turn's model
when the compaction compatibility hash changes or when switching to a
model with a smaller context window. This keeps compaction aligned with
the settings that produced the history, but it can block the next turn
when a resumed ChatGPT thread still references a model slug that has
since been retired. The Codex backend rejects that compaction request
before the user's currently selected model gets a chance to sample.

This PR lets those threads recover without changing previous-model
compaction behavior for API-key authentication or custom providers. It
is stacked on #31316, which is a behavior-preserving extraction of the
individual remote compaction attempts; this PR contains the fallback
behavior.

## What changed

- For automatic previous-model compaction, capture the selected model's
request context when using ChatGPT authentication with the OpenAI
provider and the selected model differs from the previous model.
- If the previous-model attempt returns an `InvalidRequest`, retry
compaction once with the selected model for both `/responses/compact`
and Responses Compaction V2.
- Complete history processing, lifecycle events, and token accounting
with the context of the model that successfully compacted the thread.
- If the fallback also fails, return the original previous-model error
so the retry does not change the user-visible failure.
- Record fallback attempts with reason, implementation, and outcome
telemetry.
- Leave API-key authentication, custom providers, same-model turns, and
non-`InvalidRequest` failures on their existing paths.

## Testing

- `just test -p codex-core -E 'test(pre_sampling_compact) |
test(model_unavailable_error)'` (10 tests)
- Added integration coverage for a resumed thread whose model was
renamed, a model downshift using Responses Compaction V2, and API-key
authentication with a custom provider.
2026-07-07 14:26:03 -07:00
Matthew Zeng ff06ab7172 [codex] Enable auth elicitation by default (#28772)
## Summary

- enable `auth_elicitation` by default
- promote the feature to `Stable`, as default-enabled features must be
stable
- update the feature regression test to cover the new lifecycle state
and default

## Impact

Auth elicitation is now available without requiring users or clients to
opt in through configuration.

## Testing

- `just test -p codex-features` (52 passed)
2026-07-07 11:48:27 -07:00
Adam Perry @ OpenAI f158b31db5 test: generalize exec-server fixture (#31422)
## Why

Remote-executor integration tests need one host-agnostic exec-server
fixture target instead of a Windows-only wrapper.

## What

- rename the testing binary target to exec-server
- make the fixture source and target host-agnostic
- update Windows remote-executor test wiring to use the shared target

## Validation

- bazel build //codex-rs/exec-server/testing:exec-server
- bazel cquery --config=ci-windows-cross
'set(//codex-rs/exec-server/testing:exec-server
//codex-rs/core/tests/remote_env_windows:smoke-test)'

## Stack

1. [#31422 test: generalize exec-server
fixture](https://github.com/openai/codex/pull/31422)
2. [#31425 test: add TestAppServer
builder](https://github.com/openai/codex/pull/31425)
3. [#31427 test: add delayed exec-server
transport](https://github.com/openai/codex/pull/31427)
4. [#31295 bench: add cold skill load
macrobenchmark](https://github.com/openai/codex/pull/31295)
5. [#31428 bench: add e2e benchmark
entrypoints](https://github.com/openai/codex/pull/31428)
6. [#31429 ci: smoke Bazel e2e
benchmarks](https://github.com/openai/codex/pull/31429)
2026-07-07 11:21:56 -07:00