Commit Graph

720 Commits

  • Add user command event types (#6246)
    adding new user command event, logic in TUI to render user command
    events
  • Add opt-out for rate limit model nudge (#6433)
    ## Summary
    - add a `hide_rate_limit_model_nudge` notice flag plus config edit
    plumbing so the rate limit reminder preference is persisted and
    documented
    - extend the chat widget prompt with a "never show again" option, and
    wire new app events so selecting it hides future nudges immediately and
    writes the config
    - add unit coverage and refresh the snapshot for the three-option prompt
    
    ## Testing
    - `just fmt`
    - `just fix -p codex-tui`
    - `just fix -p codex-core`
    - `cargo test -p codex-tui`
    - `cargo test -p codex-core` *(fails at
    `exec::tests::kill_child_process_group_kills_grandchildren_on_timeout`:
    grandchild process still alive)*
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_6910d7f407748321b2661fc355416994)
  • Fix warning message phrasing (#6446)
    Small fix for sentence phrasing in the warning message
    
    Co-authored-by: AndrewNikolin <877163+AndrewNikolin@users.noreply.github.com>
  • fix(seatbelt): Allow reading hw.physicalcpu (#6421)
    Allow reading `hw.physicalcpu` so numpy can be imported when running in
    the sandbox.
     
    resolves #6420
  • Kill shell tool process groups on timeout (#5258)
    ## Summary
    - launch shell tool processes in their own process group so Codex owns
    the full tree
    - on timeout or ctrl-c, send SIGKILL to the process group before
    terminating the tracked child
    - document that the default shell/unified_exec timeout remains 1000 ms
    
    ## Original Bug
    Long-lived shell tool commands hang indefinitely because the timeout
    handler only terminated the direct child process; any grandchildren it
    spawned kept running and held the PTY open, preventing Codex from
    regaining control.
    
    ## Repro Original Bug
    Install next.js and run `next dev` (which is a long-running shell
    process with children). On openai:main, it will cause the agent to
    permanently get stuck here until human intervention. On this branch,
    this command will be terminated successfully after timeout_ms which will
    unblock the agent. This is a critical fix for unmonitored / lightly
    monitored agents that don't have immediate human observation to unblock
    them.
    
    ---------
    
    Co-authored-by: Michael Bolin <mbolin@openai.com>
    Co-authored-by: Michael Bolin <bolinfest@gmail.com>
  • core: replace Cloudflare 403 HTML with friendly message (#6252)
    ### Motivation
    
    When Codex is launched from a region where Cloudflare blocks access (for
    example, Russia), the CLI currently dumps Cloudflare’s entire HTML error
    page. This isn’t actionable and makes it hard for users to understand
    what happened. We want to detect the Cloudflare block and show a
    concise, user-friendly explanation instead.
    
    ### What Changed
    
    - Added CLOUDFLARE_BLOCKED_MESSAGE and a friendly_message() helper to
    UnexpectedResponseError. Whenever we see a 403 whose body contains the
    Cloudflare block notice, we now emit a single-line message (Access
    blocked by Cloudflare…) while preserving the HTTP status and request id.
    All other responses keep the original behaviour.
    - Added two focused unit tests:
    - unexpected_status_cloudflare_html_is_simplified ensures the Cloudflare
    HTML case yields the friendly message.
    - unexpected_status_non_html_is_unchanged confirms plain-text 403s still
    return the raw body.
    
    ### Testing
    
    - cargo build -p codex-cli
    - cargo test -p codex-core
    - just fix -p codex-core
    - cargo test --all-features
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • [App-server] Implement account/read endpoint (#6336)
    This PR does two things:
    1. add a new function in core that maps the core-internal plan type to
    the external plan type;
    2. implement account/read that get account status (v2 of
    `getAuthStatus`).
  • Prefer wait_for_event over wait_for_event_with_timeout. (#6346)
    No need to specify the timeout in most cases.
  • Remove shell tool when unified exec is enabled (#6345)
    Also drop streameable shell that's just an alias for unified exec.
  • Don't retry "insufficient_quota" errors (#6340)
    This PR makes an "insufficient quota" error fatal so we don't attempt to
    retry it multiple times in the agent loop.
    
    We have multiple bug reports from users about intermittent retry
    behaviors, and this could explain some of them. With this change, we'll
    eliminate the retries and surface a clear error message.
    
    The PR is a nearly identical copy of [this
    PR](https://github.com/openai/codex/pull/4837) contributed by
    @abimaelmartell. The original PR has gone stale. Rather than wait for
    the contributor to resolve merge conflicts, I wanted to get this change
    in.
  • core: widen sandbox to allow certificate ops when network is enabled (#5980)
    This allows `gh api` to work in the workspace-write sandbox w/ network
    enabled. Without this we see e.g.
    
    ```
    $ codex debug seatbelt --full-auto gh api repos/openai/codex/pulls --paginate -X GET -F state=all
    Get "https://api.github.com/repos/openai/codex/pulls?per_page=100&state=all": tls: failed to verify certificate: x509: OSStatus -26276
    ```
  • Windows Sandbox: Show Everyone-writable directory warning (#6283)
    Show a warning when Auto Sandbox mode becomes enabled, if we detect
    Everyone-writable directories, since they cannot be protected by the
    current implementation of the Sandbox.
    
    This PR also includes changes to how we detect Everyone-writable to be
    *much* faster
  • Fixes intermittent test failures in CI (#6282)
    I'm seeing two tests fail intermittently in CI. This PR attempts to
    address (or at least mitigate) the flakiness.
    
    * summarize_context_three_requests_and_instructions - The test snapshots
    server.received_requests() immediately after observing TaskComplete.
    Because the OpenAI /v1/responses call is streamed, the HTTP request can
    still be draining when that event fires, so wiremock occasionally
    reports only two captured requests. Fix is to wait for async activity to
    complete.
    * archive_conversation_moves_rollout_into_archived_directory - times out
    on a slow CI run. Mitigation is to increase timeout value from 10s to
    20s.
  • [app-server] feat: v2 Thread APIs (#6214)
    Implements:
    ```
    thread/list
    thread/start
    thread/resume
    thread/archive
    ```
    
    along with their integration tests. These are relatively light wrappers
    around the existing core logic, and changes to core logic are minimal.
    
    However, an improvement made for developer ergonomics:
    - `thread/start` and `thread/resume` automatically attaches a
    conversation listener internally, so clients don't have to make a
    separate `AddConversationListener` call like they do today.
    
    For consistency, also updated `model/list` and `feedback/upload` (naming
    conventions, list API params).
  • Improved token refresh handling to address "Re-connecting" behavior (#6231)
    Currently, when the access token expires, we attempt to use the refresh
    token to acquire a new access token. This works most of the time.
    However, there are situations where the refresh token is expired,
    exhausted (already used to perform a refresh), or revoked. In those
    cases, the current logic treats the error as transient and attempts to
    retry it repeatedly.
    
    This PR changes the token refresh logic to differentiate between
    permanent and transient errors. It also changes callers to treat the
    permanent errors as fatal rather than retrying them. And it provides
    better error messages to users so they understand how to address the
    problem. These error messages should also help us further understand why
    we're seeing examples of refresh token exhaustion.
    
    Here is the error message in the CLI. The same text appears within the
    extension.
    
    <img width="863" height="38" alt="image"
    src="https://github.com/user-attachments/assets/7ffc0d08-ebf0-4900-b9a9-265064202f4f"
    />
    
    I also correct the spelling of "Re-connecting", which shouldn't have a
    hyphen in it.
    
    Testing: I manually tested these code paths by adding temporary code to
    programmatically cause my refresh token to be exhausted (by calling the
    token refresh endpoint in a tight loop more than 50 times). I then
    simulated an access token expiration, which caused the token refresh
    logic to be invoked. I confirmed that the updated logic properly handled
    the error condition.
    
    Note: We earlier discussed the idea of forcefully logging out the user
    at the point where token refresh failed. I made several attempts to do
    this, and all of them resulted in a bad UX. It's important to surface
    this error to users in a way that explains the problem and tells them
    that they need to log in again. We also previously discussed deleting
    the auth.json file when this condition is detected. That also creates
    problems because it effectively changes the auth status from logged in
    to logged out, and this causes odd failures and inconsistent UX. I think
    it's therefore better not to delete auth.json in this case. If the user
    closes the CLI or VSCE and starts it again, we properly detect that the
    access token is expired and the refresh token is "dead", and we force
    the user to go through the login flow at that time.
    
    This should address aspects of #6191, #5679, and #5505
  • refactor Conversation history file into its own directory (#6229)
    This is just a refactor of `conversation_history` file by breaking it up
    into multiple smaller ones with helper. This refactor will help us move
    more functionality related to context management here. in a clean way.
  • allow codex to be run from pid 1 (#4200)
    Previously it was not possible for codex to run commands as the init
    process (pid 1) in linux. Commands run in containers tend to see their
    own pid as 1. See https://github.com/openai/codex/issues/4198
    
    This pr implements the solution mentioned in that issue.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • fix(core): load custom prompts from symlinked Markdown files (#3643)
    - Discover prompts via fs::metadata to follow symlinks
    
    - Add Unix-only symlink test in custom_prompts.rs
    
    - Update docs/prompts.md to mention symlinks
    
    Fixes #3637
    
    ---------
    
    Signed-off-by: Soroush Yousefpour <h.yusefpour@gmail.com>
    Co-authored-by: dedrisian-oai <dedrisian@openai.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • fix: Update the deprecation message to link to the docs (#6211)
    The deprecation message is currently a bit confusing. Users may not
    understand what is `[features].x`. I updated the docs and the
    deprecation message for more guidance.
    
    ---------
    
    Co-authored-by: Gabriel Peal <gpeal@users.noreply.github.com>
  • ignore deltas in codex_delegate (#6208)
    ignore legacy deltas in codex-delegate to avoid this
    [issue](https://github.com/openai/codex/pull/6202).
  • [App-server] v2 for account/updated and account/logout (#6175)
    V2 for `account/updated` and `account/logout` for app server. correspond
    to old `authStatusChange` and `LogoutChatGpt` respectively. Followup PRs
    will make other v2 endpoints call `account/updated` instead of
    `authStatusChange` too.
  • Fix is_api_message to correctly exclude reasoning messages (#6156)
    ## Problem
    
    The `is_api_message` function in `conversation_history.rs` had a
    misalignment between its documentation and implementation:
    
    - **Comment stated**: "Anything that is not a system message or
    'reasoning' message is considered an API message"
    - **Code behavior**: Was returning `true` for `ResponseItem::Reasoning`,
    meaning reasoning messages were incorrectly treated as API messages
    
    This inconsistency could lead to reasoning messages being persisted in
    conversation history when they should be filtered out.
    
    ## Root Cause
    
    Investigation revealed that reasoning messages are explicitly excluded
    throughout the codebase:
    
    1. **Chat completions API** (lines 267-272 in `chat_completions.rs`)
    omits reasoning from conversation history:
       ```rust
       ResponseItem::Reasoning { .. } | ResponseItem::Other => {
           // Omit these items from the conversation history.
           continue;
       }
       ```
    
    2. **Existing tests** like `drops_reasoning_when_last_role_is_user` and
    `ignores_reasoning_before_last_user` validate that reasoning should be
    excluded from API payloads
    
    ## Solution
    
    Fixed the `is_api_message` function to align with its documentation and
    the rest of the codebase:
    
    ```rust
    // Before: Reasoning was incorrectly returning true
    ResponseItem::Reasoning { .. } | ResponseItem::WebSearchCall { .. } => true,
    
    // After: Reasoning correctly returns false  
    ResponseItem::WebSearchCall { .. } => true,
    ResponseItem::Reasoning { .. } | ResponseItem::Other => false,
    ```
    
    ## Testing
    
    - Enhanced existing test to verify reasoning messages are properly
    filtered out
    - All 264 core tests pass, including 8 chat completions tests that
    validate reasoning behavior
    - No regressions introduced
    
    This ensures reasoning messages are consistently excluded from API
    message processing across the entire codebase.
  • Fixed notify handler so it passes correct input_messages details (#6143)
    This fixes bug #6121. 
    
    The `input_messages` field passed to the notify handler is currently
    empty because the logic is incorrectly including the OutputText rather
    than InputText. I've fixed that and added proper filtering to remove
    messages associated with AGENTS.md and other context injected by the
    harness.
    
    Testing: I wrote a notify handler and verified that the user prompt is
    correctly passed through to the handler.
  • log sandbox commands to $CODEX_HOME instead of cwd (#6171)
    Logging commands in the Windows Sandbox is temporary, but while we are
    doing it, let's always write to CODEX_HOME instead of dirtying the cwd.
  • feat: add the time after aborting (#5996)
    Tell the model how much time passed after the user aborted the call.
  • Do not skip trust prompt on Windows if sandbox is enabled. (#6167)
    If the experimental windows sandbox is enabled, the trust prompt should
    show on Windows.
  • fix: improve usage URLs in status card and snapshots (#6111)
    Hi OpenAI Codex team, currently "Visit chatgpt.com/codex/settings/usage
    for up-to-date information on rate limits and credits" message in status
    card and error messages. For now, without the "https://" prefix, the
    link cannot be clicked directly from most terminals or chat interfaces.
    
    <img width="636" height="127" alt="Screenshot 2025-11-02 at 22 47 06"
    src="https://github.com/user-attachments/assets/5ea11e8b-fb74-451c-85dc-f4d492b2678b"
    />
    
    ---
    
    The fix is intent to improve this issue:
    
    - It makes the link clickable in terminals that support it, hence better
    accessibility
    - It follows standard URL formatting practices
    - It maintains consistency with other links in the application (like the
    existing "https://openai.com/chatgpt/pricing" links)
    
    Thank you!
  • Fix incorrect "deprecated" message about experimental config key (#6131)
    When I enable `experimental_sandbox_command_assessment`, I get an
    incorrect deprecation warning: "experimental_sandbox_command_assessment
    is deprecated. Use experimental_sandbox_command_assessment instead."
    
    This PR fixes this error.
  • Changes to sandbox command assessment feature based on initial experiment feedback (#6091)
    * Removed sandbox risk categories; feedback indicates that these are not
    that useful and "less is more"
    * Tweaked the assessment prompt to generate terser answers
    * Fixed bug in orchestrator that prevents this feature from being
    exposed in the extension
  • Parse the Azure OpenAI rate limit message (#5956)
    Fixes #4161
    
    Currently Codex uses a regex to parse the "Please try again in 1.898s"
    OpenAI-style rate limit message, so that it can wait the correct
    duration before retrying. Azure OpenAI returns a different error that
    looks like "Rate limit exceeded. Try again in 35 seconds."
    
    This PR extends the regex and parsing code to match in a more fuzzy
    manner, handling anything matching the pattern "try again in
    \<duration>\<unit>".
  • feat: compactor 2 (#6027)
    Co-authored-by: pakrym-oai <pakrym@openai.com>
  • Add warning on compact (#6052)
    This PR introduces the ability for `core` to send `warnings` as it can
    send `errors. It also sends a warning on compaction.
    
    <img width="811" height="187" alt="image"
    src="https://github.com/user-attachments/assets/0947a42d-b720-420d-b7fd-115f8a65a46a"
    />
  • chore: Add shell serialization tests for json (#6043)
    ## Summary
    Can never have enough tests on this code path - checking that json
    inside a shell call is deserialized correctly.
    
    ## Tests
    - [x] These are tests 😎
  • Truncate total tool calls text (#5979)
    Put a cap on the aggregate output of text content on tool calls.
    
    ---------
    
    Co-authored-by: Gabriel Peal <gpeal@users.noreply.github.com>
  • override verbosity for gpt-5-codex (#6007)
    we are seeing [reports](https://github.com/openai/codex/issues/6004) of
    users having verbosity in their config.toml and facing issues.
    gpt-5-codex doesn't accept other values rather than medium for
    verbosity.
  • docs: Fix markdown list item spacing in codex-rs/core/review_prompt.md (#4144)
    Fixes a Markdown parsing issue where a list item used `*` without a
    following space (`*Line ranges ...`). Per CommonMark, a space after the
    list marker is required. Updated to `* Line ranges ...` so the guideline
    renders as a standalone bullet. This change improves readability and
    prevents mis-parsing in renderers.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Windows Sandbox - Alpha version (#4905)
    - Added the new codex-windows-sandbox crate that builds both a library
    entry point (run_windows_sandbox_capture) and a CLI executable to launch
    commands inside a Windows restricted-token sandbox, including ACL
    management, capability SID provisioning, network lockdown, and output
    capture
    (windows-sandbox-rs/src/lib.rs:167, windows-sandbox-rs/src/main.rs:54).
    - Introduced the experimental WindowsSandbox feature flag and wiring so
    Windows builds can opt into the sandbox:
    SandboxType::WindowsRestrictedToken, the in-process execution path, and
    platform sandbox selection now honor the flag (core/src/features.rs:47,
    core/src/config.rs:1224, core/src/safety.rs:19,
    core/src/sandboxing/mod.rs:69, core/src/exec.rs:79,
    core/src/exec.rs:172).
    - Updated workspace metadata to include the new crate and its
    Windows-specific dependencies so the core crate can link against it
    (codex-rs/
        Cargo.toml:91, core/Cargo.toml:86).
    - Added a PowerShell bootstrap script that installs the Windows
    toolchain, required CLI utilities, and builds the workspace to ease
    development
        on the platform (scripts/setup-windows.ps1:1).
    - Landed a Python smoke-test suite that exercises
    read-only/workspace-write policies, ACL behavior, and network denial for
    the Windows sandbox
        binary (windows-sandbox-rs/sandbox_smoketests.py:1).
  • fix: Update seatbelt policy for java on macOS (#3987)
    # Summary
    
    This PR is related to the Issue #3978 and contains a fix to the seatbelt
    profile for macOS that allows to run java/jdk tooling from the sandbox.
    I have found that the included change is the minimum change to make it
    run on my machine.
    
    There is a unit test added by codex when making this fix. I wonder if it
    is useful since you need java installed on the target machine for it to
    be relevant. I can remove it it is better.
    
    Fixes #3978