43 Commits

  • [codex] Treat max as a first-class reasoning effort (#30467)
    ## Why
    
    The Bedrock GPT-5.6 catalog advertises `max`, but Codex treated it as an
    opaque custom effort. That made the reasoning picker render it as
    lowercase `max` while known efforts use productized labels.
    
    Making `max` a known effort aligns catalog data, parsing, and UI
    presentation without changing the `max` wire value or persisted
    representation.
    
    ## What changed
    
    - Add first-class `ReasoningEffort::Max` parsing and serialization.
    - Use the typed effort in the Bedrock catalog and render it as `Max` in
    the TUI.
    - Preserve forward-compatible custom-effort coverage with a genuinely
    unknown `future` value.
    
    ### Before
    <img width="559" height="124" alt="Screenshot 2026-06-28 at 12 08 47 PM"
    src="https://github.com/user-attachments/assets/7c43cf4f-020b-4605-9239-0a9c97eb7364"
    />
    
    ### After
    <img width="558" height="107" alt="Screenshot 2026-06-28 at 12 09 10 PM"
    src="https://github.com/user-attachments/assets/b9cc5ded-c940-43b4-b024-bba25abe0a17"
    />
  • feat: add GPT-5.6 variants to Bedrock catalog (#30285)
    ## Summary
    
    - add Sol (`openai.gpt-5.6-sol`), Terra (`openai.gpt-5.6-terra`), and
    Luna (`openai.gpt-5.6-luna`) to the Amazon Bedrock static model catalog
    - derive all three entries from the bundled GPT-5.5 metadata and add the
    Bedrock-only `max` reasoning effort
    - keep the new entries below the current GPT-5.5 and GPT-5.4 models at
    priorities 2, 3, and 4, preserving GPT-5.5 as the default
    - add deep-equality coverage for inherited model configuration, catalog
    ordering, context windows, and service-tier behavior
  • feat: use run agent task auth for inference (#19051)
    ## Stack
    
    This is PR 3 of the simplified HAI single-run-task stack:
    
    - [#19047](https://github.com/openai/codex/pull/19047) Agent Identity
    assertion and task-registration primitives, including the shared
    run-task helper used by existing Agent Identity JWT auth.
    - [#19049](https://github.com/openai/codex/pull/19049)
    Disabled-by-default ChatGPT auth opt-in that provisions/reuses persisted
    Agent Identity runtime auth and its single run task.
    - [#19051](https://github.com/openai/codex/pull/19051) Run-scoped
    provider auth that uses one backend-owned task id for first-party
    inference and compaction requests.
    
    [#19054](https://github.com/openai/codex/pull/19054) collapsed out of
    the active stack because the simplified design no longer needs a
    separate background/control-plane task helper.
    
    ## Summary
    
    This PR moves Agent Identity usage into provider auth resolution. That
    keeps `AgentAssertion` auth tied to first-party OpenAI provider requests
    instead of applying a late session-wide override that could affect
    local, custom, Bedrock, API-key, or external-bearer providers.
    
    What changed:
    
    - adds a small `ProviderAuthScope` struct carrying the run auth policy
    and session source needed by provider-scoped auth resolution
    - lets `Session` opt the existing `ModelClient` into `ChatGptAuth`
    policy when `use_agent_identity` is enabled, without adding a second
    model-client constructor
    - resolves Agent Identity only for first-party OpenAI provider auth
    paths
    - uses the persisted run task id from the `AgentIdentityAuth` record to
    build `AgentAssertion` auth for Responses requests
    - routes shared request setup through scoped provider auth so unary
    compact requests use the same run-task assertion path as inference turns
    - keeps local/custom/Bedrock/env-key/external-bearer provider auth
    unchanged
    - lets missing run-task state surface through the existing model-request
    error path instead of silently falling back to bearer auth
    
    This PR intentionally does not create thread-scoped, target-scoped, or
    background-scoped task identities. The run task is the only task Codex
    registers in this POC shape.
    
    ## Testing
    
    - `just test -p codex-model-provider`
    - `just test -p codex-core client::tests::provider_auth_scope_uses`
    - `just test -p codex-core remote_compact_uses_agent_identity_assertion`
  • Represent MCP authentication with an enum (#29924)
    ## Why
    
    MCP authentication has distinct OAuth and ChatGPT-session flows.
    Representing that choice as `use_chatgpt_auth` makes one flow implicit
    and allows the configuration model to express the distinction only
    through a boolean.
    
    ChatGPT credential forwarding also needs a first-party trust boundary. A
    configurable `chatgpt_base_url` controls routing, but must not grant an
    MCP server permission to receive session credentials.
    
    This change builds on #29733, where the boolean was introduced.
    
    ## What changed
    
    - Replace `use_chatgpt_auth` with an `auth` field backed by the
    exhaustive `McpServerAuth` enum.
    - Support `auth = "oauth"` and `auth = "chatgpt"`, with OAuth remaining
    the default.
    - Trust only the origin derived from the existing hardcoded
    `CHATGPT_CODEX_BASE_URL` when granting ChatGPT auth to an MCP server.
    - Keep configured bearer tokens and authorization headers ahead of the
    selected authentication flow.
    - Update config writers, schema output, fixtures, and integration-test
    setup to use the enum.
    
    ## Verification
    
    Integration coverage exercises the complete streamable HTTP startup path
    in two independent configurations:
    
    - A directly constructed MCP configuration verifies that matching an
    overridden `chatgpt_base_url` does not grant ChatGPT auth.
    - A persisted `config.toml` containing an attacker-controlled
    `chatgpt_base_url` and `auth = "chatgpt"` verifies the same boundary
    through normal config parsing.
    
    Both tests complete MCP initialization and tool listing and assert that
    the full captured request sequence contains no authorization headers.
    Separate integration coverage verifies that configured authorization
    takes precedence over ChatGPT auth.
  • chore: improve expired Bedrock credential errors (#28992)
    ## Why
    
    Amazon Bedrock returns a `401 Unauthorized` response containing
    `Signature expired:` when an AWS credential, including a short-lived
    `AWS_BEARER_TOKEN_BEDROCK`, has expired. Codex currently surfaces that
    response as a generic `unexpected status` error, which does not explain
    how to recover.
    
    Environment-provided bearer tokens cannot be refreshed automatically, so
    the error should direct users to refresh their AWS credentials or
    replace or remove the environment token and restart Codex. This
    classification belongs to the Amazon Bedrock provider so similar
    responses from other providers retain their existing behavior.
    
    ## What changed
    
    - Add a synchronous `ModelProvider::map_api_error` hook that defaults to
    the existing provider-neutral API error mapping, and route model
    request, stream, WebSocket, and terminal unauthorized errors through the
    active provider.
    - Override the hook for Amazon Bedrock. After preserving the structured
    status, body, URL, and request metadata, recognize `401` responses
    containing `Signature expired:` and attach actionable credential
    guidance.
    - Keep `codex-protocol` provider-neutral by representing the guidance as
    an optional `user_message`. Error rendering prefers this message while
    continuing to append the URL, request ID, Cloudflare ray, and
    authorization diagnostics.
    - Add model-provider coverage for expired signatures and negative cases,
    core coverage for provider dispatch after unauthorized recovery, and a
    TUI snapshot for the rendered error.
    
    ## Testing
    Tested with a real request with expired bedrock key:
    <img width="962" height="126" alt="Screenshot 2026-06-22 at 3 56 51 PM"
    src="https://github.com/user-attachments/assets/7e21cc7c-798e-4662-8467-7f304a2f2b59"
    />
  • Allow ChatGPT accounts without email (#28991)
    # Summary
    
    Codex required every ChatGPT account to have an email address. A
    service-account personal access token can return valid account metadata
    without one, so PAT login failed while decoding the metadata response.
    
    This change makes email optional in the account metadata type that owns
    it and preserves that absence through authentication, provider account
    state, the app-server API, generated clients, and TUI bootstrap.
    Existing accounts with email addresses keep the same behavior.
    
    ## Behavior-changing call sites
    
    | Call site | Behavior after this change |
    | --- | --- |
    | `login/src/auth/personal_access_token.rs` | PAT metadata accepts a
    missing or null email and retains `None`. |
    | `agent-identity/src/lib.rs` | Agent Identity JWT claims accept an
    omitted email. |
    | `login/src/auth/storage.rs` and `login/src/auth/agent_identity.rs` |
    Stored and managed Agent Identity records carry `Option<String>`.
    Deserialization maps the legacy empty-string sentinel to `None`. |
    | `login/src/auth/manager.rs` | `get_account_email` returns the stored
    option, and managed identity bootstrap no longer converts `None` to an
    empty string. |
    | `model-provider/src/provider.rs` and `protocol/src/account.rs` | A
    ChatGPT provider account requires a plan type but may carry no email. |
    | `app-server-protocol/src/protocol/v2/account.rs` | `account/read`
    keeps the `email` field on the wire and returns `null` when the account
    has no email. Generated TypeScript and JSON schemas describe a required,
    nullable field. |
    | `sdk/python/src/openai_codex/generated/v2_all.py` | The generated
    Python `ChatgptAccount` model accepts `None` for email. |
    | `tui/src/app_server_session.rs` | Email-less ChatGPT accounts
    bootstrap normally, keep external feedback routing, omit account-email
    telemetry, and display the plan in account status. |
    
    ## Design decisions
    
    - Missing email remains `None` at every layer. The code never uses an
    empty string as a substitute.
    - The app-server response includes `"email": null` instead of omitting
    the field. Clients retain a stable response shape.
    - Plan type remains required for provider account state. This change
    relaxes only the email assumption.
    
    ## Testing
    
    Tests: affected test targets compile, scoped Clippy and formatting pass,
    a focused TUI snapshot covers plan-only account status, real
    before/after PAT login smoke covers metadata without email, app-server
    smoke covers `account/read` with `email: null`, and a regression smoke
    covers an existing email-bearing PAT. Unit tests run in CI.
    
    ## Evidence
    
    Visual smoke evidence will be attached here.
  • feat: add run task identity primitives (#19047)
    ## Stack
    
    This is PR 1 of the simplified HAI single-run-task stack:
    
    - [#19047](https://github.com/openai/codex/pull/19047) Agent Identity
    assertion and task-registration primitives, including the shared
    run-task helper used by existing Agent Identity JWT auth.
    - [#19049](https://github.com/openai/codex/pull/19049)
    Disabled-by-default ChatGPT auth opt-in that provisions/reuses persisted
    Agent Identity runtime auth and its single run task.
    - [#19051](https://github.com/openai/codex/pull/19051) Run-scoped
    provider auth that uses one backend-owned task id for first-party
    inference and compaction requests.
    
    [#19054](https://github.com/openai/codex/pull/19054) collapsed out of
    the active stack because the simplified design no longer needs a
    separate background/control-plane task helper.
    
    ## Summary
    
    The simplified POC shape is one backend-owned task per Agent Identity
    run. This PR makes the first layer match that final shape directly
    instead of introducing task targets, caller-owned external task refs, or
    intermediate wrappers that later PRs would need to undo.
    
    What changed:
    
    - keeps the `AgentAssertion` wire payload as `agent_runtime_id`,
    `task_id`, `timestamp`, and `signature`
    - exposes `register_agent_task` as the single task-registration helper
    for both existing Agent Identity JWT auth and the ChatGPT-registration
    path added later in the stack
    - makes task registration send only the signed registration timestamp;
    the backend owns the returned opaque task id
    - removes the unused target/task-kind/external-task-ref surfaces from
    `codex-agent-identity`
    - keeps Agent Identity JWT JWKS lookup separate from agent/task
    registration URL derivation
    - updates Agent Identity JWT auth to register one run task during auth
    construction and share that task across cloned auth handles
    
    This PR intentionally does not enable ChatGPT-derived Agent Identity.
    That opt-in and config gate are added in the next PR.
    
    ## Testing
    
    - `just test -p codex-agent-identity`
  • [codex] expose Bedrock credential source in account/read (#27751)
    ## Why
    
    `account/read` currently reports only `type: "amazonBedrock"`, so
    clients cannot distinguish a Codex-managed Bedrock API key from
    credentials supplied by AWS. The app UI needs that distinction to render
    the appropriate account state without duplicating provider-auth logic.
    
    Credential-source selection belongs to the Bedrock model provider
    because it already owns the precedence between managed Bedrock auth and
    the external AWS credential path. This builds on #27443 and #27689.
    
    ## What changed
    
    - Added `AmazonBedrockCredentialSource` with `codexManaged` and
    `awsManaged` values.
    - Included the selected credential source in
    `ProviderAccount::AmazonBedrock` and the app-server `Account` response.
    - Made `AmazonBedrockModelProvider::account_state()` classify the source
    from its managed-auth state.
    - Regenerated the app-server JSON and TypeScript schemas.
    - Updated app-server account documentation and downstream TUI matches.
    
    `codexManaged` means the provider found a managed Bedrock API key.
    `awsManaged` identifies the provider's external AWS credential path; it
    does not assert that the AWS credential chain has been validated.
    
    ## Testing
    
    - Added model-provider coverage for Codex-managed precedence and
    AWS-managed fallback.
    - Added app-server protocol serialization coverage for both wire values.
    - Added app-server integration coverage for both `account/read`
    responses.
    - `just test -p codex-protocol -p codex-model-provider -p
    codex-app-server-protocol` (497 tests passed).
    
    After rebasing onto #27711, the `codex-app-server` test target compiled
    past the image-generation `PathUri` migration. Local linking was then
    interrupted by disk exhaustion (`No space left on device`).
  • [codex] Remove async_trait from first-party code (#27475)
    ## Why
    
    First-party async traits should expose their `Send` contracts explicitly
    without requiring `async_trait`. This completes the migration pattern
    established in #27303 and #27304.
    
    ## What changed
    
    - Replaced the remaining first-party `async_trait` traits with native
    return-position `impl Future + Send` where statically dispatched and
    explicit boxed `Send` futures where object safety is required.
    - Kept implementations behavior-preserving, outlining existing async
    bodies into inherent methods where that keeps the diff reviewable.
    - Removed all direct first-party `async-trait` dependencies and the
    workspace dependency declaration.
    - Added a cargo-deny policy that permits `async-trait` only through the
    remaining transitive wrapper crates.
    - Updated `rand` from 0.8.5 to 0.8.6 to resolve RUSTSEC-2026-0097 and
    keep the full cargo-deny check passing.
    
    ## Validation
    
    - `just test -p codex-exec-server`: 216 passed, 2 skipped.
    - `just test -p codex-model-provider`: 39 passed.
    - `just test -p codex-core` and `just test`: changed tests passed;
    remaining failures are environment-sensitive suites unrelated to this
    migration.
    - `cargo deny check`
    - `just fix`
    - `just fmt`
    - `cargo shear`
    - `just bazel-lock-check`
  • feat: prefer managed Bedrock auth in model provider (#27689)
    ## Why
    
    The Amazon Bedrock model provider currently discards the shared
    `AuthManager`, so a Codex-managed Bedrock API key cannot reach
    request-time provider auth. Bedrock instead falls through to AWS
    environment or SDK credentials, and the request endpoint can be resolved
    from a different region than the managed credential.
    
    Managed Bedrock login should control both the bearer credential and
    Mantle region. Unrelated OpenAI or ChatGPT credentials must remain
    isolated from Bedrock.
    
    ## What changed
    
    - Pass the shared `AuthManager` into `AmazonBedrockModelProvider`.
    - Select `CodexAuth::BedrockApiKey` before the existing
    `AWS_BEARER_TOKEN_BEDROCK` and AWS SDK/SigV4 paths.
    - Use the managed Bedrock auth region when resolving the Mantle
    endpoint.
    - Filter other `CodexAuth` variants so OpenAI and ChatGPT auth are not
    exposed to Bedrock request auth or unauthorized recovery.
    - Add focused coverage for provider construction, managed-auth
    precedence, bearer headers, endpoint selection, and OpenAI-auth
    isolation.
  • feat: add Bedrock API key as a managed auth mode (#27443)
    ## Why
    
    Codex needs to manage Amazon Bedrock API key credentials through the
    existing auth lifecycle instead of introducing a separate auth manager
    or provider-specific credential file. Treating Bedrock API key login as
    a primary auth mode gives it the same persistence, keyring, reload, and
    logout behavior as the existing OpenAI API key and ChatGPT modes.
    
    The credential is valid only for the `amazon-bedrock` model provider.
    OpenAI-compatible providers must reject this auth mode rather than
    treating the Bedrock key as an OpenAI bearer token.
    
    ## What changed
    
    - Added `bedrockApiKey` as an app-server `AuthMode` and
    `CodexAuth::BedrockApiKey` as a primary `AuthManager` mode.
    - Added `BedrockApiKeyAuth`, containing the API key and AWS region, to
    the existing `AuthDotJson` payload stored in `$CODEX_HOME/auth.json` or
    the configured keyring backend.
    - Added `login_with_bedrock_api_key(...)`, parallel to
    `login_with_api_key(...)`, which replaces the current stored login with
    Bedrock credentials.
    - Reused generic auth reload and logout behavior instead of adding a
    Bedrock-specific auth manager or logout path.
    - Updated login restrictions, status reporting, diagnostics, telemetry
    classification, generated app-server schemas, and auth fixtures for the
    new mode.
    - Added explicit errors when Bedrock API key auth is selected with an
    OpenAI-compatible model provider.
    
    This PR establishes managed storage and auth-mode behavior. Routing the
    managed key and region into Amazon Bedrock requests will be in follow-up
    PRs.
  • feat: use provider defaults for memory models (#27129)
    ## Why
    
    Memory startup used hardcoded OpenAI model slugs for extraction and
    consolidation. That works for the default OpenAI-compatible path, but
    provider-specific backends can require different model identifiers. In
    particular, Amazon Bedrock should use its Bedrock model ID for these
    background memory requests instead of the OpenAI `gpt-5.4-mini` /
    `gpt-5.4` slugs.
    
    ## What Changed
    
    - Added provider-owned preferred memory model methods alongside
    `approval_review_preferred_model`.
    - Updated memory extraction and consolidation to resolve their default
    model through the active `ModelProvider`.
    - Added Amazon Bedrock overrides so both memory stages use
    `openai.gpt-5.4` through Bedrock’s provider-specific model ID.
    - Kept explicit `memories.extract_model` and
    `memories.consolidation_model` config overrides taking precedence.
    - Added startup coverage for default OpenAI and Bedrock memory model
    selection.
    
    #closes #26288
  • [codex-rs] support v2 personal access tokens (#25731)
    ## Summary
    
    - add v2 personal access token support for `codex login
    --with-access-token` and `CODEX_ACCESS_TOKEN`
    - classify opaque `at-` tokens separately from legacy Agent Identity
    JWTs
    - hydrate required ChatGPT account metadata through AuthAPI
    `/v1/user-auth-credential/whoami`
    - use PATs directly as bearer tokens while preserving existing ChatGPT
    account surfaces
    - expose PAT-backed auth as the explicit `personalAccessToken`
    app-server auth mode
    
    ## Implementation
    
    PAT auth is intentionally small and stateless. Loading a PAT performs
    one AuthAPI metadata request, stores the hydrated metadata in the
    in-memory auth object, and redacts the secret from debug output. Legacy
    Agent Identity JWT handling remains unchanged. The shared access-token
    classifier lives in a private neutral module because it dispatches
    between both credential types.
    
    PAT hydration fails closed when AuthAPI omits any required metadata,
    including email. Hydrated metadata is intentionally not persisted:
    startup performs a live `whoami` preflight so revoked tokens or changed
    account metadata are not accepted from a stale cache.
    
    ## Workspace restriction scope
    
    This change intentionally does **not** apply
    `forced_chatgpt_workspace_id` to PAT authentication. The setting is a
    client-side config guardrail, not an authorization boundary, and PAT
    does not currently require workspace-ID parity. The PAT login and
    `CODEX_ACCESS_TOKEN` paths therefore validate through AuthAPI without
    threading workspace-restriction state through access-token loading.
    Existing workspace checks for non-PAT auth remain on their established
    paths.
    
    ## App-server compatibility
    
    The public app-server `AuthMode` is shared across v1 and v2, and
    PAT-backed auth reports `personalAccessToken` through both APIs.
    Following human review, this intentionally removes the temporary v1
    compatibility mapping that reported PATs as `chatgpt`; the deprecated v1
    API is kept in parity with v2 rather than maintaining a separate closed
    enum. Clients with exhaustive auth-mode handling in either API version
    must add the new case and should generally treat it as ChatGPT-backed
    unless they need PAT-specific behavior.
    
    The v1 auth-status response still omits the raw PAT when `includeToken`
    is requested because that response cannot carry the account metadata
    needed to reuse the credential safely. Persisted PAT auth also omits the
    new enum value so older Codex builds can deserialize `auth.json` and
    infer PAT auth from the credential field after a rollback.
    
    ## Validation
    
    Latest review-fix validation:
    
    - `CARGO_INCREMENTAL=0 just test -p codex-login` (126 passed)
    - `CARGO_INCREMENTAL=0 just test -p codex-cli` (263 passed)
    - `CARGO_INCREMENTAL=0 just test -p codex-cli
    stored_auth_validation_handles_personal_access_token`
    - `CARGO_INCREMENTAL=0 just test -p codex-app-server-protocol` (226
    passed)
    - `CARGO_INCREMENTAL=0 just test -p codex-models-manager
    refresh_available_models_uses_remote_only_catalog_for_chatgpt_auth`
    - `CARGO_INCREMENTAL=0 just test -p codex-tui
    existing_non_oauth_chatgpt_login_counts_as_signed_in`
    - `CARGO_INCREMENTAL=0 just fix -p codex-login -p
    codex-app-server-protocol -p codex-models-manager -p codex-tui -p
    codex-cli`
    - `just fmt`
    - `git diff --check`
    
    The broader `codex-tui` suite previously compiled and ran 2,834 tests.
    Three unrelated environment-sensitive guardian/IDE-socket tests failed
    after retries; the PAT-relevant TUI coverage passed.
  • fix: Limit Bedrock GPT models to default service tier (#25318)
    ## Description
    
    Bedrock currently only supports the implicit `default` service tier for
    GPT models. This PR strips non-default service tier metadata from
    Bedrock model catalogs so Codex does not advertise or send unsupported
    tiers.
    
    ## What changed
    
    - Normalize both built-in and configured Bedrock catalogs to
    default-only service tier behavior.
    - Add regression coverage for built-in and configured Bedrock catalogs.
    
    ## Validation
    
    - `just fmt`
    - `just test -p codex-model-provider`
  • fix: Bedrock API key region fallback (#25171)
    ## Why
    
    Users following the Amazon Bedrock API-key setup can export
    `AWS_BEARER_TOKEN_BEDROCK` and `AWS_REGION`, but Codex's bearer-token
    auth path only accepted `model_providers.amazon-bedrock.aws.region`.
    That made the documented env-based setup fail with a missing-region
    error even though the standard AWS region environment variable was
    present.
    
    ## What Changed
    
    - Updates Bedrock bearer-token region resolution to use
    `model_providers.amazon-bedrock.aws.region` first, then fall back to
    `AWS_REGION`, then `AWS_DEFAULT_REGION`.
    - Updates the missing-region error to list all supported region sources.
    - Adds focused coverage for config precedence, `AWS_REGION`,
    `AWS_DEFAULT_REGION`, and the missing-region failure.
  • [codex] Remove Bedrock OSS models from catalog (#24960)
    Remove the GPT OSS 120B and 20B entries from the Amazon Bedrock static
    model catalog, as they are no longer supported.
  • chore: add GPT-5.5 to the Amazon Bedrock catalog (#24701)
    ## Summary
    
    Amazon Bedrock should expose GPT-5.5 alongside GPT-5.4, and the Bedrock
    GPT entries should stay aligned with the canonical bundled OpenAI model
    metadata instead of carrying a separate hand-written copy that can drift
    over time. This change will be merged when the model is online.
    
    This change:
    
    - Adds the Bedrock Mantle model id for `openai.gpt-5.5`.
    - Builds the Bedrock GPT-5.5 and GPT-5.4 catalog entries from the
    bundled OpenAI model catalog, then overrides the Bedrock-facing slug,
    explicit priority, and Bedrock-specific context windows.
    - Hardcodes both `context_window` and `max_context_window` to `272000`
    for Bedrock GPT-5.5 and GPT-5.4.
    - Keeps `openai.gpt-5.5` as the default Bedrock model ahead of
    `openai.gpt-5.4` and the Bedrock OSS models.
  • chore: enable namespace tools for Bedrock (#24713)
    Client-side namespace tools are now supported by bedrock. Enable
    `namespace_tools` for the Amazon Bedrock provider while continuing to
    disable unsupported hosted tools such as image generation and web
    search.
  • Revert "Add Bedrock Mantle GovCloud region (#23860)" (#24690)
    This reverts commit 5381240f57. Gov cloud
    should not be supported
    
    # External (non-OpenAI) Pull Request Requirements
    
    External code contributions are by invitation only. Please read the
    dedicated "Contributing" markdown file for details:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
    
    Include a link to a bug report or enhancement request.
  • Add Bedrock Mantle GovCloud region (#23860)
    ## Summary
    - Add us-gov-west-1 to the Bedrock Mantle supported region list
    - Cover the GovCloud endpoint URL in the existing base_url unit test
    
    ## Test
    - cargo test -p codex-model-provider
  • Honor client-resolved service tier defaults (#23537)
    ## Why
    
    Model catalog responses can now advertise a nullable
    `default_service_tier` for each model. Codex needs to preserve three
    distinct states all the way from config/app-server inputs to inference:
    
    - no explicit service tier, so the client may apply the current model
    catalog default when FastMode is enabled
    - explicit `default`, meaning the user intentionally wants standard
    routing
    - explicit catalog tier ids such as `priority`, `flex`, or future tiers
    
    Keeping those states distinct prevents the UI from showing one tier
    while core sends another, especially after model switches or app-server
    `thread/start` / `turn/start` updates.
    
    ## What Changed
    
    - Plumbed `default_service_tier` through model catalog protocol types,
    app-server model responses, generated schemas, model cache fixtures, and
    provider/model-manager conversions.
    - Added the request-only `default` service tier sentinel and normalized
    legacy config spelling so `fast` in `config.toml` still materializes as
    the runtime/request id `priority`.
    - Moved catalog default resolution to the TUI/client side, including
    recomputing the effective service tier when model/FastMode-dependent
    surfaces change.
    - Updated app-server thread lifecycle config construction so
    `serviceTier: null` preserves explicit standard-routing intent by
    mapping to `default` instead of internal `None`.
    - Kept core responsible for validating explicit tiers against the
    current model and stripping `default` before `/v1/responses`, without
    applying catalog defaults itself.
    
    ## Validation
    
    - `CARGO_INCREMENTAL=0 cargo build -p codex-cli`
    - `CARGO_INCREMENTAL=0 cargo test -p codex-app-server model_list`
    - `cargo test -p codex-tui service_tier`
    - `cargo test -p codex-protocol service_tier_for_request`
    - `cargo test -p codex-core get_service_tier`
    - `RUST_MIN_STACK=8388608 CARGO_INCREMENTAL=0 cargo test -p codex-core
    service_tier`
  • feat: route guardian review model selection through providers (#22258)
    ## Why
    
    Guardian review selection was hard-coded in `core`, which worked for the
    default OpenAI path but did not give provider implementations a way to
    choose backend-specific reviewer model IDs. That matters for Amazon
    Bedrock: guardian review should run through the Bedrock/Mantle provider
    using Bedrock's `openai.gpt-5.4` model ID, instead of accidentally
    selecting a reviewer model that implies the OpenAI backend.
    
    ## What Changed
    
    - Added provider-owned approval review model selection via
    `ModelProvider::approval_review_model_selection`.
    - Moved the existing default selection policy into the provider
    abstraction: prefer the requested reviewer model when it is available,
    otherwise fall back to the active turn model, preferring `Low` reasoning
    when supported.
    - Added an Amazon Bedrock override that pins guardian review to
    `openai.gpt-5.4` with `Low` reasoning.
  • [codex] Delete function-style apply_patch (#21651)
    ## Why
    
    `apply_patch` is now a freeform/custom tool. Keeping the old
    JSON/function-style registration and parsing path left another way for
    models and tests to invoke `apply_patch`, which made the tool surface
    harder to reason about.
    
    ## What changed
    
    - Removed the `ApplyPatchToolType::Function` variant, JSON `apply_patch`
    spec, and handler support for function payloads.
    - Kept `apply_patch_tool_type = freeform` as the supported model
    metadata path, including Bedrock catalog metadata.
    - Migrated `apply_patch` tests and SSE fixtures to custom/freeform tool
    calls.
    
    ## Verification
    
    - `cargo test -p codex-tools -p codex-protocol -p codex-model-provider`
    - `cargo test -p codex-core tools::handlers::apply_patch --lib`
    - `cargo test -p codex-core --test all
    apply_patch_tool_executes_and_emits_patch_events`
    - `cargo test -p codex-core --test all
    apply_patch_reports_parse_diagnostics`
    - `cargo test -p codex-exec test_apply_patch_tool`
    - `just fix -p codex-core`
    - `just fix -p codex-tools -p codex-protocol -p codex-model-provider -p
    codex-exec`
  • [codex] request desktop attestation from app (#20619)
    ## Summary
    
    TL;DR: teaches `codex-rs` / app-server to request a desktop-provided
    attestation token and attach it as `x-oai-attestation` on the scoped
    ChatGPT Codex request paths.
    
    ![DeviceCheck attestation
    interface](https://raw.githubusercontent.com/openai/codex/dev/jm/devicecheck-diagram-assets/pr-assets/devicecheck-attestation-interface.png)
    
    ## Details
    
    This PR teaches the Codex app-server runtime how to request and attach
    an attestation token. It does not generate DeviceCheck tokens directly;
    instead, it relies on the connected desktop app to advertise that it can
    generate attestation and then asks that app for a fresh header value
    when needed.
    
    The flow is:
    
    1. The Codex desktop app connects to app-server.
    2. During `initialize`, the app can advertise that it supports
    `requestAttestation`.
    3. Before app-server calls selected ChatGPT Codex endpoints, it sends
    the internal server request `attestation/generate` to the app.
    4. app-server receives a pre-encoded header value back.
    5. app-server forwards that value as `x-oai-attestation` on the scoped
    outbound requests.
    
    The code in this repo is mostly protocol and runtime plumbing: it adds
    the app-server request/response shape, introduces an attestation
    provider in core, wires that provider into Responses / compaction /
    realtime setup paths, and covers the intended scoping with tests. The
    signed macOS DeviceCheck generation remains owned by the desktop app PR.
    
    ## Related PR
    
    - Codex desktop app implementation:
    https://github.com/openai/openai/pull/878649
    
    ## Validation
    
    <details>
    <summary>Tests run</summary>
    
    ```sh
    cargo test -p codex-app-server-protocol
    cargo test -p codex-core attestation --lib
    cargo test -p codex-app-server --lib attestation
    ```
    
    Also ran:
    
    ```sh
    just fix -p codex-core
    just fix -p codex-app-server
    just fix -p codex-app-server-protocol
    just fmt
    just write-app-server-schema
    ```
    
    </details>
    
    <details>
    <summary>E2E DeviceCheck validation</summary>
    
    First validated the signed desktop app boundary directly: launched a
    packaged signed `Codex.app`, sent `attestation/generate`, decoded the
    returned `v1.` attestation header, and validated the extracted
    DeviceCheck token with `personal/jm/verify_devicecheck_token.py` using
    bundle ID `com.openai.codex`. Apple returned `status_code: 200` and
    `is_ok: true`.
    
    Then ran the fuller app + app-server flow. The packaged `Codex.app`
    launched a current-branch app-server via `CODEX_CLI_PATH`, and a local
    MITM proxy intercepted outbound `chatgpt.com` traffic. The app-server
    requested `attestation/generate` from the real Electron app process, and
    the intercepted `/backend-api/codex/responses` traffic included
    `x-oai-attestation` on both routes:
    
    ```text
    GET  /backend-api/codex/responses  Upgrade: websocket  x-oai-attestation: present
    POST /backend-api/codex/responses  Upgrade: none       x-oai-attestation: present
    ```
    
    The captured header decoded to a DeviceCheck token that also validated
    with Apple for `com.openai.codex` (`status_code: 200`, `is_ok: true`,
    team `2DC432GLL2`).
    
    </details>
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • [codex] Generalize service tier slash commands (#21745)
    ## Why
    
    `/fast` was wired as a one-off slash command even though model metadata
    now exposes service tiers as catalog data. That meant adding another
    tier, such as a slower/cheaper tier, would require more hardcoded TUI
    plumbing instead of letting the model catalog drive the available
    commands.
    
    This change makes service-tier commands data-driven: each advertised
    `service_tiers` entry becomes a `/name` command using the catalog
    description, while the request path sends the tier `id` only when the
    selected model supports it.
    
    ## What Changed
    
    - Removed the hardcoded `/fast` slash-command variant and introduced
    dynamic service-tier command items in the composer and command popup.
    - Added toggle behavior for service-tier commands: invoking `/name`
    selects that tier, and invoking it again clears the selection.
    - Preserved the existing Fast-mode keybinding/status affordances by
    resolving the current model tier whose name is `fast`, while still
    sending the tier request value such as `priority`.
    - Persisted service-tier selections as raw request strings so non-fast
    tiers can round-trip through config.
    - Updated the Bedrock catalog entry to advertise fast support through
    `service_tiers` with `id: "priority"` and `name: "fast"`.
    - Added defensive filtering in core so unsupported selected service
    tiers are omitted from `/responses` requests.
    
    ## Validation
    
    - Added/updated coverage for dynamic service-tier slash command lookup,
    popup descriptions, composer dispatch, TUI fast toggling, and
    unsupported-tier omission in core request construction.
    - Local tests were not run per request.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • feat: enable AWS login credentials for Bedrock auth (#21623)
    ## Summary
    
    Codex's Amazon Bedrock provider signs Mantle requests with SigV4 using
    credentials resolved by the AWS SDK. That worked for standard AWS
    profiles and environment credentials, but AWS CLI console-login profiles
    created by `aws login` require the SDK's `credentials-login` feature to
    resolve `login_session` credentials.
    
    This change enables that credential provider so Bedrock can use AWS
    console-login credentials through the existing provider-owned AWS auth
    path.
    
    While testing the console-login path, we also hit a Mantle-specific
    SigV4 regression from the new split between `session_id` and
    `thread_id`. Mantle does not preserve legacy OpenAI compatibility
    headers that use `snake_case` before SigV4 verification, so signing
    those headers can make the server reconstruct a different canonical
    request. The Bedrock auth path now removes that header class before
    signing, keeping preserved hyphenated Codex/AWS headers such as
    `x-codex-turn-metadata` signed normally.
    
    ## Changes
    
    - Enable `aws-config`'s `credentials-login` feature in
    `codex-rs/aws-auth`.
    - Add a compile-time regression test for
    `aws_config::login::LoginCredentialsProvider`.
    - Strip `snake_case` compatibility headers from Bedrock Mantle SigV4
    requests before signing.
    - Expand the Bedrock auth regression test to cover `session_id`,
    `thread_id`, and future headers of the same shape.
    - Refresh Cargo and Bazel lockfiles for the added `aws-sdk-signin`
    dependency.
    
    ## Tests
    - tested with `aws login` locally and verified that it works as
    intended.
  • 1- Add model service tiers metadata (#20969)
    ## Why
    
    The model list needs to carry display-ready service tier metadata so
    clients can render tier choices with stable IDs, names, and
    descriptions. A raw speed-tier string list is not enough for richer UI
    copy or future tier labels.
    
    ## What changed
    
    - Added `ModelServiceTier` to shared model metadata with string `id`,
    `name`, and `description` fields.
    - Added `service_tiers` to `ModelInfo` and `ModelPreset`, preserving
    empty defaults for older cached model payloads.
    - Exposed `serviceTiers` on app-server v2 `Model` responses and threaded
    it through TUI app-server model conversion.
    - Marked legacy `additional_speed_tiers` / `additionalSpeedTiers`
    metadata as deprecated in source and generated schema output.
    - Regenerated app-server protocol JSON schema and TypeScript fixtures,
    including `ModelServiceTier.ts`.
    
    ## Verification
    
    - Ran `just write-app-server-schema`.
    - Did not run local tests per repo instruction; relying on PR CI.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • fix: show correct Bedrock runtime endpoint in /status (#20275)
    ## Why
    
    `/status` was showing the configured `ModelProviderInfo.base_url` for
    Amazon Bedrock, which can be stale or misleading because the actual
    Bedrock Mantle endpoint is derived at runtime from the resolved AWS
    region. This made sessions report the wrong provider endpoint even
    though requests used the correct runtime URL.
    
    ## What changed
    
    - Added `ModelProvider::runtime_base_url()` so provider implementations
    can expose the request-time base URL through the shared runtime provider
    abstraction.
    - Moved Bedrock region-to-Mantle URL resolution into
    `amazon_bedrock::mantle::runtime_base_url()`, keeping region resolution
    private to the Mantle module.
    - Overrode `runtime_base_url()` for Amazon Bedrock so it returns the
    resolved Mantle endpoint instead of the configured default.
    - Resolved and cached the runtime provider base URL during TUI startup,
    then used that cached value when rendering `/status`.
    - Added status coverage that verifies Bedrock displays the runtime URL
    and ignores the configured Bedrock `base_url` when they differ.
    
    ## Verification
    model provider is resolved correctly in local build:
    <img width="696" height="245" alt="Screenshot 2026-04-29 at 5 01 36 PM"
    src="https://github.com/user-attachments/assets/a13c10a5-3720-41ab-8ace-3c4bc573f971"
    />
  • Reduce the surface of collaboration modes (#20149)
    Collaboration modes were slightly invasive both into ThreadManager
    construction and ModelProvider
  • feat: update Bedrock Mantle endpoint and GPT-5.4 model ID (#20109)
    ## Summary
    
    Amazon Bedrock Mantle's OpenAI-compatible endpoint now lives under
    `/openai/v1`, and the GPT-5.4 Mantle model ID no longer uses the `-cmb`
    suffix. This updates Codex's built-in Bedrock provider configuration so
    generated providers and the static Bedrock catalog use the current
    endpoint and model ID.
    
    ## Changes
    
    - Update the Bedrock Mantle base URL from
    `https://bedrock-mantle.{region}.api.aws/v1` to
    `https://bedrock-mantle.{region}.api.aws/openai/v1`.
    - Update the Amazon Bedrock default base URL in
    `codex-model-provider-info`.
    - Change the Bedrock GPT-5.4 catalog slug from `openai.gpt-5.4-cmb` to
    `openai.gpt-5.4`.
    - Align provider and catalog tests with the new URL and model ID.
    
    ## Test Plan
    
    - Manual smoke test:
    
      ```shell
      target/debug/codex \
          -m openai.gpt-5.4 \
          -c 'model_provider="amazon-bedrock"' \
          -c 'model_providers.amazon-bedrock.aws.region="us-west-2"'
      ```
  • feat: disable capabilities by model provider (#19442)
    ## Why
    
    Unsupported features must fail closed and Codex must not expose
    OpenAI-hosted fallback paths when the active provider cannot support
    them. In practice, Bedrock should not surface app connectors, MCP
    servers, tool search/suggestions, image generation, web search, or JS
    REPL until those paths are explicitly supported for that provider.
    
    This PR moves that decision into provider-owned capability metadata
    instead of scattering Bedrock-specific checks across callers.
    
    ## What changed
    
    - Adds `ProviderCapabilities` to `codex-model-provider`, with default
    support for existing providers and a Bedrock override that disables
    unsupported launch surfaces.
    - Adds `ToolCapabilityBounds` to `codex-tools` so provider capability
    limits can clamp otherwise-enabled tool config.
    - Applies capability bounds when building session and review-thread tool
    config.
    - Routes MCP/app connector configuration through
    `McpManager::mcp_config`, which filters configured MCP servers and app
    connectors based on the active provider.
    - Updates app-server MCP list/read paths to use the filtered MCP config.
    - Adds coverage for default provider capabilities, Bedrock disabled
    capabilities, and optional tool-surface clamping.
    
    ## Testing
    
    built locally and verified that bedrock responses api now return without
    errors calling unsupported tools.
  • Return None when auth refresh fails (#20092)
    Right now, if Codex winds up in a state with auth but it can't refresh
    the token, the user is left with an unhelpful message that says to log
    out and log back in again.
    
    Ultimately, we should prevent that from happening but if it does,
    returning None will allow the caller to redirect the user back to the
    login page
  • refactor: load agent identity runtime eagerly (#19763)
    ## Summary
    
    AgentIdentity auth previously registered the process task lazily behind
    a `OnceCell`. That meant the auth object could be constructed before its
    runtime task binding was known.
    
    This PR makes AgentIdentity auth load the runtime task at auth load time
    and stores the resulting process task id directly on the auth object.
    The model-provider call path can then read a concrete task id instead of
    handling a missing lazy value.
    
    ## Stack
    
    1. [refactor: make auth loading
    async](https://github.com/openai/codex/pull/19762) (merged)
    2. **This PR:** [refactor: load AgentIdentity runtime
    eagerly](https://github.com/openai/codex/pull/19763)
    3. [fix: configure AgentIdentity AuthAPI base
    URL](https://github.com/openai/codex/pull/19904)
    4. [feat: verify AgentIdentity JWTs with
    JWKS](https://github.com/openai/codex/pull/19764)
    
    ## Important call sites
    
    | Area | Change |
    | --- | --- |
    | `AgentIdentityAuth::load` | Registers the process task during auth
    loading and stores `process_task_id`. |
    | `CodexAuth::from_agent_identity_jwt` | Awaits AgentIdentity auth
    loading. |
    | model-provider auth | Reads a concrete `process_task_id` instead of an
    optional lazy value. |
    | AgentIdentity auth tests | Mock task registration now covers eager
    runtime allocation. |
    
    ## Design decisions
    
    AgentIdentity auth now treats task registration as part of constructing
    a usable auth object. That matches how callers use the value: once auth
    is present, the model-provider path expects the task-scoped assertion
    data to be ready.
    
    ## Testing
    
    Tests: targeted Rust auth test compilation, formatter, scoped Clippy
    fix, and Bazel lock check.
  • fix: Bedrock GPT-5.4 reasoning levels (#19461)
    ## Why
    
    When using the Amazon Bedrock provider with `openai.gpt-5.4-cmb`, the
    model picker allowed `xhigh` because the CMB catalog entry was derived
    from the bundled `gpt-5.4` reasoning metadata. Bedrock rejects that
    effort level, causing the request to fail before the turn can run:
    
    ```text
    {"error":{"code":"validation_error","message":"Failed to deserialize the JSON body into the target type: Invalid 'reasoning': Invalid 'effort': unknown variant `xhigh`, expected one of `high`, `low`, `medium`, `minimal` at line 1 column 77239","param":null,"type":"invalid_request_error"}}
    ```
    
    ## What Changed
    
    - Replace the runtime lookup of bundled `gpt-5.4` metadata for
    `openai.gpt-5.4-cmb` with an explicit Bedrock CMB `ModelInfo` entry.
    - Advertise only the Bedrock-supported CMB reasoning levels: `minimal`,
    `low`, `medium`, and `high`.
    - Keep the existing GPT OSS Bedrock model metadata and reasoning levels
    unchanged.
    - Add catalog coverage for the hardcoded CMB metadata and
    Bedrock-compatible reasoning level list.
  • Fix: use function apply_patch tool for Bedrock model (#19416)
    ## Why
    
    `openai.gpt-5.4-cmb` is served through the Amazon Bedrock provider,
    whose request validator currently accepts `function` and `mcp` tool
    specs but rejects Responses `custom` tools. The CMB catalog entry reuses
    the bundled `gpt-5.4` metadata, which marks `apply_patch_tool_type` as
    `freeform`. That causes Codex to include an `apply_patch` tool with
    `type: "custom"`, so even heavily disabled sessions can fail before the
    model runs with:
    
    ```text
    Invalid tools: unknown variant `custom`, expected `function` or `mcp`
    ```
    
    This is provider-specific: the model should still expose `apply_patch`,
    but for Bedrock it needs to use the JSON/function tool shape instead of
    the freeform/custom shape.
    
    ## What Changed
    
    - Override the `openai.gpt-5.4-cmb` static catalog entry to set
    `apply_patch_tool_type` to `function` after inheriting the rest of the
    `gpt-5.4` model metadata.
    - Update the catalog test expectation so the CMB entry continues to
    track `gpt-5.4` metadata except for this Bedrock-specific tool shape
    override.
    
    ## Verification
    
    - `cargo test -p codex-model-provider`
    - `just fix -p codex-model-provider`
  • feat: let model providers own model discovery (#18950)
    ## Why
    
    `codex-models-manager` had grown to own provider-specific concerns:
    constructing OpenAI-compatible `/models` requests, resolving provider
    auth, emitting request telemetry, and deciding how provider catalogs
    should be sourced. That made the manager harder to reuse for providers
    whose model catalog is not fetched from the OpenAI `/models` endpoint,
    such as Amazon Bedrock.
    
    This change moves provider-specific model discovery behind
    provider-owned implementations, so the models manager can focus on
    refresh policy, cache behavior, picker ordering, and model metadata
    merging.
    
    ## What Changed
    
    - Introduced a `ModelsManager` trait with separate `OpenAiModelsManager`
    and `StaticModelsManager` implementations.
    - Added `ModelsEndpointClient` so OpenAI-compatible HTTP fetching lives
    outside `codex-models-manager`.
    - Moved `/models` request construction, provider auth resolution,
    timeout handling, and request telemetry into `codex-model-provider` via
    `OpenAiModelsEndpoint`.
    - Added provider-owned `models_manager(...)` construction so configured
    OpenAI-compatible providers use `OpenAiModelsManager`, while
    static/catalog-backed providers can return `StaticModelsManager`.
    - Added an Amazon Bedrock static model catalog for the GPT OSS Bedrock
    model IDs.
    - Updated core/session/thread manager code and tests to depend on
    `Arc<dyn ModelsManager>`.
    - Moved offline model test helpers into
    `codex_models_manager::test_support`.
    ## Metadata References
    
    The Bedrock catalog metadata is based on the official Amazon Bedrock
    OpenAI model documentation:
    
    - [Amazon Bedrock OpenAI
    models](https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-openai.html)
    lists the Bedrock model IDs, text input/output modalities, and `128,000`
    token context window for `gpt-oss-20b` and `gpt-oss-120b`.
    - [Amazon Bedrock `gpt-oss-120b` model
    card](https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-openai-gpt-oss-120b.html)
    lists the `bedrock-runtime` model ID `openai.gpt-oss-120b-1:0`, the
    `bedrock-mantle` model ID `openai.gpt-oss-120b`, text-only modalities,
    and `128K` context window.
    - [OpenAI `gpt-oss-120b` model
    docs](https://developers.openai.com/api/docs/models/gpt-oss-120b)
    document configurable reasoning effort with `low`, `medium`, and `high`,
    plus text input/output modality.
    
    The display names, default reasoning effort, and priority ordering are
    Codex-local catalog choices.
    
    ## Test Plan
    - Manually verified app-server model listing with an AWS profile:
    
    ```shell
    CODEX_HOME="$(mktemp -d)" cargo run -p codex-app-server-test-client -- \
      --codex-bin ./target/debug/codex \
      -c 'model_provider="amazon-bedrock"' \
      -c 'model_providers.amazon-bedrock.aws.profile="codex-bedrock"' \
      -c 'model_providers.amazon-bedrock.aws.region="us-west-2"' \
      model-list
    ```
    
    The response returned the Bedrock catalog with `openai.gpt-oss-120b-1:0`
    as the default model and `openai.gpt-oss-20b-1:0` as the second listed
    model, both text-only and supporting low/medium/high reasoning effort.
  • feat: expose AWS account state from account/read (#19048)
    ## Why
    
    AWS/Bedrock mode currently reports `account: null` with
    `requiresOpenaiAuth: false` from `account/read`. That suppresses the
    OpenAI-auth requirement, but it does not let app clients distinguish AWS
    auth from any other non-OpenAI custom provider. For the prototype AWS
    provider UX, clients need a simple provider-derived signal so they can
    suppress ChatGPT/API-key login and token-refresh paths without
    hardcoding Bedrock checks.
    
    ## What changed
    
    - Adds an `aws` variant to the v2 `Account` protocol union.
    - Adds `ProviderAccountKind` to `codex-model-provider` so the runtime
    provider owns the app-visible account classification.
    - Makes Amazon Bedrock return `ProviderAccountKind::Aws` from the
    model-provider layer.
    - Updates app-server `account/read` to map `ProviderAccountKind` to the
    existing `GetAccountResponse` wire shape.
    - Preserves the existing `account: null, requiresOpenaiAuth: false`
    behavior for other non-OpenAI providers.
    - Regenerates the app-server protocol schema fixtures.
    - Adds coverage for provider account classification and for the Amazon
    Bedrock `account/read` response.
    
    ## Testing
    
    - `cargo test -p codex-model-provider`
    - `cargo test -p codex-app-server-protocol`
    - `cargo test -p codex-app-server get_account_with_aws_provider`
    
    ## Notes
    
    I attempted `just bazel-lock-update` and `just bazel-lock-check`, but
    both are blocked in my local environment because `bazel` is not
    installed.
  • refactor: route Codex auth through AuthProvider (#18811)
    ## Summary
    
    This PR moves Codex backend request authentication from direct
    bearer-token handling to `AuthProvider`.
    
    The new `codex-auth-provider` crate defines the shared request-auth
    trait. `CodexAuth::provider()` returns a provider that can apply all
    headers needed for the selected auth mode.
    
    This lets ChatGPT token auth and AgentIdentity auth share the same
    callsite path:
    - ChatGPT token auth applies bearer auth plus account/FedRAMP headers
    where needed.
    - AgentIdentity auth applies AgentAssertion plus account/FedRAMP headers
    where needed.
    
    Reference old stack: https://github.com/openai/codex/pull/17387/changes
    
    ## Callsite Migration
    
    | Area | Change |
    | --- | --- |
    | backend-client | accepts an `AuthProvider` instead of a raw
    token/header |
    | chatgpt client/connectors | applies auth through
    `CodexAuth::provider()` |
    | cloud tasks | keeps Codex-backend gating, applies auth through
    provider |
    | cloud requirements | uses Codex-backend auth checks and provider
    headers |
    | app-server remote control | applies provider headers for backend calls
    |
    | MCP Apps/connectors | gates on `uses_codex_backend()` and keys caches
    from generic account getters |
    | model refresh | treats AgentIdentity as Codex-backend auth |
    | OpenAI file upload path | rejects non-Codex-backend auth before
    applying headers |
    | core client setup | keeps model-provider auth flow and allows
    AgentIdentity through provider-backed OpenAI auth |
    
    ## Stack
    
    1. https://github.com/openai/codex/pull/18757: full revert
    2. https://github.com/openai/codex/pull/18871: isolated Agent Identity
    crate
    3. https://github.com/openai/codex/pull/18785: explicit AgentIdentity
    auth mode and startup task allocation
    4. This PR: migrate Codex backend auth callsites through AuthProvider
    5. https://github.com/openai/codex/pull/18904: accept AgentIdentity JWTs
    and load `CODEX_AGENT_IDENTITY`
    
    ## Testing
    
    Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
  • chore: remove unused Bedrock auth lazy loading (#18948)
    ## Summary
    
    The Bedrock Mantle SigV4 auth provider currently looks like it can
    lazily load `AwsAuthContext`, but the provider is only constructed after
    `resolve_auth_method` has already loaded that context. Because
    `with_context` always pre-populates the `OnceCell`, the
    `get_or_try_init` fallback is unused in normal operation and makes the
    provider lifecycle harder to reason about.
    
    This change removes that dead lazy-loading path and makes the actual
    behavior explicit:
    
    - `BedrockAuthMethod::AwsSdkAuth` carries only the resolved
    `AwsAuthContext`.
    - `BedrockMantleSigV4AuthProvider` stores the resolved context directly.
    - request signing uses the stored context without going through
    `OnceCell`.
    
    The existing eager AWS auth resolution behavior is unchanged; this is a
    simplification of the provider state, not a behavior change.
    
    ## Testing
    
    - `cargo shear`
    - `cargo test -p codex-model-provider`
    - `just bazel-lock-check`
  • feat: add AWS SigV4 auth for OpenAI-compatible model providers (#17820)
    ## Summary
    
    Add first-class Amazon Bedrock Mantle provider support so Codex can keep
    using its existing Responses API transport with OpenAI-compatible
    AWS-hosted endpoints such as AOA/Mantle.
    
    This is needed for the AWS launch path, where provider traffic should
    authenticate with AWS credentials instead of OpenAI bearer credentials.
    Requests are authenticated immediately before transport send, so SigV4
    signs the final method, URL, headers, and body bytes that `reqwest` will
    send.
    
    ## What Changed
    
    - Added a new `codex-aws-auth` crate for loading AWS SDK config,
    resolving credentials, and signing finalized HTTP requests with AWS
    SigV4.
    - Added a built-in `amazon-bedrock` provider that targets Bedrock Mantle
    Responses endpoints, defaults to `us-east-1`, supports region/profile
    overrides, disables WebSockets, and does not require OpenAI auth.
    - Added Amazon Bedrock auth resolution in `codex-model-provider`: prefer
    `AWS_BEARER_TOKEN_BEDROCK` when set, otherwise use AWS SDK credentials
    and SigV4 signing.
    - Added `AuthProvider::apply_auth` and `Request::prepare_body_for_send`
    so request-signing providers can sign the exact outbound request after
    JSON serialization/compression.
    - Determine the region by taking the `aws.region` config first (required
    for bearer token codepath), and fallback to SDK default region.
    
    ## Testing
    Amazon Bedrock Mantle Responses paths:
    
    - Built the local Codex binary with `cargo build`.
    - Verified the custom proxy-backed `aws` provider using `env_key =
    "AWS_BEARER_TOKEN_BEDROCK"` streamed raw `responses` output with
    `response.output_text.delta`, `response.completed`, and `mantle-env-ok`.
    - Verified a full `codex exec --profile aws` turn returned
    `mantle-env-ok`.
    - Confirmed the custom provider used the bearer env var, not AWS profile
    auth: bogus `AWS_PROFILE` still passed, empty env var failed locally,
    and malformed env var reached Mantle and failed with `401
    invalid_api_key`.
    - Verified built-in `amazon-bedrock` with `AWS_BEARER_TOKEN_BEDROCK` set
    passed despite bogus AWS profiles, returning `amazon-bedrock-env-ok`.
    - Verified built-in `amazon-bedrock` SDK/SigV4 auth passed with
    `AWS_BEARER_TOKEN_BEDROCK` unset and temporary AWS session env
    credentials, returning `amazon-bedrock-sdk-env-ok`.
  • fix: fully revert agent identity runtime wiring (#18757)
    ## Summary
    
    This PR fully reverts the previously merged Agent Identity runtime
    integration from the old stack:
    https://github.com/openai/codex/pull/17387/changes
    
    It removes the Codex-side task lifecycle wiring, rollout/session
    persistence, feature flag plumbing, lazy `auth.json` mutation,
    background task auth paths, and request callsite changes introduced by
    that stack.
    
    This leaves the repo in a clean pre-AgentIdentity integration state so
    the follow-up PRs can reintroduce the pieces in smaller reviewable
    layers.
    
    ## Stack
    
    1. This PR: full revert
    2. https://github.com/openai/codex/pull/18871: move Agent Identity
    business logic into a crate
    3. https://github.com/openai/codex/pull/18785: add explicit
    AgentIdentity auth mode and startup task allocation
    4. https://github.com/openai/codex/pull/18811: migrate auth callsites
    through AuthProvider
    
    ## Testing
    
    Tests: targeted Rust checks, cargo-shear, Bazel lock check, and CI.
  • [codex] Use AgentAssertion downstream behind use_agent_identity (#17980)
    ## Summary
    
    This is the AgentAssertion downstream slice for feature-gated agent
    identity support, replacing the oversized AgentAssertion slice from PR
    #17807.
    
    It isolates task-scoped downstream AgentAssertion wiring on top of the
    merged PR3.1 work without re-carrying the earlier agent registration,
    task registration, or task-state history.
    
    This PR includes the task-scoped bug-fix call sites from the review:
    generic file upload auth, MCP OpenAI file upload auth, and ARC monitor
    auth. Broader user/control-plane calls move to PR4.1 and PR4.2.
    
    ## Stack
    
    - PR1: https://github.com/openai/codex/pull/17385 - add
    `features.use_agent_identity`
    - PR2: https://github.com/openai/codex/pull/17386 - register agent
    identities when enabled
    - PR3: https://github.com/openai/codex/pull/17387 - register agent tasks
    when enabled
    - PR3.1: https://github.com/openai/codex/pull/17978 - persist and
    prewarm registered tasks per thread
    - PR4: this PR - use task-scoped `AgentAssertion` downstream when
    enabled
    - PR4.1: https://github.com/openai/codex/pull/18094 - introduce
    AuthManager-owned background/control-plane `AgentAssertion` auth
    - PR4.2: https://github.com/openai/codex/pull/18260 - use background
    task auth for additional backend/control-plane calls
    
    ## What Changed
    
    - add AgentAssertion envelope generation in `codex-core`
    - route downstream HTTP and websocket auth through AgentAssertion when
    an agent task is present
    - extend the model-provider auth provider so non-bearer authorization
    schemes can be passed through cleanly
    - make generic file uploads attach the full authorization header value
    - make MCP OpenAI file uploads use the cached thread agent task
    assertion when present
    - make ARC monitor calls use the cached thread agent task assertion when
    present
    
    ## Why
    
    The original PR had drifted ancestry and showed a much larger diff than
    the semantic change actually required. Restacking it onto PR3.1 keeps
    the reviewable surface down to the downstream assertion slice.
    
    ## Validation
    
    - `just fmt`
    - `cargo check -p codex-core -p codex-login -p codex-analytics -p
    codex-app-server -p codex-cloud-requirements -p codex-cloud-tasks -p
    codex-models-manager -p codex-chatgpt -p codex-model-provider -p
    codex-mcp -p codex-core-skills`
    - `cargo test -p codex-model-provider bearer_auth_provider`
    - `cargo test -p codex-core agent_assertion`
    - `cargo test -p codex-app-server remote_control`
    - `cargo test -p codex-cloud-requirements fetch_cloud_requirements`
    - `cargo test -p codex-models-manager manager::tests`
    - `cargo test -p codex-chatgpt`
    - `cargo test -p codex-cloud-tasks`
    - `cargo test -p codex-login agent_identity`
    - `just fix -p codex-core -p codex-login -p codex-analytics -p
    codex-app-server -p codex-cloud-requirements -p codex-cloud-tasks -p
    codex-models-manager -p codex-chatgpt -p codex-model-provider -p
    codex-mcp -p codex-core-skills`
    - `just fix -p codex-app-server`
    - `git diff --check`
  • feat: add opt-in provider runtime abstraction (#17713)
    ## Summary
    
    - Add `codex-model-provider` as the runtime home for model-provider
    behavior that does not belong in `codex-core`, `codex-login`, or
    `codex-api`.
    - The new crate wraps configured `ModelProviderInfo` in a
    `ModelProvider` trait object that can resolve the API provider config,
    provider-scoped auth manager, and request auth provider for each call.
    - This centralizes provider auth behavior in one place today, and gives
    us an extension point for future provider-specific auth, model listing,
    request setup, and related runtime behavior.
    
    ## Tests
    Ran tests manually to make sure that provider auth under different
    configs still work as expected.
    
    ---------
    
    Co-authored-by: pakrym-oai <pakrym@openai.com>