Commit Graph

1978 Commits

  • Fix AltGr/backslash input on Windows Codex terminal (#6720)
    ### Summary
    
    - Treat AltGr chords (Ctrl+Alt) as literal character input in the Codex
    TUI textarea so Windows terminals that report
        backslash and other characters via AltGr insert correctly.
    - Add regression test altgr_ctrl_alt_char_inserts_literal to ensure
    Ctrl+Alt char events append the character and
        advance the cursor.
    
     ### Motivation
    
    On US/UK keyboard layouts, backslash is produced by a plain key, so
    Ctrl+Alt handling is never exercised and the
    bug isn’t visible. On many non‑US layouts (e.g., German), backslash and
    other symbols require AltGr, which terminals
    report as Ctrl+Alt+<char>. Our textarea previously filtered these chords
    like navigation bindings, so AltGr input was
    dropped on affected layouts. This change treats AltGr chords as literal
    input so backslash and similar symbols work on
      Windows terminals.
    
    This fixes multiple reported Issues where the \ symbol got cut off.
    Like:
    C:\Users\Admin
    became
    C:UsersAdmin
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • fix: resolve Windows MCP server execution for script-based tools (#3828)
    ## What?
    
    Fixes MCP server initialization failures on Windows when using
    script-based tools like `npx`, `pnpm`, and `yarn` that rely on
    `.cmd`/`.bat` files rather than `.exe` binaries.
    
    Fixes #2945
    
    ## Why?
    
    Windows users encounter "program not found" errors when configuring MCP
    servers with commands like `npx` in their `~/.codex/config.toml`. This
    happens because:
    
    - Tools like `npx` are batch scripts (`npx.cmd`) on Windows, not
    executable binaries
    - Rust's `std::process::Command` bypasses the shell and cannot execute
    these scripts directly
    - The Windows shell normally handles this by checking `PATHEXT` for
    executable extensions
    
    Without this fix, Windows users must specify full paths or add `.cmd`
    extensions manually, which breaks cross-platform compatibility.
    
    ## How?
    
    Added platform-specific program resolution using the `which` crate to
    find the correct executable path:
    
    - **Windows**: Resolves programs through PATH/PATHEXT to find
    `.cmd`/`.bat` scripts
    - **Unix**: Returns the program unchanged (no-op, as Unix handles
    scripts natively)
    
    ### Changes
    
    - Added `which = "6"` dependency to `mcp-client/Cargo.toml`
    - Implemented `program_resolver` module in `mcp_client.rs` with
    platform-specific resolution
    - Added comprehensive tests for both Windows and Unix behavior
    
    ### Testing
    
    Added platform-specific tests to verify:
    - Unix systems execute scripts without extensions
    - Windows fails without proper extensions
    - Windows succeeds with explicit extensions
    - Cross-platform resolution enables successful execution
    
    **Tested on:**
    - Windows 11 (NT 10.0.26100.0 x64)
    - PowerShell 5.1 & 7+, CMD, Git Bash
    - MCP servers: playwright, context7, supabase
    - WSL (verified no regression)
    
    **Local checks passed:**
    ```bash
    cargo test && cargo clippy --tests && cargo fmt -- --config imports_granularity=Item
    ```
    
    ### Results
    
    **Before:**
    ```
    🖐 MCP client for `playwright` failed to start: program not found
    ```
    
    **After:**
    ```
    🖐 MCP client for `playwright` failed to start: request timed out
    ```
    
    Windows users can now use simple commands like `npx` in their config
    without specifying full paths or extensions. The timeout issue is a
    separate concern that will be addressed in a follow-up PR.
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Fix documentation errors for Custom Prompts named arguments and add canonical examples (#5910)
    The Custom Prompts documentation (docs/prompts.md) was incomplete for
    named arguments:
    
    1. **Documentation for custom prompts was incomplete** - named argument
    usage was mentioned briefly but lacked comprehensive canonical examples
    showing proper syntax and behavior.
    
    2. **Fixed by adding canonical, tested syntax and examples:**
       - Example 1: Basic named arguments with TICKET_ID and TICKET_TITLE
       - Example 2: Mixed positional and named arguments with FILE and FOCUS
       - Example 3: Using positional arguments
    - Example 4: Updated draftpr example to use proper $FEATURE_NAME syntax
       - Added clear usage examples showing KEY=value syntax
       - Added expanded prompt examples showing the result
       - Documented error handling and validation requirements
    
    3. **Added Implementation Reference section** that references the
    relevant feature implementation from the codebase (PRs #4470 and #4474
    for initial implementation, #5332 and #5403 for clarifications).
    
    This addresses issue #5039 by providing complete, accurate documentation
    for named argument usage in custom prompts.
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Improve compact (#6692)
    This PR does the following:
    - Add compact prefix to the summary
    - Change the compaction prompt
    - Allow multiple compaction for long running tasks
    - Filter out summary messages on the following compaction
    
    Considerations:
    - Filtering out the summary message isn't the most clean
    - Theoretically, we can end up in infinite compaction loop if the user
    messages > compaction limit . However, that's not possible in today's
    code because we have hard cap on user messages.
    - We need to address having multiple user messages because it confuses
    the model.
    
    Testing:
    - Making sure that after compact we always end up with one user message
    (task) and one summary, even on multiple compaction.
  • Refactor truncation helpers into its own file (#6683)
    That's to centralize the truncation in one place. Next step would be to
    make only two methods public: one with bytes/lines and one with tokens.
  • ci: only run CLA assistant for openai org repos (#6687)
    This prevents notifications coming from PRs on forked repos
  • Handle "Don't Trust" directory selection in onboarding (#4941)
    Fixes #4940
    Fixes #4892
    
    When selecting "No, ask me to approve edits and commands" during
    onboarding, the code wasn't applying the correct approval policy,
    causing Codex to block all write operations instead of requesting
    approval.
    
    This PR fixes the issue by persisting the "DontTrust" decision in
    config.toml as `trust_level = "untrusted"` and handling it in the
    sandbox and approval policy logic, so Codex correctly asks for approval
    before making changes.
    
    ## Before (bug)
    <img width="709" height="500" alt="bef"
    src="https://github.com/user-attachments/assets/5aced26d-d810-4754-879a-89d9e4e0073b"
    />
    
    ## After (fixed)
    <img width="713" height="359" alt="aft"
    src="https://github.com/user-attachments/assets/9887bbcb-a9a5-4e54-8e76-9125a782226b"
    />
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Order outputs before inputs (#6691)
    For better caching performance all output items should be rendered in
    the order they were produced before all new input items (for example,
    all function_call before all function_call_output).
  • feat: add app-server-test-client crate for internal use (#5391)
    For app-server development it's been helpful to be able to trigger some
    test flows end-to-end and print the JSON-RPC messages sent between
    client and server.
  • fix codex detection, add new security-focused smoketests. (#6682)
    Fix 'codex' detection to look for debug build, then release build, then
    installed.
    
    Adds more smoketests around security from @viyatb-oai
  • feat(ts-sdk): allow overriding CLI environment (#6648)
    ## Summary
    - add an `env` option for the TypeScript Codex client and plumb it into
    `CodexExec` so the CLI can run without inheriting `process.env`
    - extend the test spy to capture spawn environments, add coverage for
    the new option, and document how to use it
    
    ## Testing
    - `pnpm test` *(fails: corepack cannot download pnpm because outbound
    network access is blocked in the sandbox)*
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_6916b2d7c7548322a72d61d91a2dac85)
  • Add test timeout (#6612)
    Add an overall test timeout of 30s.
  • Enable TUI notifications by default (#6633)
    ## Summary
    - default the `tui.notifications` setting to enabled so desktop
    notifications work out of the box
    - update configuration tests and documentation to reflect the new
    default
    
    ## Testing
    - `cargo test -p codex-core` *(fails:
    `exec::tests::kill_child_process_group_kills_grandchildren_on_timeout`
    is flaky in this sandbox because the spawned grandchild process stays
    alive)*
    - `cargo test -p codex-core
    exec::tests::kill_child_process_group_kills_grandchildren_on_timeout`
    *(fails: same sandbox limitation as above)*
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69166f811144832c9e8aaf8ee2642373)
  • [App server] add mcp tool call item started/completed events (#6642)
    this PR does two things:
    1. refactor `apply_bespoke_event_handling` into a separate file as it's
    getting kind of long;
    2. add mcp tool call `item/started` and `item/completed` events. To roll
    out app server events asap we didn't properly migrate mcp core events to
    use TurnItem for mcp tool calls - this will be a follow-up PR.
    
    real events generated in log:
    ```
    {
      "method": "codex/event/mcp_tool_call_end",
      "params": {
        "conversationId": "019a8021-26af-7c20-83db-21ca81e44d68",
        "id": "0",
        "msg": {
          "call_id": "call_7EjRQkD9HnfyMWf7tGrT9FKA",
          "duration": {
            "nanos": 92708,
            "secs": 0
          },
          "invocation": {
            "arguments": {
              "server": ""
            },
            "server": "codex",
            "tool": "list_mcp_resources"
          },
          "result": {
            "Ok": {
              "content": [
                {
                  "text": "{\"resources\":[]}",
                  "type": "text"
                }
              ],
              "isError": false
            }
          },
          "type": "mcp_tool_call_end"
        }
      }
    }
    
    {
      "method": "item/completed",
      "params": {
        "item": {
          "arguments": {
            "server": ""
          },
          "error": null,
          "id": "call_7EjRQkD9HnfyMWf7tGrT9FKA",
          "result": {
            "content": [
              {
                "text": "{\"resources\":[]}",
                "type": "text"
              }
            ],
            "structuredContent": null
          },
          "server": "codex",
          "status": "completed",
          "tool": "list_mcp_resources",
          "type": "mcpToolCall"
        }
      }
    }
    ```
  • feat: better UI for unified_exec (#6515)
    <img width="376" height="132" alt="Screenshot 2025-11-12 at 17 36 22"
    src="https://github.com/user-attachments/assets/ce693f0d-5ca0-462e-b170-c20811dcc8d5"
    />
  • Promote shared helpers for suite tests (#6460)
    ## Summary
    - add `TestCodex::submit_turn_with_policies` and extend the response
    helpers with reusable tool-call utilities
    - update the grep_files, read_file, list_dir, shell_serialization, and
    tools suites to rely on the shared helpers instead of local copies
    - make the list_dir helper return `anyhow::Result` so clippy no longer
    warns about `expect`
    
    ## Testing
    - `just fix -p codex-core`
    - `cargo test -p codex-core --test all
    suite::grep_files::grep_files_tool_collects_matches`
    - `cargo test -p codex-core
    suite::grep_files::grep_files_tool_collects_matches -- --ignored`
    (filter requests ignored tests so nothing runs, but the build stays
    clean)
    
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69112d53abac83219813cab4d7cb6446)
  • Use shared network gating helper in chat completion tests (#6461)
    ## Summary
    - replace the bespoke network check in the chat completion payload and
    SSE tests with the existing `skip_if_no_network!` helper so they follow
    the same gating convention as the rest of the suite
    
    ## Testing
    - `just fmt`
    
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69112d4cb9f08321ba773e8ccf39778e)
  • Avoid double truncation (#6631)
    1. Avoid double truncation by giving 10% above the tool default constant
    2. Add tests that fails when const = 1
  • [app-server] small fixes for JSON schema export and one-of types (#6614)
    A partner is consuming our generated JSON schema bundle for app-server
    and identified a few issues:
    - not all polymorphic / one-of types have a type descriminator
    - `"$ref": "#/definitions/v2/SandboxPolicy"` is missing
    - "Option<>" is an invalid schema name, and also unnecessary
    
    This PR:
    - adds the type descriminator to the various types that are missing it
    except for `SessionSource` and `SubAgentSource` because they are
    serialized to disk (adding this would break backwards compat for
    resume), and they should not be necessary to consume for an integration
    with app-server.
    - removes the special handling in `export.rs` of various types like
    SandboxPolicy, which turned out to be unnecessary and incorrect
    - filters out `Option<>` which was auto-generated for request params
    that don't need a body
    
    For context, we currently pull in wayyy more types than we need through
    the `EventMsg` god object which we are **not** planning to expose in API
    v2 (this is how I suspect `SessionSource` and `SubAgentSource` are being
    pulled in). But until we have all the necessary v2 notifications in
    place that will allow us to remove `EventMsg`, we will keep exporting it
    for now.
  • [App-server] add new v2 events:item/reasoning/delta, item/agentMessage/delta & item/reasoning/summaryPartAdded (#6559)
    core event to app server event mapping:
    1. `codex/event/reasoning_content_delta` ->
    `item/reasoning/summaryTextDelta`.
    2. `codex/event/reasoning_raw_content_delta` ->
    `item/reasoning/textDelta`
    3. `codex/event/agent_message_content_delta` →
    `item/agentMessage/delta`.
    4. `codex/event/agent_reasoning_section_break` ->
    `item/reasoning/summaryPartAdded`.
    
    Also added a change in core to pass down content index, summary index
    and item id from events.
    
    Tested with the `git checkout owen/app_server_test_client && cargo run
    -p codex-app-server-test-client -- send-message-v2 "hello"` and verified
    that new events are emitted correctly.
  • chore(core) Consolidate apply_patch tests (#6545)
    ## Summary
    Consolidates our apply_patch tests into one suite, and ensures each test
    case tests the various ways the harness supports apply_patch:
    1. Freeform custom tool call
    2. JSON function tool
    3. Simple shell call
    4. Heredoc shell call
    
    There are a few test cases that are specific to a particular variant,
    I've left those alone.
    
    ## Testing
    - [x] This adds a significant number of tests
  • Only list failed tests (#6619)
    Makes output easier to parse
  • feat: Add support for --add-dir to exec and TypeScript SDK (#6565)
    ## Summary
    
    Adds support for specifying additional directories in the TypeScript SDK
    through a new `additionalDirectories` option in `ThreadOptions`.
    
    ## Changes
    
    - Added `additionalDirectories` parameter to `ThreadOptions` interface
    - Updated `CodexExec` to accept and pass through additional directories
    via the `--config` flag for `sandbox_workspace_write.writable_roots`
    - Added comprehensive test coverage for the new functionality
    
    ## Test plan
    
    - Added test case that verifies `additionalDirectories` is correctly
    passed as repeated flags
    - Existing tests continue to pass
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
  • Add AbortSignal support to TypeScript SDK (#6378)
    ## Summary
    Adds AbortSignal support to the TypeScript SDK for canceling thread
    execution using AbortController.
    
    ## Changes
    - Add `signal?: AbortSignal` property to `TurnOptions` type
    - Pass signal through Thread class methods to exec layer  
    - Add signal parameter to `CodexExecArgs`
    - Leverage Node.js native `spawn()` signal support for automatic
    cancellation
    - Add comprehensive test coverage (6 tests covering all abort scenarios)
    
    ## Implementation
    The implementation uses Node.js's built-in AbortSignal support in
    `spawn()` (available since Node v15, SDK requires >=18), which
    automatically handles:
    - Checking if already aborted before starting
    - Killing the child process when abort is triggered
    - Emitting appropriate error events
    - All cleanup operations
    
    This is a one-line change to the core implementation (`signal:
    args.signal` passed to spawn), making it simple, reliable, and
    maintainable.
    
    ## Usage Example
    ```typescript
    import { Codex } from '@openai/codex-sdk';
    
    const codex = new Codex({ apiKey: 'your-api-key' });
    const thread = codex.startThread();
    
    // Create AbortController
    const controller = new AbortController();
    
    // Run with abort signal
    const resultPromise = thread.run("Your prompt here", {
      signal: controller.signal
    });
    
    // Cancel anytime
    controller.abort('User requested cancellation');
    ```
    
    ## Testing
    All tests pass (23 total across SDK):
    -  Aborts when signal is already aborted (both run and runStreamed)
    -  Aborts during execution/iteration
    -  Completes normally when not aborted
    -  Backward compatible (signal is optional)
    
    Tests verified to fail correctly when signal support is removed (no
    false positives).
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
    Co-authored-by: pakrym-oai <pakrym@openai.com>
  • Update default yield time (#6610)
    10s for exec and 250ms for write_stdin
  • Close stale PRs workflow (#6594)
    Closes stale PRs from OpenAI employees.
  • Overhaul shell detection and centralize command generation for unified exec (#6577)
    This fixes command display for unified exec. All `cd`s and `ls`es are
    now parsed.
    
    <img width="452" height="237" alt="image"
    src="https://github.com/user-attachments/assets/ce92d81f-f74c-485a-9b34-1eaa29290ec6"
    />
    
    Deletes a ton of tests that were doing nothing from shell.rs.
    
    ---------
    
    Co-authored-by: Pavel Krymets <pavel@krymets.com>
  • fix model picker wrapping (#6589)
    Previously the popup measured rows using the full content width while
    the renderer drew them with 2 columns of padding, so at certain widths
    the layout allocated too little vertical space and hid the third option.
    Now both desired_height and render call a shared helper that subtracts
    the padding before measuring, so the height we reserve always matches
    what we draw and the menu doesn't drops entries.
    
    
    https://github.com/user-attachments/assets/59058fd9-1e34-4325-b5fe-fc888dfcb6bc
  • chore(core) Update prompt for gpt-5.1 (#6588)
    ## Summary
    Updates the prompt for GPT-5.1
  • Reasoning level update (#6586)
    Automatically update reasoning levels when migrating between models
  • Avoid hang when tool's process spawns grandchild that shares stderr/stdout (#6575)
    We've received many reports of codex hanging when calling certain tools.
    [Here](https://github.com/openai/codex/issues/3204) is one example. This
    is likely a major cause. The problem occurs when
    `consume_truncated_output` waits for `stdout` and `stderr` to be closed
    once the child process terminates. This normally works fine, but it
    doesn't handle the case where the child has spawned grandchild processes
    that inherits `stdout` and `stderr`.
    
    The fix was originally written by @md-oai in [this
    PR](https://github.com/openai/codex/pull/1852), which has gone stale.
    I've copied the original fix (which looks sound to me) and added an
    integration test to prevent future regressions.
  • Change model picker to include gpt5.1 (#6569)
    - Change the presets
    - Change the tests that make sure we keep the list of tools updated
    - Filter out deprecated models