Commit Graph
8422 Commits
Author SHA1 Message Date
Michael Bolin f29e6b4904 fix: run python_multiprocessing_lock_works integration test on Mac and Linux 2025-08-14 14:59:09 -07:00
Michael Bolin a8c7f5391c fix: move general sandbox tests to codex-rs/core/tests/sandbox.rs (#2317)
Previous to this PR, `codex-rs/core/tests/sandbox.rs` contained
integration tests that were specific to Seatbelt. This PR moves those
tests to `codex-rs/core/src/seatbelt.rs` and designates
`codex-rs/core/tests/sandbox.rs` to be used as the home for
cross-platform (well, Mac and Linux...) sandbox tests.

To start, this migrates
`python_multiprocessing_lock_works_under_seatbelt()` from #1823 to the
new `sandbox.rs` because this is the type of thing that should work on
both Mac _and_ Linux, though I still need to do some work to clean up
the test so it works on both platforms.
2025-08-14 14:48:38 -07:00
Michael Bolin 41864520b0 Merge f010ff1be4 into sapling-pr-archive-bolinfest 2025-08-14 14:32:19 -07:00
Michael Bolin f010ff1be4 fix: move general sandbox tests to codex-rs/core/tests/sandbox.rs 2025-08-14 14:32:13 -07:00
David Z Hao 992e81d9b5 test(core): add seatbelt sem lock tests (#1823)
## Summary
- add a unit test to ensure the macOS seatbelt policy allows POSIX
semaphores
- add a macOS-only test that runs a Python multiprocessing Lock under
Seatbelt

## Testing
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast` (failed: failed to download from
`https://static.crates.io/crates/tokio-stream/0.1.17/download`)
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast --offline` (failed: attempting to make an HTTP request,
but --offline was specified)
- `cargo test --all-features --no-fail-fast --offline` (failed:
attempting to make an HTTP request, but --offline was specified)
- `just fmt` (failed: command not found: just)
- `just fix` (failed: command not found: just)

Ran tests locally to confirm it passes on master and failed before my
previous change

------
https://chatgpt.com/codex/tasks/task_i_6890f221e0a4833381cfb53e11499bcc
2025-08-14 14:23:06 -07:00
Jeremy Rose 7038827bf4 fix bash commands being incorrectly quoted in display (#2313)
The "display format" of commands was sometimes producing incorrect
quoting like `echo foo '>' bar`, which is importantly different from the
actual command that was being run. This refactors ParsedCommand to have
a string in `cmd` instead of a vec, as a `vec` can't accurately capture
a full command.
2025-08-14 17:08:29 -04:00
Jeremy Rose 20cd61e2a4 use a central animation loop (#2268)
instead of each shimmer needing to have its own animation thread, have
render_ref schedule a new frame if it wants one and coalesce to the
earliest next frame. this also makes the animations
frame-timing-independent, based on start time instead of frame count.
2025-08-14 16:59:47 -04:00
Jeremy Rose fd2b059504 text elements in textarea for pasted content (#2302)
This improves handling of pasted content in the textarea. It's no longer
possible to partially delete a placeholder (e.g. by ^W or ^D), nor is it
possible to place the cursor inside a placeholder. Also, we now render
placeholders in a different color to make them more clearly
differentiated.


https://github.com/user-attachments/assets/2051b3c3-963d-4781-a610-3afee522ae29
2025-08-14 20:58:51 +00:00
Michael Bolin c25f3ea53e fix: do not allow dotenv to create/modify environment variables starting with CODEX_ (#2308)
This ensures Codex cannot drop a `.env` file with a value of
`CODEX_HOME` that points to a folder that Codex can control.
2025-08-14 13:57:15 -07:00
Michael Bolin 8f11652458 fix: parallelize logic in Session::new() (#2305)
#2291 made it so that `Session::new()` is on the critical path to
`Codex::spawn()`, which means it is on the hot path to CLI startup. This
refactors `Session::new()` to run a number of async tasks in parallel
that were previously run serially to try to reduce latency.
2025-08-14 13:29:58 -07:00
Michael Bolin 9f85f3ccca Merge 941483b740 into sapling-pr-archive-bolinfest 2025-08-14 13:06:45 -07:00
Michael Bolin 941483b740 fix: parallelize logic in Session::new() 2025-08-14 13:06:33 -07:00
aibrahim-oai b62c2d9552 remove logs from composer by default (#2307)
Currently the composer shows `handle_codex_event:<event name>` by
default which feels confusing. Let's make it appear in trace.
2025-08-14 13:01:15 -07:00
Jeremy Rose 475ba13479 remove the · animation (#2271)
the pulsing dot felt too noisy to me next to the shimmering "Working"
text. we'll bring it back for streaming response text perhaps?
2025-08-14 19:30:41 +00:00
Michael Bolin c1adb6a7a2 merge commit for archive created by Sapling 2025-08-14 12:17:13 -07:00
Michael Bolin d3f5ad6c33 fix: do not allow dotenv to create/modify environment variables starting with CODEX_ 2025-08-14 12:16:19 -07:00
Michael Bolin e7d0627cb5 Merge cc0c30a50d into sapling-pr-archive-bolinfest 2025-08-14 12:05:12 -07:00
Michael Bolin cc0c30a50d fix: do not allow dotenv to create/modify environment variables starting with CODEX_ 2025-08-14 12:05:04 -07:00
Dylan 544980c008 [context] Store context messages in rollouts (#2243)
## Summary
Currently, we use request-time logic to determine the user_instructions
and environment_context messages. This means that neither of these
values can change over time as conversations go on. We want to add in
additional details here, so we're migrating these to save these messages
to the rollout file instead. This is simpler for the client, and allows
us to append additional environment_context messages to each turn if we
want

## Testing
- [x] Integration test coverage
- [x] Tested locally with a few turns, confirmed model could reference
environment context and cached token metrics were reasonably high
2025-08-14 14:51:13 -04:00
Jeremy Rose b42e679227 remove "status text" in bottom line (#2279)
this used to hold the most recent log line, but it was kinda broken and
not that useful.
2025-08-14 14:10:21 -04:00
Jeremy Rose 585f7b0679 HistoryCell is a trait (#2283)
refactors HistoryCell to be a trait instead of an enum. Also collapse
the many "degenerate" HistoryCell enums which were just a store of lines
into a single PlainHistoryCell type.

The goal here is to allow more ways of rendering history cells (e.g.
expanded/collapsed/"live"), and I expect we will return to more varied
types of HistoryCell as we develop this area.
2025-08-14 14:10:05 -04:00
Gabriel Peal cdd33b2c04 Tag InputItem (#2304)
Instead of:
```
{ Text: { text: string } }
```

It is now:
```
{ type: "text", data: { text: string } }
```
which makes for cleaner discriminated unions
2025-08-14 17:58:04 +00:00
Michael Bolin f1f54ef6f7 merge commit for archive created by Sapling 2025-08-14 10:48:54 -07:00
Michael Bolin ce34871ccf fix: parallelize logic in Session::new() 2025-08-14 10:48:49 -07:00
Michael Bolin eb5ea22e80 merge commit for archive created by Sapling 2025-08-14 10:40:12 -07:00
Michael Bolin a07132f451 fix: parallelize logic in Session::new() 2025-08-14 10:39:56 -07:00
Michael Bolin cf7a7e63a3 exploration: create Session as part of Codex::spawn() (#2291)
Historically, `Codex::spawn()` would create the instance of `Codex` and
enforce, by construction, that `Op::ConfigureSession` was the first `Op`
submitted via `submit()`. Then over in `submission_loop()`, it would
handle the case for taking the parameters of `Op::ConfigureSession` and
turning it into a `Session`.

This approach has two challenges from a state management perspective:


https://github.com/openai/codex/blob/f968a1327ad39a7786759ea8f1d1c088fe41e91b/codex-rs/core/src/codex.rs#L718

- The local `sess` variable in `submission_loop()` has to be `mut` and
`Option<Arc<Session>>` because it is not invariant that a `Session` is
present for the lifetime of the loop, so there is a lot of logic to deal
with the case where `sess` is `None` (e.g., the `send_no_session_event`
function and all of its callsites).
- `submission_loop()` is written in such a way that
`Op::ConfigureSession` could be observed multiple times, but in
practice, it is only observed exactly once at the start of the loop.

In this PR, we try to simplify the state management by _removing_ the
`Op::ConfigureSession` enum variant and constructing the `Session` as
part of `Codex::spawn()` so that it can be passed to `submission_loop()`
as `Arc<Session>`. The original logic from the `Op::ConfigureSession`
has largely been moved to the new `Session::new()` constructor.

---

Incidentally, I also noticed that the handling of `Op::ConfigureSession`
can result in events being dispatched in addition to
`EventMsg::SessionConfigured`, as an `EventMsg::Error` is created for
every MCP initialization error, so it is important to preserve that
behavior:


https://github.com/openai/codex/blob/f968a1327ad39a7786759ea8f1d1c088fe41e91b/codex-rs/core/src/codex.rs#L901-L916

Though admittedly, I believe this does not play nice with #2264, as
these error messages will likely be dispatched before the client has a
chance to call `addConversationListener`, so we likely need to make it
so `newConversation` automatically creates the subscription, but we must
also guarantee that the "ack" from `newConversation` is returned before
any other conversation-related notifications are sent so the client
knows what `conversation_id` to match on.
2025-08-14 09:55:28 -07:00
Michael Bolin a10e80e2c3 merge commit for archive created by Sapling 2025-08-14 09:34:10 -07:00
Michael Bolin 4245cead9f exploration: create Session as part of Codex::spawn() 2025-08-14 09:32:31 -07:00
Michael Bolin 398079af6b merge commit for archive created by Sapling 2025-08-14 00:07:18 -07:00
Michael Bolin b8627ef358 exploration: create Session as part of Codex::spawn() 2025-08-14 00:07:08 -07:00
Michael Bolin c4c9cb942b Merge 070970af30 into sapling-pr-archive-bolinfest 2025-08-13 23:42:57 -07:00
Michael Bolin 070970af30 exploration: rollback #1602 2025-08-13 23:42:50 -07:00
Michael Bolin f968a1327a feat: add support for an InterruptConversation request (#2287)
This adds `ClientRequest::InterruptConversation`, which effectively maps
directly to `Op::Interrupt`.

---

* __->__  #2287
* #2286
* #2285
2025-08-13 23:12:03 -07:00
Michael Bolin 661d56204c Merge 8d6a1b462f into sapling-pr-archive-bolinfest 2025-08-13 23:01:07 -07:00
Michael Bolin 8d6a1b462f feat: add support for an InterruptConversation request 2025-08-13 23:01:00 -07:00
Michael Bolin 539f4b290e fix: add support for exec and apply_patch approvals in the new wire format (#2286)
Now when `CodexMessageProcessor` receives either a
`EventMsg::ApplyPatchApprovalRequest` or a
`EventMsg::ExecApprovalRequest`, it sends the appropriate request from
the server to the client. When it gets a response, it forwards it on to
the `CodexConversation`.

Note this takes a lot of code from:


https://github.com/openai/codex/blob/main/codex-rs/mcp-server/src/conversation_loop.rs

https://github.com/openai/codex/blob/main/codex-rs/mcp-server/src/exec_approval.rs

https://github.com/openai/codex/blob/main/codex-rs/mcp-server/src/patch_approval.rs

I am copy/pasting for now because I am trying to consolidate around the
new `wire_format.rs`, so I plan to delete these other files soon.

Now that we have requests going both from client-to-server and
server-to-client, I renamed `CodexRequest` to `ClientRequest`.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/2286).
* #2287
* __->__ #2286
* #2285
2025-08-13 23:00:50 -07:00
Michael Bolin ab4c4e0831 Merge 2e44ccc409 into sapling-pr-archive-bolinfest 2025-08-13 22:54:35 -07:00
Michael Bolin 2e44ccc409 feat: add support for an InterruptConversation request 2025-08-13 22:54:20 -07:00
Michael Bolin 0afb5b2b66 fix: make all fields of Session private
***
fix: add support for exec and apply_patch approvals in the new wire format
2025-08-13 22:54:20 -07:00
Michael Bolin 085f166707 fix: make all fields of Session private (#2285)
As `Session` needs a bit of work, it will make things easier to move
around if we can start by reducing the extent of its public API. This
makes all the fields private, though adds three `pub(crate)` getters.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/2285).
* #2287
* #2286
* __->__ #2285
2025-08-13 22:53:54 -07:00
Michael Bolin ff8ef4a9ca Merge fdcdf0843e into sapling-pr-archive-bolinfest 2025-08-13 22:37:38 -07:00
Michael Bolin fdcdf0843e feat: add support for an InterruptConversation request 2025-08-13 22:37:31 -07:00
Michael Bolin 3111817c62 Merge 7e8c80f005 into sapling-pr-archive-bolinfest 2025-08-13 22:25:27 -07:00
Michael Bolin 7e8c80f005 fix: make all fields of Session private
***
fix: add support for exec and apply_patch approvals in the new wire format
2025-08-13 22:25:07 -07:00
Michael Bolin 93c7015b6a Merge a0ff6e8395 into sapling-pr-archive-bolinfest 2025-08-13 22:24:38 -07:00
Michael Bolin a0ff6e8395 fix: make all fields of Session private 2025-08-13 22:24:03 -07:00
Michael Bolin 7ae4de59de Merge 6c2ed966f2 into sapling-pr-archive-bolinfest 2025-08-13 22:21:05 -07:00
Michael Bolin 6c2ed966f2 fix: add support for exec and apply_patch approvals in the new wire format 2025-08-13 22:20:14 -07:00
Michael Bolin f086da31e5 fix: make all fields of Session private 2025-08-13 22:16:47 -07:00