Commit Graph

32 Commits

  • feat: split codex-common into smaller utils crates (#11422)
    We are removing feature-gated shared crates from the `codex-rs`
    workspace. `codex-common` grouped several unrelated utilities behind
    `[features]`, which made dependency boundaries harder to reason about
    and worked against the ongoing effort to eliminate feature flags from
    workspace crates.
    
    Splitting these utilities into dedicated crates under `utils/` aligns
    this area with existing workspace structure and keeps each dependency
    explicit at the crate boundary.
    
    ## What changed
    
    - Removed `codex-rs/common` (`codex-common`) from workspace members and
    workspace dependencies.
    - Added six new utility crates under `codex-rs/utils/`:
      - `codex-utils-cli`
      - `codex-utils-elapsed`
      - `codex-utils-sandbox-summary`
      - `codex-utils-approval-presets`
      - `codex-utils-oss`
      - `codex-utils-fuzzy-match`
    - Migrated the corresponding modules out of `codex-common` into these
    crates (with tests), and added matching `BUILD.bazel` targets.
    - Updated direct consumers to use the new crates instead of
    `codex-common`:
      - `codex-rs/cli`
      - `codex-rs/tui`
      - `codex-rs/exec`
      - `codex-rs/app-server`
      - `codex-rs/mcp-server`
      - `codex-rs/chatgpt`
      - `codex-rs/cloud-tasks`
    - Updated workspace lockfile entries to reflect the new dependency graph
    and removal of `codex-common`.
  • add WebSearchMode enum (#9216)
    ### What
    Add `WebSearchMode` enum (disabled, cached live, defaults to cached) to
    config + V2 protocol. This enum takes precedence over legacy flags:
    `web_search_cached`, `web_search_request`, and `tools.web_search`.
    
    Keep `--search` as live.
    
    ### Tests
    Added tests
  • ollama: default to Responses API for built-ins (#8798)
    This is an alternate PR to solving the same problem as
    <https://github.com/openai/codex/pull/8227>.
    
    In this PR, when Ollama is used via `--oss` (or via `model_provider =
    "ollama"`), we default it to use the Responses format. At runtime, we do
    an Ollama version check, and if the version is older than when Responses
    support was added to Ollama, we print out a warning.
    
    Because there's no way of configuring the wire api for a built-in
    provider, we temporarily add a new `oss_provider`/`model_provider`
    called `"ollama-chat"` that will force the chat format.
    
    Once the `"chat"` format is fully removed (see
    <https://github.com/openai/codex/discussions/7782>), `ollama-chat` can
    be removed as well
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
    Co-authored-by: Michael Bolin <mbolin@openai.com>
  • feat: wire fork to codex cli (#8994)
    ## Summary
    - add `codex fork` subcommand and `/fork` slash command mirroring resume
    - extend session picker to support fork/resume actions with dynamic
    labels in tui/tui2
    - wire fork selection flow through tui bootstraps and add fork-related
    tests
  • fix: add tui.alternate_screen config and --no-alt-screen CLI flag for Zellij scrollback (#8555)
    Fixes #2558
    
    Codex uses alternate screen mode (CSI 1049) which, per xterm spec,
    doesn't support scrollback. Zellij follows this strictly, so users can't
    scroll back through output.
    
    **Changes:**
    - Add `tui.alternate_screen` config: `auto` (default), `always`, `never`
    - Add `--no-alt-screen` CLI flag
    - Auto-detect Zellij and skip alt screen (uses existing `ZELLIJ` env var
    detection)
    
    **Usage:**
    ```bash
    # CLI flag
    codex --no-alt-screen
    
    # Or in config.toml
    [tui]
    alternate_screen = "never"
    ```
    
    With default `auto` mode, Zellij users get working scrollback without
    any config changes.
    
    ---------
    
    Co-authored-by: Josh McKinney <joshka@openai.com>
  • tui: add branch to 'codex resume', filter by cwd (#6232)
    By default, show only sessions that shared a cwd with the current cwd.
    `--all` shows all sessions in all cwds. Also, show the branch name from
    the rollout metadata.
    
    <img width="1091" height="638" alt="Screenshot 2025-11-04 at 3 30 47 PM"
    src="https://github.com/user-attachments/assets/aae90308-6115-455f-aff7-22da5f1d9681"
    />
  • LM Studio OSS Support (#2312)
    ## Overview
    
    Adds LM Studio OSS support. Closes #1883
    
    
    ### Changes
    This PR enhances the behavior of `--oss` flag to support LM Studio as a
    provider. Additionally, it introduces a new flag`--local-provider` which
    can take in `lmstudio` or `ollama` as values if the user wants to
    explicitly choose which one to use.
    
    If no provider is specified `codex --oss` will auto-select the provider
    based on whichever is running.
    
    #### Additional enhancements 
    The default can be set using `oss-provider` in config like:
    
    ```
    oss_provider = "lmstudio"
    ```
    
    For non-interactive users, they will need to either provide the provider
    as an arg or have it in their `config.toml`
    
    ### Notes
    For best performance, [set the default context
    length](https://lmstudio.ai/docs/app/advanced/per-model) for gpt-oss to
    the maximum your machine can support
    
    ---------
    
    Co-authored-by: Matt Clayton <matt@lmstudio.ai>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Update full-auto description with on-request (#6523)
    This PR fixes #6522 by correcting the comment for `full-auto` in both
    `codex-rs/exec/src/cli.rs` and `codex-rs/tui/src/cli.rs` from `-a
    on-failure` to `-a on-request` to make it coherent with
    `codex-rs/tui/src/lib.rs:97-105`:
    
    ```rust
    pub async fn run_main(
        mut cli: Cli,
        codex_linux_sandbox_exe: Option<PathBuf>,
    ) -> std::io::Result<AppExitInfo> {
        let (sandbox_mode, approval_policy) = if cli.full_auto {
            (
                Some(SandboxMode::WorkspaceWrite),
                Some(AskForApproval::OnRequest),
            )
    ```
    
    Running `just codex --help` or `just codex exec --help` should now yield
    the correct description of `full-auto` CLI argument.
    
    Signed-off-by: lionelchg <lionel.cheng@hotmail.fr>
  • feat: add --add-dir flag for extra writable roots (#5335)
    Add a `--add-dir` CLI flag so sessions can use extra writable roots in
    addition to the ones specified in the config file. These are ephemerally
    added during the session only.
    
    Fixes #3303
    Fixes #2797
  • cli: fix zsh completion (#4692)
    Before this change:
    ```
    tamird@L03G26TD12 codex-rs % codex
    zsh: do you wish to see all 3864 possibilities (1285 lines)?
    ```
    
    After this change:
    ```
    tamird@L03G26TD12 codex-rs % codex
    app-server              -- [experimental] Run the app server
    apply                a  -- Apply the latest diff produced by Codex agent as a `git apply` to your local working tree
    cloud                   -- [EXPERIMENTAL] Browse tasks from Codex Cloud and apply changes locally
    completion              -- Generate shell completion scripts
    debug                   -- Internal debugging commands
    exec                 e  -- Run Codex non-interactively
    generate-ts             -- Internal: generate TypeScript protocol bindings
    help                    -- Print this message or the help of the given subcommand(s)
    login                   -- Manage login
    logout                  -- Remove stored authentication credentials
    mcp                     -- [experimental] Run Codex as an MCP server and manage MCP servers
    mcp-server              -- [experimental] Run the Codex MCP server (stdio transport)
    responses-api-proxy     -- Internal: run the responses API proxy
    resume                  -- Resume a previous interactive session (picker by default; use --last to continue the most recent)
    ```
  • Fix codex resume so flags (cd, model, search, etc.) still work (#3625)
    Bug: now we can add flags/config values only before resume. 
    
    `codex -m gpt-5 resume` works
    
    However, `codex resume -m gpt-5` should also work.
    
    This PR is following this
    [approach](https://stackoverflow.com/questions/76408952/rust-clap-re-use-same-arguments-in-different-subcommand)
    in doing so.
    
    I didn't convert those flags to global because we have `codex login`
    that shouldn't expect them.
  • enable-resume (#3537)
    Adding the ability to resume conversations.
    we have one verb `resume`. 
    
    Behavior:
    
    `tui`:
    `codex resume`: opens session picker
    `codex resume --last`: continue last message
    `codex resume <session id>`: continue conversation with `session id`
    
    `exec`:
    `codex resume --last`: continue last conversation
    `codex resume <session id>`: continue conversation with `session id`
    
    Implementation:
    - I added a function to find the path in `~/.codex/sessions/` with a
    `UUID`. This is helpful in resuming with session id.
    - Added the above mentioned flags
    - Added lots of testing
  • hide resume until it's complete (#3218)
    Hide resume functionality until it's fully done.
  • TUI: Add session resume picker (--resume) and quick resume (--continue) (#3135)
    Adds a TUI resume flow with an interactive picker and quick resume.
    
    - CLI: 
      - --resume / -r: open picker to resume a prior session
      - --continue   / -l: resume the most recent session (no picker)
    - Behavior on resume: initial history is replayed, welcome banner
    hidden, and the first redraw is suppressed to avoid flicker.
    - Implementation:
    - New tui/src/resume_picker.rs (paginated listing via
    RolloutRecorder::list_conversations)
      - App::run accepts ResumeSelection; resumes from disk when requested
    - ChatWidget refactor with ChatWidgetInit and new_from_existing; replays
    initial messages
    - Tests: cover picker sorting/preview extraction and resumed-history
    rendering.
    - Docs: getting-started updated with flags and picker usage.
    
    
    
    https://github.com/user-attachments/assets/1bb6469b-e5d1-42f6-bec6-b1ae6debda3b
  • Add web search tool (#2371)
    Adds web_search tool, enabling the model to use Responses API web_search
    tool.
    - Disabled by default, enabled by --search flag
    - When --search is passed, exposes web_search_request function tool to
    the model, which triggers user approval. When approved, the model can
    use the web_search tool for the remainder of the turn
    <img width="1033" height="294" alt="image"
    src="https://github.com/user-attachments/assets/62ac6563-b946-465c-ba5d-9325af28b28f"
    />
    
    ---------
    
    Co-authored-by: easong-openai <easong@openai.com>
  • [config] Onboarding flow with persistence (#1929)
    ## Summary
    In collaboration with @gpeal: upgrade the onboarding flow, and persist
    user settings.
    
    ---------
    
    Co-authored-by: Gabriel Peal <gabriel@openai.com>
  • Introduce --oss flag to use gpt-oss models (#1848)
    This adds support for easily running Codex backed by a local Ollama
    instance running our new open source models. See
    https://github.com/openai/gpt-oss for details.
    
    If you pass in `--oss` you'll be prompted to install/launch ollama, and
    it will automatically download the 20b model and attempt to use it.
    
    We'll likely want to expand this with some options later to make the
    experience smoother for users who can't run the 20b or want to run the
    120b.
    
    Co-authored-by: Michael Bolin <mbolin@openai.com>
  • 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: add --dangerously-bypass-approvals-and-sandbox (#1384)
    This PR reworks `assess_command_safety()` so that the combination of
    `AskForApproval::Never` and `SandboxPolicy::DangerFullAccess` ensures
    that commands are run without _any_ sandbox and the user should never be
    prompted. In turn, it adds support for a new
    `--dangerously-bypass-approvals-and-sandbox` flag (that cannot be used
    with `--approval-policy` or `--full-auto`) that sets both of those
    options.
    
    Fixes https://github.com/openai/codex/issues/1254
  • chore: improve docstring for --full-auto (#1379)
    Reference `-c sandbox.mode=workspace-write` in the docstring and users
    can read the config docs for `sandbox` for more information.
  • 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: add support for -c/--config to override individual config items (#1137)
    This PR introduces support for `-c`/`--config` so users can override
    individual config values on the command line using `--config
    name=value`. Example:
    
    ```
    codex --config model=o4-mini
    ```
    
    Making it possible to set arbitrary config values on the command line
    results in a more flexible configuration scheme and makes it easier to
    provide single-line examples that can be copy-pasted from documentation.
    
    Effectively, it means there are four levels of configuration for some
    values:
    
    - Default value (e.g., `model` currently defaults to `o4-mini`)
    - Value in `config.toml` (e.g., user could override the default to be
    `model = "o3"` in their `config.toml`)
    - Specifying `-c` or `--config` to override `model` (e.g., user can
    include `-c model=o3` in their list of args to Codex)
    - If available, a config-specific flag can be used, which takes
    precedence over `-c` (e.g., user can specify `--model o3` in their list
    of args to Codex)
    
    Now that it is possible to specify anything that could be configured in
    `config.toml` on the command line using `-c`, we do not need to have a
    custom flag for every possible config option (which can clutter the
    output of `--help`). To that end, as part of this PR, we drop support
    for the `--disable-response-storage` flag, as users can now specify `-c
    disable_response_storage=true` to get the equivalent functionality.
    
    Under the hood, this works by loading the `config.toml` into a
    `toml::Value`. Then for each `key=value`, we create a small synthetic
    TOML file with `value` so that we can run the TOML parser to get the
    equivalent `toml::Value`. We then parse `key` to determine the point in
    the original `toml::Value` to do the insert/replace. Once all of the
    overrides from `-c` args have been applied, the `toml::Value` is
    deserialized into a `ConfigToml` and then the `ConfigOverrides` are
    applied, as before.
  • feat: introduce --profile for Rust CLI (#921)
    This introduces a much-needed "profile" concept where users can specify
    a collection of options under one name and then pass that via
    `--profile` to the CLI.
    
    This PR introduces the `ConfigProfile` struct and makes it a field of
    `CargoToml`. It further updates
    `Config::load_from_base_config_with_overrides()` to respect
    `ConfigProfile`, overriding default values where appropriate. A detailed
    unit test is added at the end of `config.rs` to verify this behavior.
    
    Details on how to use this feature have also been added to
    `codex-rs/README.md`.
  • chore: introduce codex-common crate (#843)
    I started this PR because I wanted to share the `format_duration()`
    utility function in `codex-rs/exec/src/event_processor.rs` with the TUI.
    The question was: where to put it?
    
    `core` should have as few dependencies as possible, so moving it there
    would introduce a dependency on `chrono`, which seemed undesirable.
    `core` already had this `cli` feature to deal with a similar situation
    around sharing common utility functions, so I decided to:
    
    * make `core` feature-free
    * introduce `common`
    * `common` can have as many "special interest" features as it needs,
    each of which can declare their own deps
    * the first two features of common are `cli` and `elapsed`
    
    In practice, this meant updating a number of `Cargo.toml` files,
    replacing this line:
    
    ```toml
    codex-core = { path = "../core", features = ["cli"] }
    ```
    
    with these:
    
    ```toml
    codex-core = { path = "../core" }
    codex-common = { path = "../common", features = ["cli"] }
    ```
    
    Moving `format_duration()` into its own file gave it some "breathing
    room" to add a unit test, so I had Codex generate some tests and new
    support for durations over 1 minute.
  • feat: make cwd a required field of Config so we stop assuming std::env::current_dir() in a session (#800)
    In order to expose Codex via an MCP server, I realized that we should be
    taking `cwd` as a parameter rather than assuming
    `std::env::current_dir()` as the `cwd`. Specifically, the user may want
    to start a session in a directory other than the one where the MCP
    server has been started.
    
    This PR makes `cwd: PathBuf` a required field of `Session` and threads
    it all the way through, though I think there is still an issue with not
    honoring `workdir` for `apply_patch`, which is something we also had to
    fix in the TypeScript version: https://github.com/openai/codex/pull/556.
    
    This also adds `-C`/`--cd` to change the cwd via the command line.
    
    To test, I ran:
    
    ```
    cargo run --bin codex -- exec -C /tmp 'show the output of ls'
    ```
    
    and verified it showed the contents of my `/tmp` folder instead of
    `$PWD`.
  • fix: overhaul SandboxPolicy and config loading in Rust (#732)
    Previous to this PR, `SandboxPolicy` was a bit difficult to work with:
    
    
    https://github.com/openai/codex/blob/237f8a11e11fdcc793a09e787e48215676d9b95b/codex-rs/core/src/protocol.rs#L98-L108
    
    Specifically:
    
    * It was an `enum` and therefore options were mutually exclusive as
    opposed to additive.
    * It defined things in terms of what the agent _could not_ do as opposed
    to what they _could_ do. This made things hard to support because we
    would prefer to build up a sandbox config by starting with something
    extremely restrictive and only granting permissions for things the user
    as explicitly allowed.
    
    This PR changes things substantially by redefining the policy in terms
    of two concepts:
    
    * A `SandboxPermission` enum that defines permissions that can be
    granted to the agent/sandbox.
    * A `SandboxPolicy` that internally stores a `Vec<SandboxPermission>`,
    but externally exposes a simpler API that can be used to configure
    Seatbelt/Landlock.
    
    Previous to this PR, we supported a `--sandbox` flag that effectively
    mapped to an enum value in `SandboxPolicy`. Though now that
    `SandboxPolicy` is a wrapper around `Vec<SandboxPermission>`, the single
    `--sandbox` flag no longer makes sense. While I could have turned it
    into a flag that the user can specify multiple times, I think the
    current values to use with such a flag are long and potentially messy,
    so for the moment, I have dropped support for `--sandbox` altogether and
    we can bring it back once we have figured out the naming thing.
    
    Since `--sandbox` is gone, users now have to specify `--full-auto` to
    get a sandbox that allows writes in `cwd`. Admittedly, there is no clean
    way to specify the equivalent of `--full-auto` in your `config.toml`
    right now, so we will have to revisit that, as well.
    
    Because `Config` presents a `SandboxPolicy` field and `SandboxPolicy`
    changed considerably, I had to overhaul how config loading works, as
    well. There are now two distinct concepts, `ConfigToml` and `Config`:
    
    * `ConfigToml` is the deserialization of `~/.codex/config.toml`. As one
    might expect, every field is `Optional` and it is `#[derive(Deserialize,
    Default)]`. Consistent use of `Optional` makes it clear what the user
    has specified explicitly.
    * `Config` is the "normalized config" and is produced by merging
    `ConfigToml` with `ConfigOverrides`. Where `ConfigToml` contains a raw
    `Option<Vec<SandboxPermission>>`, `Config` presents only the final
    `SandboxPolicy`.
    
    The changes to `core/src/exec.rs` and `core/src/linux.rs` merit extra
    special attention to ensure we are faithfully mapping the
    `SandboxPolicy` to the Seatbelt and Landlock configs, respectively.
    
    Also, take note that `core/src/seatbelt_readonly_policy.sbpl` has been
    renamed to `codex-rs/core/src/seatbelt_base_policy.sbpl` and that
    `(allow file-read*)` has been removed from the `.sbpl` file as now this
    is added to the policy in `core/src/exec.rs` when
    `sandbox_policy.has_full_disk_read_access()` is `true`.
  • feat: load defaults into Config and introduce ConfigOverrides (#677)
    This changes how instantiating `Config` works and also adds
    `approval_policy` and `sandbox_policy` as fields. The idea is:
    
    * All fields of `Config` have appropriate default values.
    * `Config` is initially loaded from `~/.codex/config.toml`, so values in
    `config.toml` will override those defaults.
    * Clients must instantiate `Config` via
    `Config::load_with_overrides(ConfigOverrides)` where `ConfigOverrides`
    has optional overrides that are expected to be settable based on CLI
    flags.
    
    The `Config` should be defined early in the program and then passed
    down. Now functions like `init_codex()` take fewer individual parameters
    because they can just take a `Config`.
    
    Also, `Config::load()` used to fail silently if `~/.codex/config.toml`
    had a parse error and fell back to the default config. This seemed
    really bad because it wasn't clear why the values in my `config.toml`
    weren't getting picked up. I changed things so that
    `load_with_overrides()` returns `Result<Config>` and verified that the
    various CLIs print a reasonable error if `config.toml` is malformed.
    
    Finally, I also updated the TUI to show which **sandbox** value is being
    used, as we do for other key values like **model** and **approval**.
    This was also a reminder that the various values of `--sandbox` are
    honored on Linux but not macOS today, so I added some TODOs about fixing
    that.
  • feat: add ZDR support to Rust implementation (#642)
    This adds support for the `--disable-response-storage` flag across our
    multiple Rust CLIs to support customers who have opted into Zero-Data
    Retention (ZDR). The analogous changes to the TypeScript CLI were:
    
    * https://github.com/openai/codex/pull/481
    * https://github.com/openai/codex/pull/543
    
    For a client using ZDR, `previous_response_id` will never be available,
    so the `input` field of an API request must include the full transcript
    of the conversation thus far. As such, this PR changes the type of
    `Prompt.input` from `Vec<ResponseInputItem>` to `Vec<ResponseItem>`.
    
    Practically speaking, `ResponseItem` was effectively a "superset" of
    `ResponseInputItem` already. The main difference for us is that
    `ResponseItem` includes the `FunctionCall` variant that we have to
    include as part of the conversation history in the ZDR case.
    
    Another key change in this PR is modifying `try_run_turn()` so that it
    returns the `Vec<ResponseItem>` for the turn in addition to the
    `Vec<ResponseInputItem>` produced by `try_run_turn()`. This is because
    the caller of `run_turn()` needs to record the `Vec<ResponseItem>` when
    ZDR is enabled.
    
    To that end, this PR introduces `ZdrTranscript` (and adds
    `zdr_transcript: Option<ZdrTranscript>` to `struct State` in `codex.rs`)
    to take responsibility for maintaining the conversation transcript in
    the ZDR case.
  • feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
    As stated in `codex-rs/README.md`:
    
    Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
    run it. For a number of users, this runtime requirement inhibits
    adoption: they would be better served by a standalone executable. As
    maintainers, we want Codex to run efficiently in a wide range of
    environments with minimal overhead. We also want to take advantage of
    operating system-specific APIs to provide better sandboxing, where
    possible.
    
    To that end, we are moving forward with a Rust implementation of Codex
    CLI contained in this folder, which has the following benefits:
    
    - The CLI compiles to small, standalone, platform-specific binaries.
    - Can make direct, native calls to
    [seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
    [landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
    order to support sandboxing on Linux.
    - No runtime garbage collection, resulting in lower memory consumption
    and better, more predictable performance.
    
    Currently, the Rust implementation is materially behind the TypeScript
    implementation in functionality, so continue to use the TypeScript
    implmentation for the time being. We will publish native executables via
    GitHub Releases as soon as we feel the Rust version is usable.