Commit Graph
1571 Commits
Author SHA1 Message Date
Michael Bolin 865072b8b0 merge commit for archive created by Sapling 2025-05-30 11:04:14 -07:00
Michael Bolin 7c6e2fc86c fix: missed a step in #1171 for codex.yml 2025-05-30 11:04:05 -07:00
Michael Bolin 8676185389 fix: update outdated repo setup in codex.yml (#1171)
We should do some work to share the setup logic across `codex.yml`,
`ci.yml`, and `rust-ci.yml`.
2025-05-30 10:58:57 -07:00
Michael Bolin a2c8119d7e merge commit for archive created by Sapling 2025-05-30 10:58:00 -07:00
Michael Bolin faaac85967 fix: update outdated repo setup in codex.yml 2025-05-30 10:57:50 -07:00
Michael Bolin baa92f37e0 feat: initial import of experimental GitHub Action (#1170)
This is a first cut at a GitHub Action that lets you define prompt
templates in `.md` files under `.github/codex/labels` that will run
Codex with the associated prompt when the label is added to a GitHub
pull request.

For example, this PR includes these files:

```
.github/codex/labels/codex-attempt.md
.github/codex/labels/codex-code-review.md
.github/codex/labels/codex-investigate-issue.md
```

And the new `.github/workflows/codex.yml` workflow declares the
following triggers:

```yaml
on:
  issues:
    types: [opened, labeled]
  pull_request:
    branches: [main]
    types: [labeled]
```

as well as the following expression to gate the action:

```
jobs:
  codex:
    if: |
      (github.event_name == 'issues' && (
        (github.event.action == 'labeled' && (github.event.label.name == 'codex-attempt' || github.event.label.name == 'codex-investigate-issue'))
      )) ||
      (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'codex-code-review')
```

Note the "actor" who added the label must have write access to the repo
for the action to take effect.

After adding a label, the action will "ack" the request by replacing the
original label (e.g., `codex-review`) with an `-in-progress` suffix
(e.g., `codex-review-in-progress`). When it is finished, it will swap
the `-in-progress` label with a `-completed` one (e.g.,
`codex-review-completed`).

Users of the action are responsible for providing an `OPENAI_API_KEY`
and making it available as a secret to the action.
2025-05-30 10:55:28 -07:00
Michael Bolin a90acbbcaa merge commit for archive created by Sapling 2025-05-30 10:49:48 -07:00
Michael Bolin 0bac2fcbc3 feat: initial import of experimental GitHub Action 2025-05-30 10:49:41 -07:00
Michael Bolin e7eed45dbc merge commit for archive created by Sapling 2025-05-30 10:43:45 -07:00
Michael Bolin 78f116e2f9 feat: initial import of experimental GitHub Action 2025-05-30 10:43:40 -07:00
Michael Bolin df67b60f83 merge commit for archive created by Sapling 2025-05-30 10:40:48 -07:00
Michael Bolin 54869c1503 feat: initial import of experimental GitHub Action 2025-05-30 10:40:40 -07:00
Michael Bolin b0d1bfacd3 merge commit for archive created by Sapling 2025-05-30 10:40:18 -07:00
Michael Bolin 6be57c201d feat: initial import of experimental GitHub Action 2025-05-30 10:40:12 -07:00
Michael Bolin 95a2760021 Merge 7da44b1143 into sapling-pr-archive-bolinfest 2025-05-30 10:38:25 -07:00
Michael Bolin 7da44b1143 feat: initial import of experimental GitHub Action 2025-05-30 10:38:18 -07:00
Michael Bolin a0239c3cd6 fix: enable set positional-arguments in justfile (#1169)
The way these definitions worked before, they did not handle quoted args
with spaces properly.

For example, if you had `/tmp/test-just/printlen.py` as:

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

import sys

print(len(sys.argv))
```

and your `justfile` was:

```
printlen *args:
    /tmp/test-just/printlen.py {{args}}
```

Then:

```shell
$ just printlen foo bar
3
$ just printlen 'foo bar'
3
```

which is not what we want: `'foo bar'` should be treated as one
argument.

The fix is to use
[positional-arguments](https://github.com/casey/just/blob/515e806b5121a4696113ef15b5f0b12e69854570/README.md#L1131):

```
set positional-arguments

printlen *args:
    /tmp/test-just/printlen.py "$@"
```
2025-05-30 09:11:53 -07:00
Michael Bolin 056bf5f32d Merge 91cc3f642f into sapling-pr-archive-bolinfest 2025-05-30 09:06:24 -07:00
Michael Bolin 91cc3f642f fix: enable set positional-arguments in justfile 2025-05-30 09:06:18 -07:00
Michael Bolin 1dafac9f15 Merge 3931f3f91e into sapling-pr-archive-bolinfest 2025-05-30 09:06:10 -07:00
Michael Bolin 3931f3f91e fix: enable set positional-arguments in justfile 2025-05-30 09:06:03 -07:00
Michael Bolin c7048da53c merge commit for archive created by Sapling 2025-05-30 00:59:00 -07:00
Michael Bolin eb9b72365f fix: chat completions API now also passes tools along 2025-05-30 00:58:55 -07:00
Michael Bolin b8cc6b0cfd Merge 63943d608b into sapling-pr-archive-bolinfest 2025-05-30 00:56:33 -07:00
Michael Bolin 63943d608b fix: chat completions API now also passes tools along 2025-05-30 00:56:25 -07:00
Michael Bolin 205b5ccbd8 Merge 9db52a6cee into sapling-pr-archive-bolinfest 2025-05-29 17:07:15 -07:00
Michael Bolin 9db52a6cee fix: chat completions API now also passes tools along 2025-05-29 17:07:07 -07:00
Michael Bolin bdfa95ed31 docs: split the config-related portion of codex-rs/README.md into its own config.md file (#1165)
Also updated the overview on `codex-rs/README.md` while here.
codex-rs-dfac02b343605ce61154ab2e075ac6c38f533916-1-rust-v0.0.2505291659
2025-05-29 16:59:35 -07:00
Michael Bolin d186f6bdc8 merge commit for archive created by Sapling 2025-05-29 16:57:35 -07:00
Michael Bolin fa4dfba064 docs: split the config-related portion of codex-rs/README.md into its own config.md file 2025-05-29 16:57:29 -07:00
Fouad Matin 828e2062c2 fix(codex-rs): use codex-mini-latest as default (#1164) 2025-05-29 16:55:19 -07:00
Michael Bolin d2fda98479 Merge 59466c66d6 into sapling-pr-archive-bolinfest 2025-05-29 16:52:39 -07:00
Michael Bolin 59466c66d6 docs: split the config-related portion of codex-rs/README.md into its own config.md file 2025-05-29 16:52:35 -07:00
Michael Bolin e7b9f79ec0 merge commit for archive created by Sapling 2025-05-29 16:11:46 -07:00
Michael Bolin cc6497aa68 fix: chat completions API now also passes tools along 2025-05-29 16:11:34 -07:00
Michael Bolin 5652569acd Merge 14c28b5f21 into sapling-pr-archive-bolinfest 2025-05-29 15:59:00 -07:00
Michael Bolin 14c28b5f21 docs: split the config-related portion of codex-rs/README.md into its own config.md file 2025-05-29 15:58:54 -07:00
Michael Bolin 92957c47fb fix: update justfile to facilitate running CLIs from source and formatting source code (#1163) 2025-05-29 15:35:14 -07:00
Michael Bolin 8c1902b562 chore: update GitHub workflow for native artifacts for npm release (#1162)
Among other things, this picks up this UI treatment fix:

https://github.com/openai/codex/pull/1161
2025-05-29 15:34:06 -07:00
Michael Bolin a9cf88f4d4 Merge eebcb8ae54 into sapling-pr-archive-bolinfest 2025-05-29 15:32:39 -07:00
Michael Bolin eebcb8ae54 chore: update GitHub workflow for native artifacts for npm release 2025-05-29 15:31:46 -07:00
Michael Bolin 07f52f3aa1 Merge 56f6b6e4fd into sapling-pr-archive-bolinfest 2025-05-29 15:31:06 -07:00
Michael Bolin 56f6b6e4fd fix: update justfile to facilitate running CLIs from source and formatting source code 2025-05-29 15:31:00 -07:00
Michael Bolin 265f916c35 Merge 173374e376 into sapling-pr-archive-bolinfest 2025-05-29 15:27:55 -07:00
Michael Bolin 173374e376 chore: update GitHub workflow for native artifacts for npm release 2025-05-29 15:27:20 -07:00
Michael Bolin a32d305ae6 fix: update UI treatment of slash command menu to match that of the TS CLI (#1161)
Uses the same colors as in the TypeScript CLI:


![image](https://github.com/user-attachments/assets/919cd472-ffb4-4654-a46a-d84f0cd9c097)

Now it is also readable on a light theme, e.g., in Ghostty:


![image](https://github.com/user-attachments/assets/468c37b0-ea63-4455-9b48-73dc2c95f0f6)
codex-rs-b152435fb95e7f1ab197ae2cdde68ae29a7d219b-1-rust-v0.0.2505291458
2025-05-29 14:57:55 -07:00
Michael Bolin c46c87e455 Merge 189f3d3cb6 into sapling-pr-archive-bolinfest 2025-05-29 14:53:15 -07:00
Michael Bolin 189f3d3cb6 fix: update UI treatment of slash command menu to match that of the TS CLI 2025-05-29 14:53:08 -07:00
Michael Bolin a768a6a41d fix: introduce ResponseInputItem::McpToolCallOutput variant (#1151)
The output of an MCP server tool call can be one of several types, but
to date, we treated all outputs as text by showing the serialized JSON
as the "tool output" in Codex:


https://github.com/openai/codex/blob/25a9949c49194d5a64de54a11bcc5b4724ac9bd5/codex-rs/mcp-types/src/lib.rs#L96-L101

This PR adds support for the `ImageContent` variant so we can now
display an image output from an MCP tool call.

In making this change, we introduce a new
`ResponseInputItem::McpToolCallOutput` variant so that we can work with
the `mcp_types::CallToolResult` directly when the function call is made
to an MCP server.

Though arguably the more significant change is the introduction of
`HistoryCell::CompletedMcpToolCallWithImageOutput`, which is a cell that
uses `ratatui_image` to render an image into the terminal. To support
this, we introduce `ImageRenderCache`, cache a
`ratatui_image::picker::Picker`, and `ensure_image_cache()` to cache the
appropriate scaled image data and dimensions based on the current
terminal size.

To test, I created a minimal `package.json`:

```json
{
  "name": "kitty-mcp",
  "version": "1.0.0",
  "type": "module",
  "description": "MCP that returns image of kitty",
  "main": "index.js",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.12.0"
  }
}
```

with the following `index.js` to define the MCP server:

```js
#!/usr/bin/env node

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { readFile } from "node:fs/promises";
import { join } from "node:path";

const IMAGE_URI = "image://Ada.png";

const server = new McpServer({
  name: "Demo",
  version: "1.0.0",
});

server.tool(
  "get-cat-image",
  "If you need a cat image, this tool will provide one.",
  async () => ({
    content: [
      { type: "image", data: await getAdaPngBase64(), mimeType: "image/png" },
    ],
  })
);

server.resource("Ada the Cat", IMAGE_URI, async (uri) => {
  const base64Image = await getAdaPngBase64();
  return {
    contents: [
      {
        uri: uri.href,
        mimeType: "image/png",
        blob: base64Image,
      },
    ],
  };
});

async function getAdaPngBase64() {
  const __dirname = new URL(".", import.meta.url).pathname;
  // From https://github.com/benjajaja/ratatui-image/blob/9705ce2c59ec669abbce2924cbfd1f5ae22c9860/assets/Ada.png
  const filePath = join(__dirname, "Ada.png");
  const imageData = await readFile(filePath);
  const base64Image = imageData.toString("base64");
  return base64Image;
}

const transport = new StdioServerTransport();
await server.connect(transport);
```

With the local changes from this PR, I added the following to my
`config.toml`:

```toml
[mcp_servers.kitty]
command = "node"
args = ["/Users/mbolin/code/kitty-mcp/index.js"]
```

Running the TUI from source:

```
cargo run --bin codex -- --model o3 'I need a picture of a cat'
```

I get:

<img width="732" alt="image"
src="https://github.com/user-attachments/assets/bf80b721-9ca0-4d81-aec7-77d6899e2869"
/>

Now, that said, I have only tested in iTerm and there is definitely some
funny business with getting an accurate character-to-pixel ratio
(sometimes the `CompletedMcpToolCallWithImageOutput` thinks it needs 10
rows to render instead of 4), so there is still work to be done here.
2025-05-28 19:03:17 -07:00
Michael Bolin 6e3b94f975 merge commit for archive created by Sapling 2025-05-28 18:56:15 -07:00