2025-05-16 14:38:08 -07:00
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use base64::Engine;
|
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
|
|
|
|
use mcp_types::CallToolResult;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use serde::Deserialize;
|
2025-07-23 10:37:45 -07:00
|
|
|
|
use serde::Deserializer;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
use serde::Serialize;
|
2025-05-07 08:37:48 -07:00
|
|
|
|
use serde::ser::Serializer;
|
2025-09-08 14:54:47 -07:00
|
|
|
|
use ts_rs::TS;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
use crate::protocol::InputItem;
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum ResponseInputItem {
|
|
|
|
|
|
Message {
|
|
|
|
|
|
role: String,
|
|
|
|
|
|
content: Vec<ContentItem>,
|
|
|
|
|
|
},
|
|
|
|
|
|
FunctionCallOutput {
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
output: FunctionCallOutputPayload,
|
|
|
|
|
|
},
|
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
|
|
|
|
McpToolCallOutput {
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
result: Result<CallToolResult, String>,
|
|
|
|
|
|
},
|
2025-08-22 13:42:34 -07:00
|
|
|
|
CustomToolCallOutput {
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
output: String,
|
|
|
|
|
|
},
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum ContentItem {
|
|
|
|
|
|
InputText { text: String },
|
|
|
|
|
|
InputImage { image_url: String },
|
|
|
|
|
|
OutputText { text: String },
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum ResponseItem {
|
|
|
|
|
|
Message {
|
2025-09-05 10:41:47 -07:00
|
|
|
|
#[serde(skip_serializing)]
|
2025-07-23 10:37:45 -07:00
|
|
|
|
id: Option<String>,
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
role: String,
|
|
|
|
|
|
content: Vec<ContentItem>,
|
|
|
|
|
|
},
|
2025-05-10 21:43:27 -07:00
|
|
|
|
Reasoning {
|
2025-09-09 14:47:06 -07:00
|
|
|
|
#[serde(default, skip_serializing)]
|
2025-05-10 21:43:27 -07:00
|
|
|
|
id: String,
|
|
|
|
|
|
summary: Vec<ReasoningItemReasoningSummary>,
|
2025-08-13 18:39:58 -07:00
|
|
|
|
#[serde(default, skip_serializing_if = "should_serialize_reasoning_content")]
|
2025-08-05 01:56:13 -07:00
|
|
|
|
content: Option<Vec<ReasoningItemContent>>,
|
2025-07-23 10:37:45 -07:00
|
|
|
|
encrypted_content: Option<String>,
|
2025-05-10 21:43:27 -07:00
|
|
|
|
},
|
2025-05-16 14:38:08 -07:00
|
|
|
|
LocalShellCall {
|
|
|
|
|
|
/// Set when using the chat completions API.
|
2025-09-05 10:41:47 -07:00
|
|
|
|
#[serde(skip_serializing)]
|
2025-05-16 14:38:08 -07:00
|
|
|
|
id: Option<String>,
|
|
|
|
|
|
/// Set when using the Responses API.
|
|
|
|
|
|
call_id: Option<String>,
|
|
|
|
|
|
status: LocalShellStatus,
|
|
|
|
|
|
action: LocalShellAction,
|
|
|
|
|
|
},
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
FunctionCall {
|
2025-09-05 10:41:47 -07:00
|
|
|
|
#[serde(skip_serializing)]
|
2025-07-23 10:37:45 -07:00
|
|
|
|
id: Option<String>,
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
name: String,
|
|
|
|
|
|
// The Responses API returns the function call arguments as a *string* that contains
|
|
|
|
|
|
// JSON, not as an already‑parsed object. We keep it as a raw string here and let
|
|
|
|
|
|
// Session::handle_function_call parse it into a Value. This exactly matches the
|
|
|
|
|
|
// Chat Completions + Responses API behavior.
|
|
|
|
|
|
arguments: String,
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
},
|
|
|
|
|
|
// NOTE: The input schema for `function_call_output` objects that clients send to the
|
|
|
|
|
|
// OpenAI /v1/responses endpoint is NOT the same shape as the objects the server returns on the
|
|
|
|
|
|
// SSE stream. When *sending* we must wrap the string output inside an object that includes a
|
|
|
|
|
|
// required `success` boolean. The upstream TypeScript CLI does this implicitly. To ensure we
|
|
|
|
|
|
// serialize exactly the expected shape we introduce a dedicated payload struct and flatten it
|
|
|
|
|
|
// here.
|
|
|
|
|
|
FunctionCallOutput {
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
output: FunctionCallOutputPayload,
|
|
|
|
|
|
},
|
2025-08-22 13:42:34 -07:00
|
|
|
|
CustomToolCall {
|
2025-09-05 10:41:47 -07:00
|
|
|
|
#[serde(skip_serializing)]
|
2025-08-22 13:42:34 -07:00
|
|
|
|
id: Option<String>,
|
|
|
|
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
status: Option<String>,
|
|
|
|
|
|
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
name: String,
|
|
|
|
|
|
input: String,
|
|
|
|
|
|
},
|
|
|
|
|
|
CustomToolCallOutput {
|
|
|
|
|
|
call_id: String,
|
|
|
|
|
|
output: String,
|
|
|
|
|
|
},
|
2025-08-28 19:24:38 -07:00
|
|
|
|
// Emitted by the Responses API when the agent triggers a web search.
|
|
|
|
|
|
// Example payload (from SSE `response.output_item.done`):
|
|
|
|
|
|
// {
|
|
|
|
|
|
// "id":"ws_...",
|
|
|
|
|
|
// "type":"web_search_call",
|
|
|
|
|
|
// "status":"completed",
|
|
|
|
|
|
// "action": {"type":"search","query":"weather: San Francisco, CA"}
|
|
|
|
|
|
// }
|
|
|
|
|
|
WebSearchCall {
|
2025-09-05 10:41:47 -07:00
|
|
|
|
#[serde(skip_serializing)]
|
2025-08-28 19:24:38 -07:00
|
|
|
|
id: Option<String>,
|
|
|
|
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
status: Option<String>,
|
|
|
|
|
|
action: WebSearchAction,
|
|
|
|
|
|
},
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
#[serde(other)]
|
|
|
|
|
|
Other,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-13 18:39:58 -07:00
|
|
|
|
fn should_serialize_reasoning_content(content: &Option<Vec<ReasoningItemContent>>) -> bool {
|
|
|
|
|
|
match content {
|
|
|
|
|
|
Some(content) => !content
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
.any(|c| matches!(c, ReasoningItemContent::ReasoningText { .. })),
|
|
|
|
|
|
None => false,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-25 12:08:18 -07:00
|
|
|
|
impl From<ResponseInputItem> for ResponseItem {
|
|
|
|
|
|
fn from(item: ResponseInputItem) -> Self {
|
|
|
|
|
|
match item {
|
2025-07-23 10:37:45 -07:00
|
|
|
|
ResponseInputItem::Message { role, content } => Self::Message {
|
|
|
|
|
|
role,
|
|
|
|
|
|
content,
|
|
|
|
|
|
id: None,
|
|
|
|
|
|
},
|
2025-04-25 12:08:18 -07:00
|
|
|
|
ResponseInputItem::FunctionCallOutput { call_id, output } => {
|
|
|
|
|
|
Self::FunctionCallOutput { call_id, output }
|
|
|
|
|
|
}
|
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
|
|
|
|
ResponseInputItem::McpToolCallOutput { call_id, result } => Self::FunctionCallOutput {
|
|
|
|
|
|
call_id,
|
|
|
|
|
|
output: FunctionCallOutputPayload {
|
|
|
|
|
|
success: Some(result.is_ok()),
|
|
|
|
|
|
content: result.map_or_else(
|
|
|
|
|
|
|tool_call_err| format!("err: {tool_call_err:?}"),
|
|
|
|
|
|
|result| {
|
|
|
|
|
|
serde_json::to_string(&result)
|
|
|
|
|
|
.unwrap_or_else(|e| format!("JSON serialization error: {e}"))
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
2025-08-22 13:42:34 -07:00
|
|
|
|
ResponseInputItem::CustomToolCallOutput { call_id, output } => {
|
|
|
|
|
|
Self::CustomToolCallOutput { call_id, output }
|
|
|
|
|
|
}
|
2025-04-25 12:08:18 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-05-16 14:38:08 -07:00
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
|
|
pub enum LocalShellStatus {
|
|
|
|
|
|
Completed,
|
|
|
|
|
|
InProgress,
|
|
|
|
|
|
Incomplete,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-05-16 14:38:08 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum LocalShellAction {
|
|
|
|
|
|
Exec(LocalShellExecAction),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-05-16 14:38:08 -07:00
|
|
|
|
pub struct LocalShellExecAction {
|
|
|
|
|
|
pub command: Vec<String>,
|
|
|
|
|
|
pub timeout_ms: Option<u64>,
|
|
|
|
|
|
pub working_directory: Option<String>,
|
|
|
|
|
|
pub env: Option<HashMap<String, String>>,
|
|
|
|
|
|
pub user: Option<String>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-08-28 19:24:38 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum WebSearchAction {
|
|
|
|
|
|
Search {
|
|
|
|
|
|
query: String,
|
|
|
|
|
|
},
|
|
|
|
|
|
#[serde(other)]
|
|
|
|
|
|
Other,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-05-10 21:43:27 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum ReasoningItemReasoningSummary {
|
|
|
|
|
|
SummaryText { text: String },
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
2025-08-05 01:56:13 -07:00
|
|
|
|
#[serde(tag = "type", rename_all = "snake_case")]
|
|
|
|
|
|
pub enum ReasoningItemContent {
|
|
|
|
|
|
ReasoningText { text: String },
|
2025-08-13 18:39:58 -07:00
|
|
|
|
Text { text: String },
|
2025-08-05 01:56:13 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
impl From<Vec<InputItem>> for ResponseInputItem {
|
|
|
|
|
|
fn from(items: Vec<InputItem>) -> Self {
|
|
|
|
|
|
Self::Message {
|
|
|
|
|
|
role: "user".to_string(),
|
|
|
|
|
|
content: items
|
|
|
|
|
|
.into_iter()
|
|
|
|
|
|
.filter_map(|c| match c {
|
|
|
|
|
|
InputItem::Text { text } => Some(ContentItem::InputText { text }),
|
|
|
|
|
|
InputItem::Image { image_url } => Some(ContentItem::InputImage { image_url }),
|
|
|
|
|
|
InputItem::LocalImage { path } => match std::fs::read(&path) {
|
|
|
|
|
|
Ok(bytes) => {
|
|
|
|
|
|
let mime = mime_guess::from_path(&path)
|
|
|
|
|
|
.first()
|
|
|
|
|
|
.map(|m| m.essence_str().to_owned())
|
2025-09-11 16:10:24 -07:00
|
|
|
|
.unwrap_or_else(|| "image".to_string());
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
let encoded = base64::engine::general_purpose::STANDARD.encode(bytes);
|
|
|
|
|
|
Some(ContentItem::InputImage {
|
2025-07-10 20:08:16 +02:00
|
|
|
|
image_url: format!("data:{mime};base64,{encoded}"),
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
Err(err) => {
|
|
|
|
|
|
tracing::warn!(
|
|
|
|
|
|
"Skipping image {} – could not read file: {}",
|
|
|
|
|
|
path.display(),
|
|
|
|
|
|
err
|
|
|
|
|
|
);
|
|
|
|
|
|
None
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
.collect::<Vec<ContentItem>>(),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-04 10:57:12 -07:00
|
|
|
|
/// If the `name` of a `ResponseItem::FunctionCall` is either `container.exec`
|
|
|
|
|
|
/// or shell`, the `arguments` field should deserialize to this struct.
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Deserialize, Debug, Clone, PartialEq, TS)]
|
2025-05-04 10:57:12 -07:00
|
|
|
|
pub struct ShellToolCallParams {
|
|
|
|
|
|
pub command: Vec<String>,
|
|
|
|
|
|
pub workdir: Option<String>,
|
|
|
|
|
|
|
2025-08-21 19:58:07 -07:00
|
|
|
|
/// This is the maximum time in milliseconds that the command is allowed to run.
|
|
|
|
|
|
#[serde(alias = "timeout")]
|
2025-05-04 10:57:12 -07:00
|
|
|
|
pub timeout_ms: Option<u64>,
|
2025-08-05 20:44:20 -07:00
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub with_escalated_permissions: Option<bool>,
|
|
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
|
|
pub justification: Option<String>,
|
2025-05-04 10:57:12 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 14:54:47 -07:00
|
|
|
|
#[derive(Debug, Clone, PartialEq, TS)]
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
pub struct FunctionCallOutputPayload {
|
|
|
|
|
|
pub content: String,
|
|
|
|
|
|
pub success: Option<bool>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// The Responses API expects two *different* shapes depending on success vs failure:
|
|
|
|
|
|
// • success → output is a plain string (no nested object)
|
|
|
|
|
|
// • failure → output is an object { content, success:false }
|
|
|
|
|
|
// The upstream TypeScript CLI implements this by special‑casing the serialize path.
|
|
|
|
|
|
// We replicate that behavior with a manual Serialize impl.
|
|
|
|
|
|
|
|
|
|
|
|
impl Serialize for FunctionCallOutputPayload {
|
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
|
where
|
|
|
|
|
|
S: Serializer,
|
|
|
|
|
|
{
|
|
|
|
|
|
// The upstream TypeScript CLI always serializes `output` as a *plain string* regardless
|
|
|
|
|
|
// of whether the function call succeeded or failed. The boolean is purely informational
|
|
|
|
|
|
// for local bookkeeping and is NOT sent to the OpenAI endpoint. Sending the nested object
|
|
|
|
|
|
// form `{ content, success:false }` triggers the 400 we are still seeing. Mirror the JS CLI
|
|
|
|
|
|
// exactly: always emit a bare string.
|
|
|
|
|
|
|
|
|
|
|
|
serializer.serialize_str(&self.content)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-23 10:37:45 -07:00
|
|
|
|
impl<'de> Deserialize<'de> for FunctionCallOutputPayload {
|
|
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
|
|
where
|
|
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
|
|
{
|
|
|
|
|
|
let s = String::deserialize(deserializer)?;
|
|
|
|
|
|
Ok(FunctionCallOutputPayload {
|
|
|
|
|
|
content: s,
|
|
|
|
|
|
success: None,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
// Implement Display so callers can treat the payload like a plain string when logging or doing
|
|
|
|
|
|
// trivial substring checks in tests (existing tests call `.contains()` on the output). Display
|
|
|
|
|
|
// returns the raw `content` field.
|
|
|
|
|
|
|
|
|
|
|
|
impl std::fmt::Display for FunctionCallOutputPayload {
|
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
|
f.write_str(&self.content)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl std::ops::Deref for FunctionCallOutputPayload {
|
|
|
|
|
|
type Target = str;
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
|
|
&self.content
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 22:34:50 -07:00
|
|
|
|
// (Moved event mapping logic into codex-core to avoid coupling protocol to UI-facing events.)
|
|
|
|
|
|
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
#[cfg(test)]
|
|
|
|
|
|
mod tests {
|
|
|
|
|
|
use super::*;
|
2025-09-23 13:31:36 -07:00
|
|
|
|
use anyhow::Result;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
#[test]
|
2025-09-23 13:31:36 -07:00
|
|
|
|
fn serializes_success_as_plain_string() -> Result<()> {
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
let item = ResponseInputItem::FunctionCallOutput {
|
|
|
|
|
|
call_id: "call1".into(),
|
|
|
|
|
|
output: FunctionCallOutputPayload {
|
|
|
|
|
|
content: "ok".into(),
|
|
|
|
|
|
success: None,
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-23 13:31:36 -07:00
|
|
|
|
let json = serde_json::to_string(&item)?;
|
|
|
|
|
|
let v: serde_json::Value = serde_json::from_str(&json)?;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
// Success case -> output should be a plain string
|
|
|
|
|
|
assert_eq!(v.get("output").unwrap().as_str().unwrap(), "ok");
|
2025-09-23 13:31:36 -07:00
|
|
|
|
Ok(())
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
2025-09-23 13:31:36 -07:00
|
|
|
|
fn serializes_failure_as_string() -> Result<()> {
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
let item = ResponseInputItem::FunctionCallOutput {
|
|
|
|
|
|
call_id: "call1".into(),
|
|
|
|
|
|
output: FunctionCallOutputPayload {
|
|
|
|
|
|
content: "bad".into(),
|
|
|
|
|
|
success: Some(false),
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-23 13:31:36 -07:00
|
|
|
|
let json = serde_json::to_string(&item)?;
|
|
|
|
|
|
let v: serde_json::Value = serde_json::from_str(&json)?;
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
|
|
|
|
|
|
assert_eq!(v.get("output").unwrap().as_str().unwrap(), "bad");
|
2025-09-23 13:31:36 -07:00
|
|
|
|
Ok(())
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|
2025-05-04 10:57:12 -07:00
|
|
|
|
|
|
|
|
|
|
#[test]
|
2025-09-23 13:31:36 -07:00
|
|
|
|
fn deserialize_shell_tool_call_params() -> Result<()> {
|
2025-05-04 10:57:12 -07:00
|
|
|
|
let json = r#"{
|
|
|
|
|
|
"command": ["ls", "-l"],
|
|
|
|
|
|
"workdir": "/tmp",
|
|
|
|
|
|
"timeout": 1000
|
|
|
|
|
|
}"#;
|
|
|
|
|
|
|
2025-09-23 13:31:36 -07:00
|
|
|
|
let params: ShellToolCallParams = serde_json::from_str(json)?;
|
2025-05-04 10:57:12 -07:00
|
|
|
|
assert_eq!(
|
|
|
|
|
|
ShellToolCallParams {
|
|
|
|
|
|
command: vec!["ls".to_string(), "-l".to_string()],
|
|
|
|
|
|
workdir: Some("/tmp".to_string()),
|
|
|
|
|
|
timeout_ms: Some(1000),
|
2025-08-05 20:44:20 -07:00
|
|
|
|
with_escalated_permissions: None,
|
|
|
|
|
|
justification: None,
|
2025-05-04 10:57:12 -07:00
|
|
|
|
},
|
|
|
|
|
|
params
|
|
|
|
|
|
);
|
2025-09-23 13:31:36 -07:00
|
|
|
|
Ok(())
|
2025-05-04 10:57:12 -07:00
|
|
|
|
}
|
feat: initial import of Rust implementation of Codex CLI in codex-rs/ (#629)
As stated in `codex-rs/README.md`:
Today, Codex CLI is written in TypeScript and requires Node.js 22+ to
run it. For a number of users, this runtime requirement inhibits
adoption: they would be better served by a standalone executable. As
maintainers, we want Codex to run efficiently in a wide range of
environments with minimal overhead. We also want to take advantage of
operating system-specific APIs to provide better sandboxing, where
possible.
To that end, we are moving forward with a Rust implementation of Codex
CLI contained in this folder, which has the following benefits:
- The CLI compiles to small, standalone, platform-specific binaries.
- Can make direct, native calls to
[seccomp](https://man7.org/linux/man-pages/man2/seccomp.2.html) and
[landlock](https://man7.org/linux/man-pages/man7/landlock.7.html) in
order to support sandboxing on Linux.
- No runtime garbage collection, resulting in lower memory consumption
and better, more predictable performance.
Currently, the Rust implementation is materially behind the TypeScript
implementation in functionality, so continue to use the TypeScript
implmentation for the time being. We will publish native executables via
GitHub Releases as soon as we feel the Rust version is usable.
2025-04-24 13:31:40 -07:00
|
|
|
|
}
|