Commit graph

2291 commits

Author SHA1 Message Date
Michael Bolin
7386e2efbc
fix: clear out space on ubuntu runners before running Rust tests (#7678)
When I put up https://github.com/openai/codex/pull/7617 for review,
initially I started seeing failures on the `ubuntu-24.04` runner used
for Rust test runs for the `x86_64-unknown-linux-gnu` architecture. Chat
suggested a number of things that could be removed to save space, which
seems to help.
2025-12-06 21:46:07 -08:00
Victor
b2cb05d562
docs: point dev checks to just (#7673)
Update install and contributing guides to use the root justfile helpers
(`just fmt`, `just fix -p <crate>`, and targeted tests) instead of the
older cargo fmt/clippy/test instructions that have been in place since
459363e17b. This matches the justfile relocation to the repo root in
952d6c946 and the current lint/test workflow for CI (see
`.github/workflows/rust-ci.yml`).
2025-12-06 18:57:08 -08:00
Jay Sabva
9a74228c66
docs: Remove experimental_use_rmcp_client from config (#7672)
Removed experimental Rust MCP client option from config.
2025-12-06 16:51:07 -08:00
Jay Sabva
315b1e957d
docs: fix documentation of rmcp client flag (#7665)
## Summary
- Updated the rmcp client flag's documentation in config.md file
- changed it from `experimental_use_rmcp_client` to `rmcp_client`
2025-12-06 10:17:18 -08:00
Michael Bolin
82090803d9
fix: exec-server stream was erroring for large requests (#7654)
Previous to this change, large `EscalateRequest` payloads exceeded the
kernel send buffer, causing our single `sendmsg(2)` call (with attached
FDs) to be split and retried without proper control handling; this led
to `EINVAL`/broken pipe in the
`handle_escalate_session_respects_run_in_sandbox_decision()` test when
using an `env` with large contents.

**Before:** `AsyncSocket::send_with_fds()` called `send_json_message()`,
which called `send_message_bytes()`, which made one `socket.sendmsg()`
call followed by additional `socket.send()` calls, as necessary:


2e4a402521/codex-rs/exec-server/src/posix/socket.rs (L198-L209)

**After:** `AsyncSocket::send_with_fds()` now calls
`send_stream_frame()`, which calls `send_stream_chunk()` one or more
times. Each call to `send_stream_chunk()` calls `socket.sendmsg()`.

In the previous implementation, the subsequent `socket.send()` writes
had no control information associated with them, whereas in the new
`send_stream_chunk()` implementation, a fresh `MsgHdr` (using
`with_control()`, as appropriate) is created for `socket.sendmsg()` each
time.

Additionally, with this PR, stream sending attaches `SCM_RIGHTS` only on
the first chunk, and omits control data when there are no FDs, allowing
oversized payloads to deliver correctly while preserving FD limits and
error checks.
2025-12-06 10:16:47 -08:00
Alexander
f521d29726
fix: OTEL HTTP exporter panic and mTLS support (#7651)
This fixes two issues with the OTEL HTTP exporter:

1. **Runtime panic with async reqwest client**

The `opentelemetry_sdk` `BatchLogProcessor` spawns a dedicated OS thread
that uses `futures_executor::block_on()` rather than tokio's runtime.
When the async reqwest client's timeout mechanism calls
`tokio::time::sleep()`, it panics with "there is no reactor running,
must be called from the context of a Tokio 1.x runtime".

The fix is to use `reqwest::blocking::Client` instead, which doesn't
depend on tokio for timeouts. However, the blocking client creates its
own internal tokio runtime during construction, which would panic if
built from within an async context. We wrap the construction in
`tokio::task::block_in_place()` to handle this.

2. **mTLS certificate handling**

The HTTP client wasn't properly configured for mTLS, matching the fixes
previously done for the model provider client:

- Added `.tls_built_in_root_certs(false)` when using a custom CA
certificate to ensure only our CA is trusted
- Added `.https_only(true)` when using client identity
- Added `rustls-tls` feature to ensure rustls is used (required for
`Identity::from_pem()` to work correctly)
2025-12-05 20:46:44 -08:00
xl-openai
93f61dbc5f
Also load skills from repo root. (#7645)
Also load skills from /REPO_ROOT/codex/skills.
2025-12-05 18:01:49 -08:00
Dylan Hurd
6c9c563faf
fix(apply-patch): preserve CRLF line endings on Windows (#7515)
## Summary
This PR is heavily based on #4017, which contains the core logic for the
fix. To reduce the risk, we are first introducing it only on windows. We
can then expand to wsl / other environments as needed, and then tackle
net new files.

## Testing
- [x] added unit tests in apply-patch
- [x] add integration tests to apply_patch_cli.rs

---------

Co-authored-by: Chase Naples <Cnaples79@gmail.com>
2025-12-05 16:43:27 -08:00
Josh McKinney
952d6c9465
Move justfile to repository root (#7652)
## Summary
- move the workspace justfile to the repository root for easier
discovery
- set the just working directory to codex-rs so existing recipes still
run in the Rust workspace

## Testing
- not run (not requested)


------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_69334db473108329b0cc253b7fd8218e)
2025-12-05 16:24:55 -08:00
Jeremy Rose
2e4a402521
cloud: status, diff, apply (#7614)
Adds cli commands for getting the status of cloud tasks, and for
getting/applying the diffs from same.
2025-12-05 21:39:23 +00:00
Pavel Krymets
f48d88067e
Fix unified_exec on windows (#7620)
Fix unified_exec on windows

Requires removal of PSUEDOCONSOLE_INHERIT_CURSOR flag so child processed
don't attempt to wait for cursor position response (and timeout).


https://github.com/wezterm/wezterm/compare/main...pakrym:wezterm:PSUEDOCONSOLE_INHERIT_CURSOR?expand=1

---------

Co-authored-by: pakrym-oai <pakrym@openai.com>
2025-12-05 20:09:43 +00:00
Dylan Hurd
a8cbbdbc6e
feat(core) Add login to shell_command tool (#6846)
## Summary
Adds the `login` parameter to the `shell_command` tool - optional,
defaults to true.

## Testing
- [x] Tested locally
2025-12-05 11:03:25 -08:00
Ahmed Ibrahim
d08efb1743
Wire with_remote_overrides to construct model families (#7621)
- This PR wires `with_remote_overrides` and make the
`construct_model_families` an async function
- Moves getting model family a level above to keep the function `sync`
- Updates the tests to local, offline, and `sync` helper for model
families
2025-12-05 10:40:15 -08:00
jif-oai
5f80ad6da8
fix: chat completion with parallel tool call (#7634) 2025-12-05 10:20:36 -08:00
jif-oai
e91bb6b947
fix: ignore ghost snapshots in token consumption (#7638) 2025-12-05 13:57:24 +00:00
zhao-oai
b8eab7ce90
fix: taking plan type from usage endpoint instead of thru auth token (#7610)
pull plan type from the usage endpoint, persist it in session state /
tui state, and propagate through rate limit snapshots
2025-12-04 23:34:13 -08:00
zhao-oai
b1c918d8f7
feat: exec policy integration in shell mcp (#7609)
adding execpolicy support into the `posix` mcp

Co-authored-by: Michael Bolin <mbolin@openai.com>
2025-12-04 21:55:54 -08:00
zhao-oai
4c9762d15c
fix typo (#7626) 2025-12-04 21:48:15 -08:00
Ahmed Ibrahim
7b359c9c8e
Call models endpoint in models manager (#7616)
- Introduce `with_remote_overrides` and update
`refresh_available_models`
- Put `auth_manager` instead of `auth_mode` on `models_manager`
- Remove `ShellType` and `ReasoningLevel` to use already existing
structs
2025-12-04 18:28:03 -08:00
jif-oai
6736d1828d
fix: sse for chat (#7594) 2025-12-04 16:46:56 -08:00
Dylan Hurd
073a8533b8
chore(apply-patch) scenarios for e2e testing (#7567)
## Summary
This PR introduces an End to End test suite for apply-patch, so we can
easily validate behavior against other implementations as well.

## Testing
- [x] These are tests
2025-12-05 00:20:54 +00:00
Michael Bolin
0972cd9404
chore: refactor to move Arc<RwLock> concern outside exec_policy_for (#7615)
The caller should decide whether wrapping the policy in `Arc<RwLock>` is
necessary. This should make https://github.com/openai/codex/pull/7609 a
bit smoother.

- `exec_policy_for()` -> `load_exec_policy_for_features()`
- introduce `load_exec_policy()` that does not take `Features` as an arg
- both return `Result<Policy, ExecPolicyError>` instead of
Result<Arc<RwLock<Policy>>, ExecPolicyError>`

This simplifies the tests as they have no need for `Arc<RwLock>`.
2025-12-04 15:13:27 -08:00
Robby He
28dcdb566a
Fix handle_shortcut_overlay_key for cross-platform consistency (#7583)
**Summary**
- Shortcut toggle using `?` in `handle_shortcut_overlay_key` fails to
trigger on some platforms (notably Windows). Current match requires
`KeyCode::Char('?')` with `KeyModifiers::NONE`. Some terminals set
`SHIFT` when producing `?` (since it is typically `Shift + /`), so the
strict `NONE` check prevents toggling.

**Impact**
- On Windows consoles/terminals, pressing `?` with an empty composer
often does nothing, leading to inconsistent UX compared to macOS/Linux.

**Root Cause**
- Crossterm/terminal backends report modifiers inconsistently across
platforms. Generating `?` may include `SHIFT`. The code enforces
`modifiers == NONE`, so valid `?` presses with `SHIFT` are ignored.
AltGr keyboards may also surface as `ALT`.

**Repro Steps**
- Open the TUI, ensure the composer is empty.
- Press `?`.
- Expected: Shortcut overlay toggles.
- Actual (Windows frequently): No toggle occurs.

**Fix Options**
- Option 1 (preferred): Accept `?` regardless of `SHIFT`, but reject
`CONTROL` and `ALT`.
- Rationale: Keeps behavior consistent across platforms with minimal
code change.
	- Example change:
		- Before: matching `KeyModifiers::NONE` only.
		- After: allow `SHIFT`, disallow `CONTROL | ALT`.
		- Suggested condition:
			```rust
			let toggles = matches!(key_event.code, KeyCode::Char('?'))
&& !key_event.modifiers.intersects(KeyModifiers::CONTROL |
KeyModifiers::ALT)
					&& self.is_empty();
			```

- Option 2: Platform-specific handling (Windows vs non-Windows).
- Implement two variants or conditional branches using `#[cfg(target_os
= "windows")]`.
- On Windows, accept `?` with `SHIFT`; on other platforms, retain
current behavior.
- Trade-off: Higher maintenance burden and code divergence for limited
benefit.

---

close #5495
2025-12-04 14:56:58 -08:00
Owen Lin
e8f6d65899
fix(app-server): add will_retry to ErrorNotification (#7611)
VSCE renders `codex/event/stream_error` (automatically retried, e.g.
`"Reconnecting... 1/n"`) and `codex/event/error` (terminal errors)
differently, so add `will_retry` on ErrorNotification to indicate this.
2025-12-04 21:48:37 +00:00
Owen Lin
342c084cc3
fix(app-server): add duration_ms to McpToolCallItem (#7605)
Seems like a nice field to have, and also VSCE does render this one.
2025-12-04 13:45:07 -08:00
Ahmed Ibrahim
903b7774bc
Add models endpoint (#7603)
- Use the codex-api crate to introduce models endpoint. 
- Add `models` to codex core tests helpers
- Add `ModelsInfo` for the endpoint return type
2025-12-04 12:57:54 -08:00
Ahmed Ibrahim
6e6338aa87
Inline response recording and remove process_items indirection (#7310)
- Inline response recording during streaming: `run_turn` now records
items as they arrive instead of building a `ProcessedResponseItem` list
and post‑processing via `process_items`.
- Simplify turn handling: `handle_output_item_done` returns the
follow‑up signal + optional tool future; `needs_follow_up` is set only
there, and in‑flight tool futures are drained once at the end (errors
logged, no extra state writes).
- Flattened stream loop: removed `process_items` indirection and the
extra output queue
- - Tests: relaxed `tool_parallelism::tool_results_grouped` to allow any
completion order while still requiring matching call/output IDs.
2025-12-04 12:17:54 -08:00
Jeremy Rose
7dfc3a4dc7
add --branch to codex cloud exec (#7602)
Adds `--branch` to `codex cloud exec` to set base branch.
2025-12-04 12:00:18 -08:00
Ahmed Ibrahim
9b2055586d
remove model_family from `config (#7571)
- Remove `model_family` from `config`
- Make sure to still override config elements related to `model_family`
like supporting reasoning
2025-12-04 11:57:58 -08:00
Maxime Savard
ce0b38c056
FIX: WSL Paste image does not work (#6793)
## Related issues:  
- https://github.com/openai/codex/issues/3939  
- https://github.com/openai/codex/issues/2292  
- https://github.com/openai/codex/issues/7528 (After correction
https://github.com/openai/codex/pull/3990)

**Area:** `codex-cli` (image handling / clipboard & file uploads)  
**Platforms affected:** WSL (Ubuntu on Windows 10/11). No behavior
change on native Linux/macOS/Windows.

## Summary

This PR fixes image pasting and file uploads when running `codex-cli`
inside WSL. Previously, image operations failed silently or with
permission errors because paths weren't properly mapped between Windows
and WSL filesystems.

## Visual Result

<img width="1118" height="798" alt="image"
src="https://github.com/user-attachments/assets/14e10bc4-6b71-4d1f-b2a6-52c0a67dd069"
/>

## Last Rust-Cli

<img width="1175" height="859" alt="image"
src="https://github.com/user-attachments/assets/7ef41e29-9118-42c9-903c-7116d21e1751"
/>

## Root cause

The CLI assumed native Linux/Windows environments and didn't handle the
WSL↔Windows boundary:

- Used Linux paths for files that lived on the Windows host
- Missing path normalization between Windows (`C:\...`) and WSL
(`/mnt/c/...`)
- Clipboard access failed under WSL

### Why `Ctrl+V` doesn't work in WSL terminals

Most WSL terminal emulators (Windows Terminal, ConEmu, etc.) intercept
`Ctrl+V` at the terminal level to paste text from the Windows clipboard.
This keypress never reaches the CLI application itself, so our clipboard
image handler never gets triggered. Users need `Ctrl+Alt+V`.

## Changes

### WSL detection & path mapping

- Detects WSL by checking `/proc/sys/kernel/osrelease` and the
`WSL_INTEROP` env var
- Maps Windows drive paths to WSL mount paths (`C:\...` → `/mnt/c/...`)

### Clipboard fallback for WSL

- When clipboard access fails under WSL, falls back to PowerShell to
extract images from the Windows clipboard
- Saves to a temp file and maps the path back to WSL

### UI improvements

- Shows `Ctrl+Alt+V` hint on WSL (many terminals intercept plain
`Ctrl+V`)
- Better error messages for unreadable images

## Performance

- Negligible overhead. The fallback adds a single FS copy to a temp file
only when needed.
- Direct streaming remains the default.

## Files changed

- `protocol/src/lib.rs` – Added platform detection module  
- `protocol/src/models.rs` – Added WSL path mapping for local images  
- `protocol/src/platform.rs` – New module with WSL detection utilities  
- `tui/src/bottom_pane/chat_composer.rs` – Added base64 data URL support
and WSL path mapping
- `tui/src/bottom_pane/footer.rs` – WSL-aware keyboard shortcuts  
- `tui/src/clipboard_paste.rs` – PowerShell clipboard fallback

## How to reproduce the original bug (pre-fix)

1. Run `codex-cli` inside WSL2 on Windows.  
2. Paste an image from the Windows clipboard or drag an image from
`C:\...` into the terminal.
3. Observe that the image is not attached (silent failure) or an error
is logged; no artifact reaches the tool.

## How to verify the fix

1. Build this branch and run `codex-cli` inside WSL2.  
2. Paste from clipboard and drag from both Windows and WSL paths.  
3. Confirm that the image appears in the tool and the CLI shows a single
concise info line (no warning unless fallback was used).

I’m happy to adjust paths, naming, or split helpers into a separate
module if you prefer.

## How to try this branch

If you want to try this before it’s merged, you can use my Git branch:

Repository: https://github.com/Waxime64/codex.git  
Branch: `wsl-image-2`

1. Start WSL on your Windows machine.
2. Clone the repository and switch to the branch:
   ```bash
   git clone https://github.com/Waxime64/codex.git
   cd codex
   git checkout wsl-image-2
   # then go into the Rust workspace root, e.g.:
   cd codex-rs
3. Build the TUI binary:
  cargo build -p codex-tui --bin codex-tui --release
4. Install the binary:
   sudo install -m 0755 target/release/codex-tui /usr/local/bin/codex
5. From the project directory where you want to use Codex, start it
with:
   cd /path/to/your/project
   /usr/local/bin/codex

On WSL, use CTRL+ALT+V to paste an image from the Windows clipboard into
the chat.
2025-12-04 10:50:20 -08:00
Dylan Hurd
37c36024c7
chore(core): test apply_patch_cli on Windows (#7554)
## Summary
These tests pass on windows, let's enable them.

## Testing
- [x] These are more tests
2025-12-04 10:39:45 -08:00
jif-oai
291b54a762
chore: review in read-only (#7593) 2025-12-04 10:01:12 -08:00
jif-oai
2b5d0b2935
feat: update sandbox policy to allow TTY (#7580)
**Change**: Seatbelt now allows file-ioctl on /dev/ttys[0-9]+ even
without the sandbox extension so pre-created PTYs remain interactive
(Python REPL, shells).

**Risk**: A seatbelted process that already holds a PTY fd (including
one it shouldn’t) could issue tty ioctls like TIOCSTI or termios changes
on that fd. This doesn’t allow opening new PTYs or reading/writing them;
it only broadens ioctl capability on existing fds.

**Why acceptable**: We already hand the child its PTY for interactive
use; restoring ioctls is required for isatty() and prompts to work. The
attack requires being given or inheriting a sensitive PTY fd; by design
we don’t hand untrusted processes other users’ PTYs (we don't hand them
any PTYs actually), so the practical exposure is limited to the PTY
intentionally allocated for the session.

**Validation**:
Running
```
start a python interpreter and keep it running
```
Followed by:
* `calculate 1+1 using it` -> works as expected
* `Use this Python session to run the command just fix in
/Users/jif/code/codex/codex-rs` -> does not work as expected
2025-12-04 17:58:58 +00:00
zhao-oai
404a1ea34b
Update execpolicy.md (#7595) 2025-12-04 17:55:42 +00:00
jif-oai
36edb412b1
fix: release session ID when not used (#7592) 2025-12-04 17:42:16 +00:00
jif-oai
1b2509f05a
chore: default warning messages to true (#7588) 2025-12-04 17:29:23 +00:00
pakrym-oai
f1b7cdc3bd
Use shared check sandboxing (#7547) 2025-12-04 08:34:09 -08:00
pakrym-oai
c4e18f1b63
Slightly better status display for unified exec (#7563)
Trim bash -lc
2025-12-04 08:32:54 -08:00
jif-oai
8f4e00e1f1
chore: tool tip for /prompt (#7591) 2025-12-04 15:13:49 +00:00
zhao-oai
87666695ba
execpolicy tui flow (#7543)
## Updating the `execpolicy` TUI flow

In the TUI, when going through the command approval flow, codex will now
ask the user if they would like to whitelist the FIRST unmatched command
among a chain of commands.

For example, let's say the agent wants to run `apple | pear` with an
empty `execpolicy`

Neither apple nor pear will match to an `execpolicy` rule. Thus, when
prompting the user, codex tui will ask the user if they would like to
whitelist `apple`.

If the agent wants to run `apple | pear` again, they would be prompted
again because pear is still unknown. when prompted, the user will now be
asked if they'd like to whitelist `pear`.

Here's a demo video of this flow:


https://github.com/user-attachments/assets/fd160717-f6cb-46b0-9f4a-f0a974d4e710

This PR also removed the `allow for this session` option from the TUI.
2025-12-04 07:58:13 +00:00
ae
871f44f385
Add Enterprise plan to ChatGPT login description (#6918)
## Summary
- update ChatGPT onboarding login description to mention Enterprise
plans alongside Plus, Pro, and Team

## Testing
- just fmt


------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_691e088daf20832c88d8b667adf45128)
2025-12-03 23:47:46 -08:00
zhao-oai
3d35cb4619
Refactor execpolicy fallback evaluation (#7544)
## Refactor of the `execpolicy` crate

To illustrate why we need this refactor, consider an agent attempting to
run `apple | rm -rf ./`. Suppose `apple` is allowed by `execpolicy`.
Before this PR, `execpolicy` would consider `apple` and `pear` and only
render one rule match: `Allow`. We would skip any heuristics checks on
`rm -rf ./` and immediately approve `apple | rm -rf ./` to run.

To fix this, we now thread a `fallback` evaluation function into
`execpolicy` that runs when no `execpolicy` rules match a given command.
In our example, we would run `fallback` on `rm -rf ./` and prevent
`apple | rm -rf ./` from being run without approval.
2025-12-03 23:39:48 -08:00
zhao-oai
e925a380dc
whitelist command prefix integration in core and tui (#7033)
this PR enables TUI to approve commands and add their prefixes to an
allowlist:
<img width="708" height="605" alt="Screenshot 2025-11-21 at 4 18 07 PM"
src="https://github.com/user-attachments/assets/56a19893-4553-4770-a881-becf79eeda32"
/>

note: we only show the option to whitelist the command when 
1) command is not multi-part (e.g `git add -A && git commit -m 'hello
world'`)
2) command is not already matched by an existing rule
2025-12-03 23:17:02 -08:00
Jeremy Rose
ccdeb9d9c4
use markdown for rendering tips (#7557)
## Summary
- render tooltip content through the markdown renderer and prepend a
bold Tip label
- wrap tooltips at the available width using the indent’s measured width
before adding the indent

## Testing
- `/root/.cargo/bin/just fmt`
- `RUSTFLAGS="--cfg tokio_unstable" TOKIO_UNSTABLE=1
/root/.cargo/bin/just fix -p codex-tui` *(fails: codex-tui tests
reference tokio::time::advance/start_paused gated behind the tokio
test-util feature)*
- `RUSTFLAGS="--cfg tokio_unstable" TOKIO_UNSTABLE=1 cargo test -p
codex-tui` *(fails: codex-tui tests reference
tokio::time::advance/start_paused gated behind the tokio test-util
feature)*

------
[Codex
Task](https://chatgpt.com/codex/tasks/task_i_693081406050832c9772ae9fa5dd77ca)
2025-12-04 04:58:35 +00:00
Ahmed Ibrahim
67e67e054f
Migrate codex max (#7566)
- make codex max the default
- fix: we were doing some async work in sync function which caused tui
to panic
2025-12-03 20:54:48 -08:00
Eric Traut
edd98dd3b7
Remove test from #7481 that doesn't add much value (#7558)
Follow-up from PR #7481
2025-12-03 19:10:54 -08:00
Celia Chen
3e6cd5660c
[app-server] make file_path for config optional (#7560)
When we are writing to config using `config/value/write` or
`config/batchWrite`, it always require a `config/read` before it right
now in order to get the correct file path to write to. make this
optional so we read from the default user config file if this is not
passed in.
2025-12-04 03:08:18 +00:00
Ahmed Ibrahim
cee37a32b2
Migrate model family to models manager (#7565)
This PR moves `ModelsFamily` to `openai_models`. It also propagates
`ModelsManager` to session services and use it to drive model family. We
also make `derive_default_model_family` private because it's a step
towards what we want: one place that gives model configuration.

This is a second step at having one source of truth for models
information and config: `ModelsManager`.

Next steps would be to remove `ModelsFamily` from config. That's massive
because it's being used in 41 occasions mostly pre launching `codex`.
Also, we need to make `find_family_for_model` private. It's also big
because it's being used in 21 occasions ~ all tests.
2025-12-03 18:49:47 -08:00
Ahmed Ibrahim
8da91d1c89
Migrate tui to use models manager (#7555)
- This PR treats the `ModelsManager` like `AuthManager` and propagate it
into the tui, replacing the `builtin_model_presets`
- We are also decreasing the visibility of `builtin_model_presets`

based on https://github.com/openai/codex/pull/7552
2025-12-03 18:00:47 -08:00
Ahmed Ibrahim
00cc00ead8
Introduce ModelsManager and migrate app-server to use it. (#7552) 2025-12-03 17:17:56 -08:00