Commit Graph
644 Commits
Author SHA1 Message Date
Michael Bolin 66a2153d4f Merge 3f73058676 into sapling-pr-archive-bolinfest 2025-05-03 13:52:15 -07:00
Michael Bolin 3f73058676 feat: make cwd a required field of Config so we stop assuming std::env::current_dir() in a session 2025-05-03 13:52:06 -07:00
Michael Bolin 717dac4690 Merge da049df255 into sapling-pr-archive-bolinfest 2025-05-03 12:31:08 -07:00
Michael Bolin da049df255 feat: drop support for q since we already support ctrl+d 2025-05-03 12:30:58 -07:00
Andrey Mishchenko 4b61fb8bab use "Title case" in README.md (#798) 2025-05-03 10:17:44 -07:00
Michael Bolin 0442458309 doc: update the config.toml documentation for the Rust CLI in codex-rs/README.md (#795)
https://github.com/openai/codex/pull/793 had important information on
the `notify` config option that seemed worth memorializing, so this PR
updates the documentation about all of the configurable options in
`~/.codex/config.toml`.
2025-05-02 20:32:24 -07:00
Michael Bolin 7c7b55e7c9 merge commit for archive created by Sapling 2025-05-02 20:30:23 -07:00
Michael Bolin cbd97f54e5 doc: update the config.toml documentation for the Rust CLI in codex-rs/README.md 2025-05-02 20:30:18 -07:00
Michael Bolin a001909243 merge commit for archive created by Sapling 2025-05-02 20:29:23 -07:00
Michael Bolin 630880e379 doc: update the config.toml documentation for the Rust CLI in codex-rs/README.md 2025-05-02 20:29:18 -07:00
Michael Bolin 84c0b0c589 Merge dfa0c64528 into sapling-pr-archive-bolinfest 2025-05-02 20:27:14 -07:00
Michael Bolin dfa0c64528 doc: update the config.toml documentation for the Rust CLI in codex-rs/README.md 2025-05-02 20:27:06 -07:00
Michael Bolin a180ed44e8 feat: configurable notifications in the Rust CLI (#793)
With this change, you can specify a program that will be executed to get
notified about events generated by Codex. The notification info will be
packaged as a JSON object. The supported notification types are defined
by the `UserNotification` enum introduced in this PR. Initially, it
contains only one variant, `AgentTurnComplete`:

```rust
pub(crate) enum UserNotification {
    #[serde(rename_all = "kebab-case")]
    AgentTurnComplete {
        turn_id: String,

        /// Messages that the user sent to the agent to initiate the turn.
        input_messages: Vec<String>,

        /// The last message sent by the assistant in the turn.
        last_assistant_message: Option<String>,
    },
}
```

This is intended to support the common case when a "turn" ends, which
often means it is now your chance to give Codex further instructions.

For example, I have the following in my `~/.codex/config.toml`:

```toml
notify = ["python3", "/Users/mbolin/.codex/notify.py"]
```

I created my own custom notifier script that calls out to
[terminal-notifier](https://github.com/julienXX/terminal-notifier) to
show a desktop push notification on macOS. Contents of `notify.py`:

```python
#!/usr/bin/env python3

import json
import subprocess
import sys


def main() -> int:
    if len(sys.argv) != 2:
        print("Usage: notify.py <NOTIFICATION_JSON>")
        return 1

    try:
        notification = json.loads(sys.argv[1])
    except json.JSONDecodeError:
        return 1

    match notification_type := notification.get("type"):
        case "agent-turn-complete":
            assistant_message = notification.get("last-assistant-message")
            if assistant_message:
                title = f"Codex: {assistant_message}"
            else:
                title = "Codex: Turn Complete!"
            input_messages = notification.get("input_messages", [])
            message = " ".join(input_messages)
            title += message
        case _:
            print(f"not sending a push notification for: {notification_type}")
            return 0

    subprocess.check_output(
        [
            "terminal-notifier",
            "-title",
            title,
            "-message",
            message,
            "-group",
            "codex",
            "-ignoreDnD",
            "-activate",
            "com.googlecode.iterm2",
        ]
    )

    return 0


if __name__ == "__main__":
    sys.exit(main())
```

For reference, here are related PRs that tried to add this functionality
to the TypeScript version of the Codex CLI:

* https://github.com/openai/codex/pull/160
* https://github.com/openai/codex/pull/498
codex-rs-5915a59c8290765d6097caf4074aae93a85380fa-1-rust-v0.0.2505021951
2025-05-02 19:48:13 -07:00
Michael Bolin 2cee8b914e Merge 68a493930a into sapling-pr-archive-bolinfest 2025-05-02 19:37:33 -07:00
Michael Bolin 68a493930a feat: add support for notifications 2025-05-02 19:37:27 -07:00
Michael Bolin 21cd953dbd feat: introduce mcp-server crate (#792)
This introduces the `mcp-server` crate, which contains a barebones MCP
server that provides an `echo` tool that echoes the user's request back
to them.

To test it out, I launched
[modelcontextprotocol/inspector](https://github.com/modelcontextprotocol/inspector)
like so:

```
mcp-server$ npx @modelcontextprotocol/inspector cargo run --
```

and opened up `http://127.0.0.1:6274` in my browser:


![image](https://github.com/user-attachments/assets/83fc55d4-25c2-4497-80cd-e9702283ff93)

I also had to make a small fix to `mcp-types`, adding
`#[serde(untagged)]` to a number of `enum`s.
2025-05-02 17:25:58 -07:00
Michael Bolin 8a14aedcc7 Merge 03323bbe75 into sapling-pr-archive-bolinfest 2025-05-02 16:59:41 -07:00
Michael Bolin 03323bbe75 feat: introduce mcp-server crate 2025-05-02 16:59:37 -07:00
Michael Bolin d71452eb97 merge commit for archive created by Sapling 2025-05-02 16:44:32 -07:00
Michael Bolin 47d859b049 feat: introduce mcp-server crate 2025-05-02 16:44:27 -07:00
Michael Bolin 3c1171245f Merge 45c8623fe9 into sapling-pr-archive-bolinfest 2025-05-02 16:38:26 -07:00
Michael Bolin 45c8623fe9 feat: introduce mcp-server crate 2025-05-02 16:38:21 -07:00
Michael Bolin 865e518771 fix: mcp-types serialization wasn't quite working (#791)
While creating a basic MCP server in
https://github.com/openai/codex/pull/792, I discovered a number of bugs
with the initial `mcp-types` crate that I needed to fix in order to
implement the server.

For example, I discovered that when serializing a message, `"jsonrpc":
"2.0"` was not being included.

I changed the codegen so that the field is added as:

```rust
    #[serde(rename = "jsonrpc", default = "default_jsonrpc")]
    pub jsonrpc: String,
```

This ensures that the field is serialized as `"2.0"`, though the field
still has to be assigned, which is tedious. I may experiment with
`Default` or something else in the future. (I also considered creating a
custom serializer, but I'm not sure it's worth the trouble.)

While here, I also added `MCP_SCHEMA_VERSION` and `JSONRPC_VERSION` as
`pub const`s for the crate.

I also discovered that MCP rejects sending `null` for optional fields,
so I had to add `#[serde(skip_serializing_if = "Option::is_none")]` on
`Option` fields.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/791).
* #792
* __->__ #791
2025-05-02 16:38:05 -07:00
Michael Bolin 6d9298787e Merge d4538c333c into sapling-pr-archive-bolinfest 2025-05-02 16:30:06 -07:00
Michael Bolin d4538c333c feat: introduce mcp-server crate 2025-05-02 16:29:57 -07:00
Michael Bolin 61825ccf25 Merge 97bdc586a4 into sapling-pr-archive-bolinfest 2025-05-02 16:09:23 -07:00
Michael Bolin 97bdc586a4 fix: ensure jsonrpc field is serialized as "2.0" 2025-05-02 16:09:01 -07:00
Michael Bolin 0d315104fe merge commit for archive created by Sapling 2025-05-02 15:29:44 -07:00
Michael Bolin 423ac7c7e9 fix: ensure jsonrpc field is serialized as "2.0" 2025-05-02 15:29:38 -07:00
Michael Bolin 3e9af0abb7 Merge 434d6ef892 into sapling-pr-archive-bolinfest 2025-05-02 15:05:29 -07:00
Michael Bolin 434d6ef892 fix: ensure jsonrpc field is serialized as "2.0" 2025-05-02 15:05:19 -07:00
Michael Bolin 2748894ca2 Merge 0a70ed663f into sapling-pr-archive-bolinfest 2025-05-02 15:04:35 -07:00
Michael Bolin 0a70ed663f fix: ensure jsonrpc field is serialized as "2.0" 2025-05-02 15:04:29 -07:00
Michael Bolin 3d0726109c merge commit for archive created by Sapling 2025-05-02 15:01:32 -07:00
Michael Bolin c8f85b45e1 fix: ensure jsonrpc field is serialized as "2.0" 2025-05-02 14:39:00 -07:00
Michael Bolin 83961e0299 feat: introduce mcp-types crate (#787)
This adds our own `mcp-types` crate to our Cargo workspace. We vendor in
the
[`2025-03-26/schema.json`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/05f204513641c05bd78d056791af99c6c84520fa/schema/2025-03-26/schema.json)
from the MCP repo and introduce a `generate_mcp_types.py` script to
codegen the `lib.rs` from the JSON schema.

Test coverage is currently light, but I plan to refine things as we
start making use of this crate.

And yes, I am aware that
https://github.com/modelcontextprotocol/rust-sdk exists, though the
published https://crates.io/crates/rmcp appears to be a competing
effort. While things are up in the air, it seems better for us to
control our own version of this code.

Incidentally, Codex did a lot of the work for this PR. I told it to
never edit `lib.rs` directly and instead to update
`generate_mcp_types.py` and then re-run it to update `lib.rs`. It
followed these instructions and once things were working end-to-end, I
iteratively asked for changes to the tests until the API looked
reasonable (and the code worked). Codex was responsible for figuring out
what to do to `generate_mcp_types.py` to achieve the requested test/API
changes.
2025-05-02 13:33:14 -07:00
Michael Bolin d045ce7ed7 merge commit for archive created by Sapling 2025-05-02 12:46:11 -07:00
Michael Bolin 48a15728e2 feat: introduce mcp-types crate 2025-05-02 12:46:04 -07:00
Michael Bolin 620871cc48 merge commit for archive created by Sapling 2025-05-02 12:37:49 -07:00
Michael Bolin 9bf3ab35ff feat: introduce mcp-types crate 2025-05-02 12:37:39 -07:00
Michael Bolin 53e395969e Merge 71ffb6df1b into sapling-pr-archive-bolinfest 2025-05-02 12:25:41 -07:00
Michael Bolin 71ffb6df1b feat: introduce mcp-types crate 2025-05-02 12:25:28 -07:00
f6b1ce2e3a Configure HTTPS agent for proxies (#775)
- Some workflows require you to route openAI API traffic through a proxy
- See
https://github.com/openai/openai-node/tree/v4?tab=readme-ov-file#configuring-an-https-agent-eg-for-proxies
for more details

---------

Co-authored-by: Thibault Sottiaux <tibo@openai.com>
Co-authored-by: Fouad Matin <fouad@openai.com>
2025-05-02 12:08:13 -07:00
Fouad Matin b864cc3810 update: vite version (#766) 2025-05-02 09:30:08 -07:00
Michael Bolin a4b51f6b67 feat: use Landlock for sandboxing on Linux in TypeScript CLI (#763)
Building on top of https://github.com/openai/codex/pull/757, this PR
updates Codex to use the Landlock executor binary for sandboxing in the
Node.js CLI. Note that Codex has to be invoked with either `--full-auto`
or `--auto-edit` to activate sandboxing. (Using `--suggest` or
`--dangerously-auto-approve-everything` ensures the sandboxing codepath
will not be exercised.)

When I tested this on a Linux host (specifically, `Ubuntu 24.04.1 LTS`),
things worked as expected: I ran Codex CLI with `--full-auto` and then
asked it to do `echo 'hello mbolin' into hello_world.txt` and it
succeeded without prompting me.

However, in my testing, I discovered that the sandboxing did *not* work
when using `--full-auto` in a Linux Docker container from a macOS host.
I updated the code to throw a detailed error message when this happens:


![image](https://github.com/user-attachments/assets/e5b99def-f00e-4ade-a0c5-2394d30df52e)
2025-05-01 12:34:56 -07:00
Michael Bolin 9db12eb5d2 merge commit for archive created by Sapling 2025-05-01 11:48:14 -07:00
Michael Bolin 3d5cdd3fd5 feat: use Landlock for sandboxing on Linux 2025-05-01 11:48:09 -07:00
Michael Bolin 9bc4fde11b merge commit for archive created by Sapling 2025-05-01 11:47:20 -07:00
Michael Bolin a490029d67 feat: use Landlock for sandboxing on Linux 2025-05-01 11:47:14 -07:00
Michael Bolin 1acf0d0e24 merge commit for archive created by Sapling 2025-05-01 08:46:06 -07:00