Commit Graph

4710 Commits

  • Updated the AI labeler rules to match the most recent issue tracker labels (#6347)
    This PR updates the AI prompt used for the workflow that adds automated
    labels to incoming issues. I've been updating and refining the list of
    labels as I work through the issue backlog, and the old prompt was
    becoming somewhat outdated.
  • 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.
  • feat: Enable CTRL-n and CTRL-p for navigating slash commands, files, history (#1994)
    Adds CTRL-n and CTRL-p navigation for slash commands, files, and
    history.
    Closes #1992
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • tui: fix backtracking past /status (#6335)
    Fixes https://github.com/openai/codex/issues/4722
    
    Supersedes https://github.com/openai/codex/pull/5058
    
    Ideally we'd have a clearer way of separating history per-session than
    by detecting a specific history cell type, but this is a fairly minimal
    fix for now.
  • Make generate_ts prettier output warn-only (#6342)
    Before, every file would be outputted with the time prettier spent
    formatting it. This made downstream scripts way too noisy.
  • [App Server] Add more session metadata to listConversations (#6337)
    This unlocks a few new product experience for app server consumers
  • 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
    ```
  • Updated contributing guidelines and PR template to request link to bug report in PR notes (#6332)
    Some PRs are being submitted without reference to existing bug reports
    or feature requests. This updates the PR template and contributing
    guidelines to request that all PRs from the community contain such a
    link. This provides additional context and helps prioritize, track, and
    assess PRs.
  • chore: move relevant tests to app-server/tests/suite/v2 (#6289)
    These are technically app-server v2 APIs, so move them to the same
    directory as the others.
  • 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
  • docs: Fix code fence and typo in advanced guide (#6295)
    - add `bash` to code fence
    - fix spelling of `JavaScript`
  • [app-server] feat: v2 Turn APIs (#6216)
    Implements:
    ```
    turn/start
    turn/interrupt
    ```
    
    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:
    - `turn/start` replaces both `SendUserMessage` (no turn overrides) and
    `SendUserTurn` (can override model, approval policy, etc.)
  • chore: rename for clarity (#6319)
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
  • [App-server] Add account/login/cancel v2 endpoint (#6288)
    Add `account/login/cancel` v2 endpoint for auth. this is similar
    implementation to `cancelLoginChatgpt` v1 endpoint.
  • fix: ToC so it doesn’t include itself or duplicate the end marker (#4388)
    turns out the ToC was including itself when generating, which messed up
    comparisons and sometimes made the file rewrite endlessly.
    
    also fixed the slice so `<!-- End ToC -->` doesn’t get duplicated when
    we insert the new ToC.
    
    should behave nicely now - no extra rewrites, no doubled markers.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Prevent dismissal of login menu in TUI (#6285)
    We currently allow the user to dismiss the login menu via Ctrl+C. This
    leaves them in a bad state where they're not auth'ed but have an input
    prompt. In the extension, this isn't a problem because we don't allow
    the user to dismiss the login screen.
    
    Testing: I confirmed that Ctrl+C no longer dismisses the login menu.
    
    This is an alternative (simpler) fix for a [community
    PR](https://github.com/openai/codex/pull/3234).
  • [App-server] Implement v2 for account/login/start and account/login/completed (#6183)
    This PR implements `account/login/start` and `account/login/completed`.
    Instead of having separate endpoints for login with chatgpt and api, we
    have a single enum handling different login methods. For sync auth
    methods like sign in with api key, we still send a `completed`
    notification back to be compatible with the async login flow.
  • stop capturing r when environment selection modal is open (#6249)
    This fixes an issue where you can't select environments with an r in them when the selection modal is open
  • 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).
  • Update rmcp to 0.8.5 (#6261)
    Picks up https://github.com/modelcontextprotocol/rust-sdk/pull/511 which
    should fix todoist and some other MCP server oauth and may further
    resolve issues in https://github.com/openai/codex/issues/5045
  • 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.
  • tui: refactor ChatWidget and BottomPane to use Renderables (#5565)
    - introduce RenderableItem to support both owned and borrowed children
    in composite Renderables
    - refactor some of our gnarlier manual layouts, BottomPane and
    ChatWidget, to use ColumnRenderable
    - Renderable and friends now handle cursor_pos()
  • Add modelReasoningEffort option to TypeScript SDK (#6237)
    ## Summary
    - Adds `ModelReasoningEffort` type to TypeScript SDK with values:
    `minimal`, `low`, `medium`, `high`
    - Adds `modelReasoningEffort` option to `ThreadOptions`
    - Forwards the option to the codex CLI via `--config
    model_reasoning_effort="<value>"`
    - Includes test coverage for the new option
    
    ## Changes
    - `sdk/typescript/src/threadOptions.ts`: Define `ModelReasoningEffort`
    type and add to `ThreadOptions`
    - `sdk/typescript/src/index.ts`: Export `ModelReasoningEffort` type
    - `sdk/typescript/src/exec.ts`: Forward `modelReasoningEffort` to CLI as
    config flag
    - `sdk/typescript/src/thread.ts`: Pass option through to exec (+ debug
    logging)
    - `sdk/typescript/tests/run.test.ts`: Add test for
    `modelReasoningEffort` flag forwarding
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • 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 nix build (#6230)
    Previously, the `nix build .#default` command fails due to a missing
    output hash in the `./codex-rs/default.nix` for `crossterm-0.28.1`:
    
    ```
    error: No hash was found while vendoring the git dependency crossterm-0.28.1. You can add
    a hash through the `outputHashes` argument of `importCargoLock`:
    
    outputHashes = {
     "crossterm-0.28.1" = "<hash>";
    };
    
    If you use `buildRustPackage`, you can add this attribute to the `cargoLock`
    attribute set.
    ```
    
    This PR adds the missing hash:
    
    ```diff
    cargoLock.outputHashes = {
      "ratatui-0.29.0" = "sha256-HBvT5c8GsiCxMffNjJGLmHnvG77A6cqEL+1ARurBXho=";
    + "crossterm-0.28.1" = "sha256-6qCtfSMuXACKFb9ATID39XyFDIEMFDmbx6SSmNe+728=";
    };
    ```
    
    With this change, `nix build .#default` succeeds:
    
    ```
    > nix build .#default --max-jobs 1 --cores 2
    
    warning: Git tree '/home/lukas/r/github.com/lukasl-dev/codex' is dirty
    [1/0/1 built] building codex-rs-0.1.0 (buildPhase)[1/0/1 built] building codex-rs-0.1.0 (buildP[1/0/1 built] building codex-rs-0.1.0 (buildPhase):    [1/0/1 built] building codex-rs-0.1.0 (b[1/0/1 built] building codex-rs-0.1.0 (buildPhase):    Compi[1/0/1 built] building codex-rs-0.1
    
    > ./result/bin/codex
      You are running Codex in /home/lukas/r/github.com/lukasl-dev/codex
    
      Since this folder is version controlled, you may wish to allow Codex to work in this folder without asking for approval.
      ...
    ```
  • [app-server] feat: export.rs supports a v2 namespace, initial v2 notifications (#6212)
    **Typescript and JSON schema exports**
    While working on Thread/Turn/Items type definitions, I realize we will
    run into name conflicts between v1 and v2 APIs (e.g. `RateLimitWindow`
    which won't be reusable since v1 uses `RateLimitWindow` from `protocol/`
    which uses snake_case, but we want to expose camelCase everywhere, so
    we'll define a V2 version of that struct that serializes as camelCase).
    
    To set us up for a clean and isolated v2 API, generate types into a
    `v2/` namespace for both typescript and JSON schema.
    - TypeScript: v2 types emit under `out_dir/v2/*.ts`, and root index.ts
    now re-exports them via `export * as v2 from "./v2"`;.
    - JSON Schemas: v2 definitions bundle under `#/definitions/v2/*` rather
    than the root.
    
    The location for the original types (v1 and types pulled from
    `protocol/` and other core crates) haven't changed and are still at the
    root. This is for backwards compatibility: no breaking changes to
    existing usages of v1 APIs and types.
    
    **Notifications**
    While working on export.rs, I:
    - refactored server/client notifications with macros (like we already do
    for methods) so they also get exported (I noticed they weren't being
    exported at all).
    - removed the hardcoded list of types to export as JSON schema by
    leveraging the existing macros instead
    - and took a stab at API V2 notifications. These aren't wired up yet,
    and I expect to iterate on these this week.
  • 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).
  • fix: pin musl 1.2.5 for DNS fixes (#6189)
    ## Summary
    musl 1.2.5 includes [several fixes to DNS over
    TCP](https://www.openwall.com/lists/musl/2024/03/01/2), which appears to
    be the root cause of #6116.
    
    This approach is a bit janky, but according to codex:
    > On the Ubuntu 24.04 runners we use, apt-cache policy musl-tools shows
    only the distro build (1.2.4-2ubuntu2)"
    
    We should build with this version and confirm.
    
    ## Testing
    - [ ] TODO: test and see if this fixes Azure issues
  • [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.
  • Follow symlinks during file search (#4453)
    I have read the CLA Document and I hereby sign the CLA
    
    Closes #4452
    
    This fixes a usability issue where users with symlinked folders in their
    working directory couldn't search those files using the `@` file search
    feature.
    
    ## Rationale
    
    The "bug" was in the file search implementation in
    `codex-rs/file-search/src/lib.rs`. The `WalkBuilder` was using default
    settings which don't follow symlinks, causing two related issues:
    
    1. Partial search results: The `@` search would find symlinked
    directories but couldn't find files inside them
    2. Inconsistent behavior: Users expect symlinked folders to behave like
    regular folders in search results.
    
    ## Root cause
    
    The `ignore` crate's `WalkBuilder` defaults to `.follow_links(false)`
    [[source](https://github.com/BurntSushi/ripgrep/blob/9802945e6342ec284633924cb7d8d3ce67204995/crates/ignore/src/walk.rs#L532)],
    so when traversing the file system, it would:
    
    - Detect symlinked directories as directory entries
    - But not traverse into them to index their contents
    - The `get_file_path` function would then filter out actual directories,
    leaving only the symlinked folder itself as a result
    
    Fix: Added `.follow_links(true)` to the `WalkBuilder` configuration,
    making the file search follow symlinks and index their contents just
    like regular directories.
    
    This change maintains backward compatibility since symlink following is
    generally expected behavior for file search tools, and it aligns with
    how users expect the `@` search feature to work.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • docs: add example config.toml (#5175)
    I was missing an example config.toml, and following docs/config.md alone
    was slower. I had GPT-5 scan the codebase for every accepted config key,
    check the defaults, and generate a single example config.toml with
    annotations. It lists all keys Codex reads from TOML, sets each to its
    effective default where it exists, leaves optional ones commented, and
    adds short comments on purpose and valid values. This should make
    onboarding faster and reduce configuration errors. I can rename it to
    config.example.toml or move it under docs/ if you prefer.
  • fix: --search shouldn't show deprecation message (#6180)
    Use the new feature flags instead of the old config.
  • 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.
  • tui: refine text area word separator handling (#5541)
    ## Summary
    - replace the word part enum with a simple `is_word_separator` helper
    - keep word-boundary logic aligned with the helper and punctuation-aware
    behavior
    - extend forward/backward deletion tests to cover whitespace around
    separators
    
    ## Testing
    - just fix -p codex-tui
    - cargo test -p codex-tui
    
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68f91c71d838832ca2a3c4f0ec1b55d4