30 Commits

  • Added back codex-rs/config.md to link to new location (#2778)
    Quick fix: point old config.md to new location
  • README / docs refactor (#2724)
    This PR cleans up the monolithic README by breaking it into a set
    navigable pages under docs/ (install, getting started, configuration,
    authentication, sandboxing and approvals, platform details, FAQ, ZDR,
    contributing, license). The top‑level README is now more concise and
    intuitive, (with corrected screenshots).
    
    It also consolidates overlapping content from codex-rs/README.md into
    the top‑level docs and updates links accordingly. The codex-rs README
    remains in place for now as a pointer and for continuity.
    
    Finally, added an extensive config reference table at the bottom of
    docs/config.md.
    
    ---------
    
    Co-authored-by: easong-openai <easong@openai.com>
  • feat(gpt5): add model_verbosity for GPT‑5 via Responses API (#2108)
    **Summary**
    - Adds `model_verbosity` config (values: low, medium, high).
    - Sends `text.verbosity` only for GPT‑5 family models via the Responses
    API.
    - Updates docs and adds serialization tests.
    
    **Motivation**
    - GPT‑5 introduces a verbosity control to steer output length/detail
    without pro
    mpt surgery.
    - Exposing it as a config knob keeps prompts stable and makes behavior
    explicit
    and repeatable.
    
    **Changes**
    - Config:
      - Added `Verbosity` enum (low|medium|high).
    - Added optional `model_verbosity` to `ConfigToml`, `Config`, and
    `ConfigProfi
    le`.
    - Request wiring:
      - Extended `ResponsesApiRequest` with optional `text` object.
    - Populates `text.verbosity` only when model family is `gpt-5`; omitted
    otherw
    ise.
    - Tests:
    - Verifies `text.verbosity` serializes when set and is omitted when not
    set.
    - Docs:
      - Added “GPT‑5 Verbosity” section in `codex-rs/README.md`.
      - Added `model_verbosity` section to `codex-rs/config.md`.
    
    **Usage**
    - In `~/.codex/config.toml`:
      - `model = "gpt-5"`
      - `model_verbosity = "low"` (or `"medium"` default, `"high"`)
    - CLI override example:
      - `codex -c model="gpt-5" -c model_verbosity="high"`
    
    **API Impact**
    - Requests to GPT‑5 via Responses API include: `text: { verbosity:
    "low|medium|h
    igh" }` when configured.
    - For legacy models or Chat Completions providers, `text` is omitted.
    
    **Backward Compatibility**
    - Default behavior unchanged when `model_verbosity` is not set (server
    default “
    medium”).
    
    **Testing**
    - Added unit tests for serialization/omission of `text.verbosity`.
    - Ran `cargo fmt` and `cargo test --all-features` (all green).
    
    **Docs**
    - `README.md`: new “GPT‑5 Verbosity” note under Config with example.
    - `config.md`: new `model_verbosity` section.
    
    **Out of Scope**
    - No changes to temperature/top_p or other GPT‑5 parameters.
    - No changes to Chat Completions wiring.
    
    **Risks / Notes**
    - If OpenAI changes the wire shape for verbosity, we may need to update
    `Respons
    esApiRequest`.
    - Behavior gated to `gpt-5` model family to avoid unexpected effects
    elsewhere.
    
    **Checklist**
    - [x] Code gated to GPT‑5 family only
    - [x] Docs updated (`README.md`, `config.md`)
    - [x] Tests added and passing
    - [x] Formatting applied
    
    Release note: Add `model_verbosity` config to control GPT‑5 output verbosity via the Responses API (low|medium|high).
  • docs: update codex-rs/config.md to reflect that gpt-5 is the default model (#2199)
    `gpt-5` has replaced `codex-mini-latest` as the default.
  • feat: change shell_environment_policy to default to inherit="all" (#1904)
    Trying to use `core` as the default has been "too clever." Users can
    always take responsibility for controlling the env without this setting
    at all by specifying the `env` they use when calling `codex` in the
    first place.
    
    See https://github.com/openai/codex/issues/1249.
  • chore: fix outstanding review comments from the bot on #1919 (#1928)
    I should have read the comments before submitting!
  • feat: add /tmp by default (#1919)
    Replaces the `include_default_writable_roots` option on
    `sandbox_workspace_write` (that defaulted to `true`, which was slightly
    weird/annoying) with `exclude_tmpdir_env_var`, which defaults to
    `false`.
    
    Though perhaps more importantly `/tmp` is now enabled by default as part
    of `sandbox_mode = "workspace-write"`, though `exclude_slash_tmp =
    false` can be used to disable this.
  • [approval_policy] Add OnRequest approval_policy (#1865)
    ## Summary
    A split-up PR of #1763 , stacked on top of a tools refactor #1858 to
    make the change clearer. From the previous summary:
    
    > Let's try something new: tell the model about the sandbox, and let it
    decide when it will need to break the sandbox. Some local testing
    suggests that it works pretty well with zero iteration on the prompt!
    
    ## Testing
    - [x] Added unit tests
    - [x] Tested locally and it appears to work smoothly!
  • Rescue chat completion changes (#1846)
    https://github.com/openai/codex/pull/1835 has some messed up history.
    
    This adds support for streaming chat completions, which is useful for ollama. We should probably take a very skeptical eye to the code introduced in this PR.
    
    ---------
    
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
  • feat: make .git read-only within a writable root when using Seatbelt (#1765)
    To make `--full-auto` safer, this PR updates the Seatbelt policy so that
    a `SandboxPolicy` with a `writable_root` that contains a `.git/`
    _directory_ will make `.git/` _read-only_ (though as a follow-up, we
    should also consider the case where `.git` is a _file_ with a `gitdir:
    /path/to/actual/repo/.git` entry that should also be protected).
    
    The two major changes in this PR:
    
    - Updating `SandboxPolicy::get_writable_roots_with_cwd()` to return a
    `Vec<WritableRoot>` instead of a `Vec<PathBuf>` where a `WritableRoot`
    can specify a list of read-only subpaths.
    - Updating `create_seatbelt_command_args()` to honor the read-only
    subpaths in `WritableRoot`.
    
    The logic to update the policy is a fairly straightforward update to
    `create_seatbelt_command_args()`, but perhaps the more interesting part
    of this PR is the introduction of an integration test in
    `tests/sandbox.rs`. Leveraging the new API in #1785, we test
    `SandboxPolicy` under various conditions, including ones where `$TMPDIR`
    is not readable, which is critical for verifying the new behavior.
    
    To ensure that Codex can run its own tests, e.g.:
    
    ```
    just codex debug seatbelt --full-auto -- cargo test if_git_repo_is_writable_root_then_dot_git_folder_is_read_only
    ```
    
    I had to introduce the use of `CODEX_SANDBOX=sandbox`, which is
    comparable to how `CODEX_SANDBOX_NETWORK_DISABLED=1` was already being
    used.
    
    Adding a comparable change for Landlock will be done in a subsequent PR.
  • Add support for a separate chatgpt auth endpoint (#1712)
    Adds a `CodexAuth` type that encapsulates information about available
    auth modes and logic for refreshing the token.
    Changes `Responses` API to send requests to different endpoints based on
    the auth type.
    Updates login_with_chatgpt to support API-less mode and skip the key
    exchange.
  • Easily Selectable History (#1672)
    This update replaces the previous ratatui history widget with an
    append-only log so that the terminal can handle text selection and
    scrolling. It also disables streaming responses, which we'll do our best
    to bring back in a later PR. It also adds a small summary of token use
    after the TUI exits.
  • Refactor env settings into config (#1601)
    ## Summary
    - add OpenAI retry and timeout fields to Config
    - inject these settings in tests instead of mutating env vars
    - plumb Config values through client and chat completions logic
    - document new configuration options
    
    ## Testing
    - `cargo test -p codex-core --no-run`
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68792c5b04cc832195c03050c8b6ea94
    
    ---------
    
    Co-authored-by: Michael Bolin <mbolin@openai.com>
  • feat: add new config option: model_supports_reasoning_summaries (#1524)
    As noted in the updated docs, this makes it so that you can set:
    
    ```toml
    model_supports_reasoning_summaries = true
    ```
    
    as a way of overriding the existing heuristic for when to set the
    `reasoning` field on a sampling request:
    
    
    https://github.com/openai/codex/blob/341c091c5b09dc706ab5c7d629516e6ef5aaf902/codex-rs/core/src/client_common.rs#L152-L166
  • feat: honor OPENAI_BASE_URL for the built-in openai provider (#1487)
    Some users have proxies or other setups where they are ultimately
    hitting OpenAI endpoints, but need a custom `base_url` rather than the
    default value of `"https://api.openai.com/v1"`. This PR makes it
    possible to override the `base_url` for the `openai` provider via the
    `OPENAI_BASE_URL` environment variable.
  • feat: add support for --sandbox flag (#1476)
    On a high-level, we try to design `config.toml` so that you don't have
    to "comment out a lot of stuff" when testing different options.
    
    Previously, defining a sandbox policy was somewhat at odds with this
    principle because you would define the policy as attributes of
    `[sandbox]` like so:
    
    ```toml
    [sandbox]
    mode = "workspace-write"
    writable_roots = [ "/tmp" ]
    ```
    
    but if you wanted to temporarily change to a read-only sandbox, you
    might feel compelled to modify your file to be:
    
    ```toml
    [sandbox]
    mode = "read-only"
    # mode = "workspace-write"
    # writable_roots = [ "/tmp" ]
    ```
    
    Technically, commenting out `writable_roots` would not be strictly
    necessary, as `mode = "read-only"` would ignore `writable_roots`, but
    it's still a reasonable thing to do to keep things tidy.
    
    Currently, the various values for `mode` do not support that many
    attributes, so this is not that hard to maintain, but one could imagine
    this becoming more complex in the future.
    
    In this PR, we change Codex CLI so that it no longer recognizes
    `[sandbox]`. Instead, it introduces a top-level option, `sandbox_mode`,
    and `[sandbox_workspace_write]` is used to further configure the sandbox
    when when `sandbox_mode = "workspace-write"` is used:
    
    ```toml
    sandbox_mode = "workspace-write"
    
    [sandbox_workspace_write]
    writable_roots = [ "/tmp" ]
    ```
    
    This feels a bit more future-proof in that it is less tedious to
    configure different sandboxes:
    
    ```toml
    sandbox_mode = "workspace-write"
    
    [sandbox_read_only]
    # read-only options here...
    
    [sandbox_workspace_write]
    writable_roots = [ "/tmp" ]
    
    [sandbox_danger_full_access]
    # danger-full-access options here...
    ```
    
    In this scheme, you never need to comment out the configuration for an
    individual sandbox type: you only need to redefine `sandbox_mode`.
    
    Relatedly, previous to this change, a user had to do `-c
    sandbox.mode=read-only` to change the mode on the command line. With
    this change, things are arguably a bit cleaner because the equivalent
    option is `-c sandbox_mode=read-only` (and now `-c
    sandbox_workspace_write=...` can be set separately).
    
    Though more importantly, we introduce the `-s/--sandbox` option to the
    CLI, which maps directly to `sandbox_mode` in `config.toml`, making
    config override behavior easier to reason about. Moreover, as you can
    see in the updates to the various Markdown files, it is much easier to
    explain how to configure sandboxing when things like `--sandbox
    read-only` can be used as an example.
    
    Relatedly, this cleanup also made it straightforward to add support for
    a `sandbox` option for Codex when used as an MCP server (see the changes
    to `mcp-server/src/codex_tool_config.rs`).
    
    Fixes https://github.com/openai/codex/issues/1248.
  • feat: support custom HTTP headers for model providers (#1473)
    This adds support for two new model provider config options:
    
    - `http_headers` for hardcoded (key, value) pairs
    - `env_http_headers` for headers whose values should be read from
    environment variables
    
    This also updates the built-in `openai` provider to use this feature to
    set the following headers:
    
    - `originator` => `codex_cli_rs`
    - `version` => [CLI version]
    - `OpenAI-Organization` => `OPENAI_ORGANIZATION` env var
    - `OpenAI-Project` => `OPENAI_PROJECT` env var
    
    for consistency with the TypeScript implementation:
    
    
    https://github.com/openai/codex/blob/bd5a9e8ba96c7d9c58ecaf5e61ec62d14ac6378d/codex-cli/src/utils/agent/agent-loop.ts#L321-L329
    
    While here, this also consolidates some logic that was duplicated across
    `client.rs` and `chat_completions.rs` by introducing
    `ModelProviderInfo.create_request_builder()`.
    
    Resolves https://github.com/openai/codex/discussions/1152
  • feat: add query_params option to ModelProviderInfo to support Azure (#1435)
    As discovered in https://github.com/openai/codex/issues/1365, the Azure
    provider needs to be able to specify `api-version` as a query param, so
    this PR introduces a generic `query_params` option to the
    `model_providers` config so that an Azure provider can be defined as
    follows:
    
    ```toml
    [model_providers.azure]
    name = "Azure"
    base_url = "https://YOUR_PROJECT_NAME.openai.azure.com/openai"
    env_key = "AZURE_OPENAI_API_KEY"
    query_params = { api-version = "2025-04-01-preview" }
    ```
    
    This PR also updates the docs with this example.
    
    While here, we also update `wire_api` to default to `"chat"`, as that is
    likely the common case for someone defining an external provider.
    
    Fixes https://github.com/openai/codex/issues/1365.
  • chore: change built_in_model_providers so "openai" is the only "bundled" provider (#1407)
    As we are [close to releasing the Rust CLI
    beta](https://github.com/openai/codex/discussions/1405), for the moment,
    let's take a more neutral stance on what it takes to be a "built-in"
    provider.
    
    * For example, there seems to be a discrepancy around what the "right"
    configuration for Gemini is: https://github.com/openai/codex/pull/881
    * And while the current list of "built-in" providers are all arguably
    "well-known" names, this raises a question of what to do about
    potentially less familiar providers, such as
    https://github.com/openai/codex/pull/1142. Do we just accept every pull
    request like this, or is there some criteria a provider has to meet to
    "qualify" to be bundled with Codex CLI?
    
    I think that if we can establish clear ground rules for being a built-in
    provider, then we can bring this back. But until then, I would rather
    take a minimalist approach because if we decided to reverse our position
    later, it would break folks who were depending on the presence of the
    built-in providers.
  • feat: show number of tokens remaining in UI (#1388)
    When using the OpenAI Responses API, we now record the `usage` field for
    a `"response.completed"` event, which includes metrics about the number
    of tokens consumed. We also introduce `openai_model_info.rs`, which
    includes current data about the most common OpenAI models available via
    the API (specifically `context_window` and `max_output_tokens`). If
    Codex does not recognize the model, you can set `model_context_window`
    and `model_max_output_tokens` explicitly in `config.toml`.
    
    When then introduce a new event type to `protocol.rs`, `TokenCount`,
    which includes the `TokenUsage` for the most recent turn.
    
    Finally, we update the TUI to record the running sum of tokens used so
    the percentage of available context window remaining can be reported via
    the placeholder text for the composer:
    
    ![Screenshot 2025-06-25 at 11 20
    55 PM](https://github.com/user-attachments/assets/6fd6982f-7247-4f14-84b2-2e600cb1fd49)
    
    We could certainly get much fancier with this (such as reporting the
    estimated cost of the conversation), but for now, we are just trying to
    achieve feature parity with the TypeScript CLI.
    
    Though arguably this improves upon the TypeScript CLI, as the TypeScript
    CLI uses heuristics to estimate the number of tokens used rather than
    using the `usage` information directly:
    
    
    https://github.com/openai/codex/blob/296996d74e345b1b05d8c3451a06ace21c5ada96/codex-cli/src/utils/approximate-tokens-used.ts#L3-L16
    
    Fixes https://github.com/openai/codex/issues/1242
  • chore: rename unless-allow-listed to untrusted (#1378)
    For the `approval_policy` config option, renames `unless-allow-listed`
    to `untrusted`. In general, when it comes to exec'ing commands, I think
    "trusted" is a more accurate term than "safe."
    
    Also drops the `AskForApproval::AutoEdit` variant, as we were not really
    making use of it, anyway.
    
    Fixes https://github.com/openai/codex/issues/1250.
    
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/1378).
    * #1379
    * __->__ #1378
  • feat: redesign sandbox config (#1373)
    This is a major redesign of how sandbox configuration works and aims to
    fix https://github.com/openai/codex/issues/1248. Specifically, it
    replaces `sandbox_permissions` in `config.toml` (and the
    `-s`/`--sandbox-permission` CLI flags) with a "table" with effectively
    three variants:
    
    ```toml
    # Safest option: full disk is read-only, but writes and network access are disallowed.
    [sandbox]
    mode = "read-only"
    
    # The cwd of the Codex task is writable, as well as $TMPDIR on macOS.
    # writable_roots can be used to specify additional writable folders.
    [sandbox]
    mode = "workspace-write"
    writable_roots = []  # Optional, defaults to the empty list.
    network_access = false  # Optional, defaults to false.
    
    # Disable sandboxing: use at your own risk!!!
    [sandbox]
    mode = "danger-full-access"
    ```
    
    This should make sandboxing easier to reason about. While we have
    dropped support for `-s`, the way it works now is:
    
    - no flags => `read-only`
    - `--full-auto` => `workspace-write`
    - currently, there is no way to specify `danger-full-access` via a CLI
    flag, but we will revisit that as part of
    https://github.com/openai/codex/issues/1254
    
    Outstanding issue:
    
    - As noted in the `TODO` on `SandboxPolicy::is_unrestricted()`, we are
    still conflating sandbox preferences with approval preferences in that
    case, which needs to be cleaned up.
  • feat: make reasoning effort/summaries configurable (#1199)
    Previous to this PR, we always set `reasoning` when making a request
    using the Responses API:
    
    
    https://github.com/openai/codex/blob/d7245cbbc9d8ff5446da45e5951761103492476d/codex-rs/core/src/client.rs#L108-L111
    
    Though if you tried to use the Rust CLI with `--model gpt-4.1`, this
    would fail with:
    
    ```shell
    "Unsupported parameter: 'reasoning.effort' is not supported with this model."
    ```
    
    We take a cue from the TypeScript CLI, which does a check on the model
    name:
    
    
    https://github.com/openai/codex/blob/d7245cbbc9d8ff5446da45e5951761103492476d/codex-cli/src/utils/agent/agent-loop.ts#L786-L789
    
    This PR does a similar check, though also adds support for the following
    config options:
    
    ```
    model_reasoning_effort = "low" | "medium" | "high" | "none"
    model_reasoning_summary = "auto" | "concise" | "detailed" | "none"
    ```
    
    This way, if you have a model whose name happens to start with `"o"` (or
    `"codex"`?), you can set these to `"none"` to explicitly disable
    reasoning, if necessary. (That said, it seems unlikely anyone would use
    the Responses API with non-OpenAI models, but we provide an escape
    hatch, anyway.)
    
    This PR also updates both the TUI and `codex exec` to show `reasoning
    effort` and `reasoning summaries` in the header.
  • feat: add hide_agent_reasoning config option (#1181)
    This PR introduces a `hide_agent_reasoning` config option (that defaults
    to `false`) that users can enable to make the output less verbose by
    suppressing reasoning output.
    
    To test, verified that this includes agent reasoning in the output:
    
    ```
    echo hello | just exec
    ```
    
    whereas this does not:
    
    ```
    echo hello | just exec --config hide_agent_reasoning=false
    ```
  • docs: split the config-related portion of codex-rs/README.md into its own config.md file (#1165)
    Also updated the overview on `codex-rs/README.md` while here.