Commit Graph

4710 Commits

  • Fix flakey conversation flow test (#9784)
    I've seen this test fail with:
    
    ```
     - Mock #1.
            	Expected range of matching incoming requests: == 2
            	Number of matched incoming requests: 1
    ```
    
    This is because we pop the wrong task_complete events and then the test
    exits. I think this is because the MCP events are now buffered after
    https://github.com/openai/codex/pull/8874.
    
    So:
    1. clear the buffer before we do any user message sending
    2. additionally listen for task start before task complete
    3. use the ID from task start to find the correct task complete event.
  • Fix flakey resume test (#9789)
    Sessions' `updated_at` times are truncated to seconds, with the UUID
    session ID used to break ties. If the two test sessions are created in
    the same second, AND the session B UUID < session A UUID, the test
    fails.
    
    Fix this by mutating the session mtimes, from which we derive the
    updated_at time, to ensure session B is updated_at later than session A.
  • feat: dynamic tools injection (#9539)
    ## Summary
    Add dynamic tool injection to thread startup in API v2, wire dynamic
    tool calls through the app server to clients, and plumb responses back
    into the model tool pipeline.
    
    ### Flow (high level)
    - Thread start injects `dynamic_tools` into the model tool list for that
    thread (validation is done here).
    - When the model emits a tool call for one of those names, core raises a
    `DynamicToolCallRequest` event.
    - The app server forwards it to the client as `item/tool/call`, waits
    for the client’s response, then submits a `DynamicToolResponse` back to
    core.
    - Core turns that into a `function_call_output` in the next model
    request so the model can continue.
    
    ### What changed
    - Added dynamic tool specs to v2 thread start params and protocol types;
    introduced `item/tool/call` (request/response) for dynamic tool
    execution.
    - Core now registers dynamic tool specs at request time and routes those
    calls via a new dynamic tool handler.
    - App server validates tool names/schemas, forwards dynamic tool call
    requests to clients, and publishes tool outputs back into the session.
    - Integration tests
  • chore(core) move model_instructions_template config (#9871)
    ## Summary
    Move `model_instructions_template` config to the experimental slug while
    we iterate on this feature
    
    ## Testing
    - [x] Tested locally, unit tests still pass
  • feat(tui) /personality (#9718)
    ## Summary
    Adds /personality selector in the TUI, which leverages the new core
    interface in #9644
    
    Notes:
    - We are doing some of our own state management for model_info loading
    here, but not sure if that's ideal. open to opinions on simpler
    approach, but would like to avoid blocking on a larger refactor
    - Right now, the `/personality` selector just hides when the model
    doesn't support it. we can update this behavior down the line
    
    ## Testing
    - [x] Tested locally
    - [x] Added snapshot tests
  • Plan prompt (#9877)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    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.
  • Prompt (#9874)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    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.
  • chore: remove extra newline in println (#9850)
    ## Summary
    
    This PR makes a minor formatting adjustment to a `println!` message by
    removing an extra empty line and explicitly using `\n` for clarity.
    
    ## Changes
    
    - Adjusted console output formatting for the success message.
    - No functional or behavioral changes.
  • feat: cap number of agents (#9855)
    Adding more guards to agent:
    * Max depth or 1 (i.e. a sub-agent can't spawn another one)
    * Max 12 sub-agents in total
  • Mark collab as beta (#9834)
    Co-authored-by: jif-oai <jif@openai.com>
  • Use collaboration mode masks without mutating base settings (#9806)
    Keep an unmasked base collaboration mode and apply the active mask on
    demand. Simplify the TUI mask helpers and update tests/docs to match the
    mask contract.
  • Ask for cwd choice when resuming session from different cwd (#9731)
    # Summary
    - Fix resume/fork config rebuild so cwd changes inside the TUI produce a
    fully rebuilt Config (trust/approval/sandbox) instead of mutating only
    the cwd.
    - Preserve `--add-dir` behavior across resume/fork by normalizing
    relative roots to absolute paths once (based on the original cwd).
    - Prefer latest `TurnContext.cwd` for resume/fork prompts but fall back
    to `SessionMeta.cwd` if the latest cwd no longer exists.
    - Align resume/fork selection handling and ensure UI config matches the
    resumed thread config.
    - Fix Windows test TOML path escaping in trust-level test.
    
    # Details
    - Rebuild Config via `ConfigBuilder` when resuming into a different cwd;
    carry forward runtime approval/sandbox overrides.
    - Add `normalize_harness_overrides_for_cwd` to resolve relative
    `additional_writable_roots` against the initial cwd before reuse.
    - Guard `read_session_cwd` with filesystem existence check for the
    latest `TurnContext.cwd`.
    - Update naming/flow around cwd comparison and prompt selection.
    
    <img width="603" height="150" alt="Screenshot 2026-01-23 at 5 42 13 PM"
    src="https://github.com/user-attachments/assets/d1897386-bb28-4e8a-98cf-187fdebbecb0"
    />
    
    And proof the model understands the new cwd:
    
    <img width="828" height="353" alt="Screenshot 2026-01-22 at 5 36 45 PM"
    src="https://github.com/user-attachments/assets/12aed8ca-dec3-4b64-8dae-c6b8cff78387"
    />
  • Raise welcome animation breakpoint to 37 rows (#9778)
    ### Motivation
    - The large ASCII welcome animation can push onboarding content below
    the fold on default-height terminals, making the CLI appear
    unresponsive; raising the breakpoint prevents that.
    - The existing test measured an arbitrary row count rather than
    asserting the welcome line position relative to the animation frame,
    which made the intent unclear.
    
    ### Description
    - Increase `MIN_ANIMATION_HEIGHT` from `20` to `37` in
    `codex-rs/tui/src/onboarding/welcome.rs` so the animation is skipped
    unless there is enough vertical space.
    - Replace the brittle measurement logic in the welcome render test with
    a `row_containing` helper and assert the welcome row equals the frame
    height plus the spacer line (`frame_lines + 1`).
    - Add a regression test
    `welcome_skips_animation_below_height_breakpoint` that verifies the
    animation is not rendered when the viewport height is one row below the
    breakpoint.
    
    ### Testing
    - Ran formatting with `~/.cargo/bin/just fmt` which completed
    successfully.
    - Ran unit tests for the crate with `cargo test -p codex-tui --lib` and
    they passed (unit test suite succeeded).
    - Ran `cargo test -p codex-tui` which reported a failing integration
    test in this environment because the test cannot locate the `codex`
    binary, so full crate tests are blocked here (environment limitation).
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_6973b0a710d4832c9ff36fac26eb1519)
  • Prevent backspace from removing a text element when the cursor is at the element’s left edge (#9630)
    **Summary**
    - Prevent backspace from removing a text element when the cursor is at
    the element’s left edge.
    - Instead just delete the char before the placeholder (moving it to the
    left).
  • fix(windows-sandbox): remove request files after read (#9316)
    ## Summary
    - Remove elevated runner request files after read (best-effort cleanup
    on errors)
    - Add a unit test to cover request file lifecycle
    
    ## Testing
    - `cargo test -p codex-windows-sandbox` (Windows)
    
    Fixes #9315
  • feat: ephemeral threads (#9765)
    Add ephemeral threads capabilities. Only exposed through the
    `app-server` v2
    
    The idea is to disable the rollout recorder for those threads.
  • Another round of improvements for config error messages (#9746)
    In a [recent PR](https://github.com/openai/codex/pull/9182), I made some
    improvements to config error messages so errors didn't leave app server
    clients in a dead state. This is a follow-on PR to make these error
    messages more readable and actionable for both TUI and GUI users. For
    example, see #9668 where the user was understandably confused about the
    source of the problem and how to fix it.
    
    The improved error message:
    1. Clearly identifies the config file where the error was found (which
    is more important now that we support layered configs)
    2. Provides a line and column number of the error
    3. Displays the line where the error occurred and underlines it
    
    For example, if my `config.toml` includes the following:
    ```toml
    [features]
    collaboration_modes = "true"
    ```
    
    Here's the current CLI error message:
    ```
    Error loading config.toml: invalid type: string "true", expected a boolean in `features`
    ```
    
    And here's the improved message:
    ```
    Error loading config.toml:
    /Users/etraut/.codex/config.toml:43:23: invalid type: string "true", expected a boolean
       |
    43 | collaboration_modes = "true"
       |                       ^^^^^^
    ```
    
    The bulk of the new logic is contained within a new module
    `config_loader/diagnostics.rs` that is responsible for calculating the
    text range for a given toml path (which is more involved than I would
    have expected).
    
    In addition, this PR adds the file name and text range to the
    `ConfigWarningNotification` app server struct. This allows GUI clients
    to present the user with a better error message and an optional link to
    open the errant config file. This was a suggestion from @.bolinfest when
    he reviewed my previous PR.
  • feat: introducing a network sandbox proxy (#8442)
    This add a new crate, `codex-network-proxy`, a local network proxy
    service used by Codex to enforce fine-grained network policy (domain
    allow/deny) and to surface blocked network events for interactive
    approvals.
    
    - New crate: `codex-rs/network-proxy/` (`codex-network-proxy` binary +
    library)
    - Core capabilities:
      - HTTP proxy support (including CONNECT tunneling)
      - SOCKS5 proxy support (in the later PR)
    - policy evaluation (allowed/denied domain lists; denylist wins;
    wildcard support)
      - small admin API for polling/reload/mode changes
    - optional MITM support for HTTPS CONNECT to enforce “limited mode”
    method restrictions (later PR)
    
    Will follow up integration with codex in subsequent PRs.
    
    ## Testing
    
    - `cd codex-rs && cargo build -p codex-network-proxy`
    - `cd codex-rs && cargo run -p codex-network-proxy -- proxy`
  • change collaboration mode to struct (#9793)
    Shouldn't cause behavioral change
  • bundle sandbox helper binaries in main zip, for winget. (#9707)
    Winget uses the main codex.exe value as its target.
    The elevated sandbox requires these two binaries to live next to
    codex.exe
  • Remove stale TODO comment from defs.bzl (#9787)
    ### Motivation
    - Remove an outdated comment in `defs.bzl` referencing
    `cargo_build_script` that is no longer relevant.
    
    ### Description
    - Delete the stale `# TODO(zbarsky): cargo_build_script support?` line
    so the logic flows directly from `binaries` to `lib_srcs` in `defs.bzl`.
    
    ### Testing
    - Ran `git diff --check` which produced no errors.
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_6973d9ac757c8331be475a8fb0f90a88)
  • Fix resume picker when user event appears after head (#9512)
    Fixes #9501
    
    Contributing guide:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    ## Summary
    The resume picker requires a session_meta line and at least one
    user_message event within the initial head scan. Some rollout files
    contain multiple session_meta entries before the first user_message, so
    the user event can fall outside the default head window and the session
    is omitted from the picker even though it is resumable by ID.
    
    This PR keeps the head summary bounded but extends scanning for a
    user_message once a session_meta has been observed. The summary still
    caps stored head entries, but we allow a small, bounded extra scan to
    find the first user event so valid sessions are not filtered out.
    
    ## Changes
    - Continue scanning past the head limit (bounded) when session_meta is
    present but no user_message has been seen yet.
    - Mark session_meta as seen even if the head summary buffer is already
    full.
    - Add a regression test with multiple session_meta lines before the
    first user_message.
    
    ## Why This Is Safe
    - The head summary remains bounded to avoid unbounded memory usage.
    - The extra scan is capped (USER_EVENT_SCAN_LIMIT) and only triggers
    after a session_meta is seen.
    - Behavior is unchanged for typical files where the user_message appears
    early.
    
    ## Testing
    - cargo test -p codex-core --lib
    test_list_threads_scans_past_head_for_user_event
  • Select default model from filtered presets (#9782)
    Pick the first available preset after auth filtering for default
    selection.
  • Print warning if we skip config loading (#9611)
    https://github.com/openai/codex/pull/9533 silently ignored config if
    untrusted. Instead, we still load it but disable it. Maybe we shouldn't
    try to parse it either...
    
    <img width="939" height="515" alt="Screenshot 2026-01-21 at 14 56 38"
    src="https://github.com/user-attachments/assets/e753cc22-dd99-4242-8ffe-7589e85bef66"
    />
  • Upgrade GitHub Actions for Node 24 compatibility (#9722)
    ## Summary
    
    Upgrade GitHub Actions to their latest versions to ensure compatibility
    with Node 24, as Node 20 will reach end-of-life in April 2026.
    
    ## Changes
    
    | Action | Old Version(s) | New Version | Release | Files |
    |--------|---------------|-------------|---------|-------|
    | `actions/cache` |
    [`v4`](https://github.com/actions/cache/releases/tag/v4) |
    [`v5`](https://github.com/actions/cache/releases/tag/v5) |
    [Release](https://github.com/actions/cache/releases/tag/v5) | bazel.yml
    |
    
    ## Context
    
    Per [GitHub's
    announcement](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/),
    Node 20 is being deprecated and runners will begin using Node 24 by
    default starting March 4th, 2026.
    
    ### Why this matters
    
    - **Node 20 EOL**: April 2026
    - **Node 24 default**: March 4th, 2026
    - **Action**: Update to latest action versions that support Node 24
    
    ### Security Note
    
    Actions that were previously pinned to commit SHAs remain pinned to SHAs
    (updated to the latest release SHA) to maintain the security benefits of
    immutable references.
    
    ### Testing
    
    These changes only affect CI/CD workflow configurations and should not
    impact application functionality. The workflows should be tested by
    running them on a branch before merging.
    
    Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
  • fix(exec): skip git repo check when --yolo flag is used (#9590)
    ## Summary
    
    Fixes #7522
    
    The `--yolo` (`--dangerously-bypass-approvals-and-sandbox`) flag is
    documented to skip all confirmation prompts and execute commands without
    sandboxing, intended solely for running in environments that are
    externally sandboxed. However, it was not bypassing the trusted
    directory (git repo) check, requiring users to also specify
    `--skip-git-repo-check`.
    
    This change makes `--yolo` also skip the git repo check, matching the
    documented behavior and user expectations.
    
    ## Changes
    
    - Modified `codex-rs/exec/src/lib.rs` to check for
    `dangerously_bypass_approvals_and_sandbox` flag in addition to
    `skip_git_repo_check` when determining whether to skip the git repo
    check
    
    ## Testing
    
    - Verified the code compiles with `cargo check -p codex-exec`
    - Ran existing tests with `cargo test -p codex-exec` (34 passed, 8
    integration tests failed due to unrelated API connectivity issues)
    
    ---
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-authored-by: Claude <noreply@anthropic.com>
  • prompt (#9777)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    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.
  • Persist text element ranges and attached images across history/resume (#9116)
    **Summary**
    - Backtrack selection now rehydrates `text_elements` and
    `local_image_paths` from the chosen user history cell so Esc‑Esc history
    edits preserve image placeholders and attachments.
    - Composer prefill uses the preserved elements/attachments in both `tui`
    and `tui2`.
    - Extended backtrack selection tests to cover image placeholder elements
    and local image paths.
    
    **Changes**
    - `tui/src/app_backtrack.rs`: Backtrack selection now carries text
    elements + local image paths; composer prefill uses them (removes TODO).
    - `tui2/src/app_backtrack.rs`: Same as above.
    - `tui/src/app.rs`: Updated backtrack test to assert restored
    elements/paths.
    - `tui2/src/app.rs`: Same test updates.
    
    ### The original scope of this PR (threading text elements and image
    attachments through the codex harness thoroughly/persistently) was
    broken into the following PRs other than this one:
    
    The diff of this PR was reduced by changing types in a starter PR:
    https://github.com/openai/codex/pull/9235
    
    Then text element metadata was added to protocol, app server, and core
    in this PR: https://github.com/openai/codex/pull/9331
    
    Then the end-to-end flow was completed by wiring TUI/TUI2 input,
    history, and restore behavior in
    https://github.com/openai/codex/pull/9393
    
    Prompt expansion was supported in this PR:
    https://github.com/openai/codex/pull/9518
    
    TextElement optional placeholder field was protected in
    https://github.com/openai/codex/pull/9545
  • chore: use some raw strings to reduce quoting (#9745)
    Small follow-ups for https://github.com/openai/codex/pull/9565. Mainly
    `r#`, but also added some whitespace for early returns.
  • Fix execpolicy parsing for multiline quoted args (#9565)
    ## What
    Fix bash command parsing to accept double-quoted strings that contain
    literal newlines so execpolicy can match allow rules.
    
    ## Why
    Allow rules like [git, commit] should still match when commit messages
    include a newline in a quoted argument; the parser currently rejects
    these strings and falls back to the outer shell invocation.
    
    ## How
    - Validate double-quoted strings by ensuring all named children are
    string_content and then stripping the outer quotes from the raw node
    text so embedded newlines are preserved.
    - Reuse the helper for concatenated arguments.
    - Ensure large SI suffix formatting uses the caller-provided locale
    formatter for grouping.
    - Add coverage for newline-containing quoted arguments.
    
    Fixes #9541.
    
    ## Tests
    - cargo test -p codex-core
    - just fix -p codex-core
    - cargo test -p codex-protocol
    - just fix -p codex-protocol
    - cargo test --all-features
  • feat: add session source as otel metadata tag (#9720)
    Add session.source and user.account_id as global OTEL metric tags to
    identify client surface and user.
  • Hide mode cycle hint while a task is running (#9730)
    ## Summary
    - hide the “(shift+tab to cycle)” suffix on the collaboration mode label
    while a task is running
    - keep the cycle hint visible when idle
    - add a snapshot to cover the running-task label state
  • Change the prompt for planning and reasoning effort (#9733)
    Change the prompt for planning and reasoning effort preset for better
    experience
  • feat(app-server) Expose personality (#9674)
    ### Motivation
    Exposes a per-thread / per-turn `personality` override in the v2
    app-server API so clients can influence model communication style at
    thread/turn start. Ensures the override is passed into the session
    configuration resolution so it becomes effective for subsequent turns
    and headless runners.
    
    ### Testing
    - [x] Add an integration-style test
    `turn_start_accepts_personality_override_v2` in
    `codex-rs/app-server/tests/suite/v2/turn_start.rs` that verifies a
    `/personality` override results in a developer update message containing
    `<personality_spec>` in the outbound model request.
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_6971d646b1c08322a689a54d2649f3fe)