Commit Graph

1532 Commits

Author SHA1 Message Date
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:


25a9949c49/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 9705ce2c59/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
Michael Bolin
8100a09f49 fix: introduce ResponseInputItem::McpToolCallOutput variant 2025-05-28 18:56:07 -07:00
Michael Bolin
1a6fac4d50 merge commit for archive created by Sapling 2025-05-28 17:18:15 -07:00
Michael Bolin
e0c278566f fix: introduce ResponseInputItem::McpToolCallOutput variant 2025-05-28 17:17:26 -07:00
Michael Bolin
25a9949c49 fix: ensure inputSchema for MCP tool always has "properties" field when talking to OpenAI (#1150)
As noted in the comment introduced in this PR, this is analogous to the
issue reported in
https://github.com/openai/openai-agents-python/issues/449. This seems to
work now.
2025-05-28 17:17:21 -07:00
Michael Bolin
3340322f1c merge commit for archive created by Sapling 2025-05-28 17:10:30 -07:00
Michael Bolin
45931c8398 fix: introduce ResponseInputItem::McpToolCallOutput variant 2025-05-28 17:10:20 -07:00
Michael Bolin
fbccf0d9f6 fix: ensure inputSchema for MCP tool always has "properties" field when talking to OpenAI 2025-05-28 17:10:20 -07:00
Michael Bolin
392fdd7db6 fix: honor RUST_LOG in mcp-client CLI and default to DEBUG (#1149)
We had `debug!()` logging statements already, but they weren't being
printed because `tracing_subscriber` was not set up.
2025-05-28 17:10:06 -07:00
Michael Bolin
d89e9d9741 merge commit for archive created by Sapling 2025-05-28 17:05:57 -07:00
Michael Bolin
27b2c41643 fix: introduce ResponseInputItem::McpToolCallOutput variant 2025-05-28 17:05:35 -07:00
Michael Bolin
fc8e891637 fix: ensure inputSchema for MCP tool always has "properties" field when talking to OpenAI 2025-05-28 17:05:35 -07:00
Michael Bolin
41d34ee1ae fix: honor RUST_LOG in mcp-client CLI and default to DEBUG 2025-05-28 17:05:34 -07:00
Michael Bolin
ae1a83f095 feat: introduce CellWidget trait (#1148)
The motivation behind this PR is to make it so a `HistoryCell` is more
like a `WidgetRef` that knows how to render itself into a `Rect` so that
it can be backed by something other than a `Vec<Line>`. Because a
`HistoryCell` is intended to appear in a scrollable list, we want to
ensure the stack of cells can be scrolled one `Line` at a time even if
the `HistoryCell` is not backed by a `Vec<Line>` itself.

To this end, we introduce the `CellWidget` trait whose key method is:

```
fn render_window(&self, first_visible_line: usize, area: Rect, buf: &mut Buffer);
```

The `first_visible_line` param is what differs from
`WidgetRef::render_ref()`, as a `CellWidget` needs to know the offset
into its "full view" at which it should start rendering.

The bookkeeping in `ConversationHistoryWidget` has been updated
accordingly to ensure each `CellWidget` in the history is rendered
appropriately.
2025-05-28 14:03:19 -07:00
Michael Bolin
bb1cd38f0e Merge 23d47c4d48 into sapling-pr-archive-bolinfest 2025-05-28 13:26:46 -07:00
Michael Bolin
23d47c4d48 feat: introduce CellWidget trait 2025-05-28 13:26:39 -07:00
Michael Bolin
d60f350cf8 feat: add support for -c/--config to override individual config items (#1137)
This PR introduces support for `-c`/`--config` so users can override
individual config values on the command line using `--config
name=value`. Example:

```
codex --config model=o4-mini
```

Making it possible to set arbitrary config values on the command line
results in a more flexible configuration scheme and makes it easier to
provide single-line examples that can be copy-pasted from documentation.

Effectively, it means there are four levels of configuration for some
values:

- Default value (e.g., `model` currently defaults to `o4-mini`)
- Value in `config.toml` (e.g., user could override the default to be
`model = "o3"` in their `config.toml`)
- Specifying `-c` or `--config` to override `model` (e.g., user can
include `-c model=o3` in their list of args to Codex)
- If available, a config-specific flag can be used, which takes
precedence over `-c` (e.g., user can specify `--model o3` in their list
of args to Codex)

Now that it is possible to specify anything that could be configured in
`config.toml` on the command line using `-c`, we do not need to have a
custom flag for every possible config option (which can clutter the
output of `--help`). To that end, as part of this PR, we drop support
for the `--disable-response-storage` flag, as users can now specify `-c
disable_response_storage=true` to get the equivalent functionality.

Under the hood, this works by loading the `config.toml` into a
`toml::Value`. Then for each `key=value`, we create a small synthetic
TOML file with `value` so that we can run the TOML parser to get the
equivalent `toml::Value`. We then parse `key` to determine the point in
the original `toml::Value` to do the insert/replace. Once all of the
overrides from `-c` args have been applied, the `toml::Value` is
deserialized into a `ConfigToml` and then the `ConfigOverrides` are
applied, as before.
2025-05-27 23:11:44 -07:00
Michael Bolin
c2ea43d05f merge commit for archive created by Sapling 2025-05-27 22:26:41 -07:00
Michael Bolin
52875c20ae feat: add support for -c/--config to override individual config items 2025-05-27 22:26:34 -07:00
Michael Bolin
e5c71e2304 merge commit for archive created by Sapling 2025-05-27 22:16:05 -07:00
Michael Bolin
6d4baff7d4 feat: add support for -c/--config to override individual config items 2025-05-27 22:15:58 -07:00
Michael Bolin
adc672476f merge commit for archive created by Sapling 2025-05-27 22:00:18 -07:00
Michael Bolin
fd8e479435 feat: add support for -c/--config to override individual config items 2025-05-27 21:59:13 -07:00
Michael Bolin
44b153aee4 merge commit for archive created by Sapling 2025-05-27 21:44:25 -07:00
Michael Bolin
57d7987942 feat: add support for -c/--config to override individual config items 2025-05-27 21:44:14 -07:00
Michael Bolin
9cc192a35c merge commit for archive created by Sapling 2025-05-27 17:57:27 -07:00
Michael Bolin
b8b755e060 feat: add support for -c/--config to override individual config items 2025-05-27 17:57:19 -07:00
Michael Bolin
8202e24478 merge commit for archive created by Sapling 2025-05-27 17:46:26 -07:00
Michael Bolin
24a6334688 feat: add support for -c/--config to override individual config items 2025-05-27 17:46:18 -07:00
Michael Bolin
af0cfc78d9 merge commit for archive created by Sapling 2025-05-27 14:26:45 -07:00
Michael Bolin
ee21a61978 feat: add support for -c/--config to override individual config items 2025-05-27 14:26:36 -07:00
Michael Bolin
70026fb7fe merge commit for archive created by Sapling 2025-05-27 12:55:24 -07:00
Michael Bolin
b9302c46d3 feat: add support for -c/--config to override individual config items 2025-05-27 12:55:17 -07:00
Michael Bolin
d7e8f05f2a merge commit for archive created by Sapling 2025-05-27 11:31:53 -07:00
Michael Bolin
a9409dc175 feat: add support for -c/--config to override individual config items 2025-05-27 11:31:47 -07:00
Michael Bolin
c9e942b6da merge commit for archive created by Sapling 2025-05-27 11:03:30 -07:00
Michael Bolin
2a797839ed feat: add support for -c/--config to override individual config items 2025-05-27 11:03:21 -07:00
Michael Bolin
b68a9274d8 Merge 1c9594b18b into sapling-pr-archive-bolinfest 2025-05-27 10:46:14 -07:00
Michael Bolin
1c9594b18b feat: add support for -c/--config to override individual config items 2025-05-27 10:46:05 -07:00
Michael Bolin
eba0e32909 fix: update install_native_deps.sh to pick up the latest release (#1136) 2025-05-27 10:06:41 -07:00