Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new,*meriyah.umd.min.js
skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new
check-hidden = true
ignore-regex = ^\s*"image/\S+": ".*|\b(afterAll)\b
ignore-words-list = ratatui,ser,iTerm,iterm2,iterm,te,TE,PASE,SEH
2 changes: 1 addition & 1 deletion .github/actions/prepare-bazel-ci/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ inputs:
description: Logical namespace used to keep concurrent Bazel jobs from reserving the same repository cache key.
required: true
install-test-prereqs:
description: Install Node.js and DotSlash for Bazel-backed test jobs.
description: Install DotSlash for Bazel-backed test jobs.
required: false
default: "false"
outputs:
Expand Down
8 changes: 1 addition & 7 deletions .github/actions/setup-bazel-ci/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ inputs:
description: Target triple used for cache namespacing.
required: true
install-test-prereqs:
description: Install Node.js and DotSlash for Bazel-backed test jobs.
description: Install DotSlash for Bazel-backed test jobs.
required: false
default: "false"
outputs:
Expand All @@ -16,12 +16,6 @@ outputs:
runs:
using: composite
steps:
- name: Set up Node.js for js_repl tests
if: inputs.install-test-prereqs == 'true'
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: codex-rs/node-version.txt

# Some integration tests rely on DotSlash being installed.
# See https://github.com/openai/codex/pull/7617.
- name: Install DotSlash
Expand Down
17 changes: 1 addition & 16 deletions .github/scripts/run-bazel-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ set -euo pipefail

print_failed_bazel_test_logs=0
print_failed_bazel_action_summary=0
use_node_test_env=0
remote_download_toplevel=0
windows_msvc_host_platform=0

Expand All @@ -18,10 +17,6 @@ while [[ $# -gt 0 ]]; do
print_failed_bazel_action_summary=1
shift
;;
--use-node-test-env)
use_node_test_env=1
shift
;;
--remote-download-toplevel)
remote_download_toplevel=1
shift
Expand All @@ -42,7 +37,7 @@ while [[ $# -gt 0 ]]; do
done

if [[ $# -eq 0 ]]; then
echo "Usage: $0 [--print-failed-test-logs] [--print-failed-action-summary] [--use-node-test-env] [--remote-download-toplevel] [--windows-msvc-host-platform] -- <bazel args> -- <targets>" >&2
echo "Usage: $0 [--print-failed-test-logs] [--print-failed-action-summary] [--remote-download-toplevel] [--windows-msvc-host-platform] -- <bazel args> -- <targets>" >&2
exit 1
fi

Expand Down Expand Up @@ -249,16 +244,6 @@ if [[ ${#bazel_args[@]} -eq 0 || ${#bazel_targets[@]} -eq 0 ]]; then
exit 1
fi

if [[ $use_node_test_env -eq 1 ]]; then
# Bazel test sandboxes on macOS may resolve an older Homebrew `node`
# before the `actions/setup-node` runtime on PATH.
node_bin="$(which node)"
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
node_bin="$(cygpath -w "${node_bin}")"
fi
bazel_args+=("--test_env=CODEX_JS_REPL_NODE_PATH=${node_bin}")
fi

post_config_bazel_args=()
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_msvc_host_platform -eq 1 ]]; then
has_host_platform_override=0
Expand Down
18 changes: 1 addition & 17 deletions .github/workflows/Dockerfile.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,9 @@ FROM ubuntu:24.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
curl git python3 ca-certificates xz-utils && \
curl git python3 ca-certificates && \
rm -rf /var/lib/apt/lists/*

COPY codex-rs/node-version.txt /tmp/node-version.txt

RUN set -eux; \
node_arch="$(dpkg --print-architecture)"; \
case "${node_arch}" in \
amd64) node_dist_arch="x64" ;; \
arm64) node_dist_arch="arm64" ;; \
*) echo "unsupported architecture: ${node_arch}"; exit 1 ;; \
esac; \
node_version="$(tr -d '[:space:]' </tmp/node-version.txt)"; \
curl -fsSLO "https://nodejs.org/dist/v${node_version}/node-v${node_version}-linux-${node_dist_arch}.tar.xz"; \
tar -xJf "node-v${node_version}-linux-${node_dist_arch}.tar.xz" -C /usr/local --strip-components=1; \
rm "node-v${node_version}-linux-${node_dist_arch}.tar.xz" /tmp/node-version.txt; \
node --version; \
npm --version

# Install dotslash.
RUN curl -LSfs "https://github.com/facebook/dotslash/releases/download/v0.5.8/dotslash-ubuntu-22.04.$(uname -m).tar.gz" | tar fxz - -C /usr/local/bin

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ jobs:

bazel_wrapper_args=(
--print-failed-test-logs
--use-node-test-env
)
bazel_test_args=(
test
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/rust-ci-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,6 @@ jobs:

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Node.js for js_repl tests
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: codex-rs/node-version.txt
- name: Install Linux build dependencies
if: ${{ runner.os == 'Linux' }}
shell: bash
Expand Down
3 changes: 0 additions & 3 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@ Copyright 2025 OpenAI
This project includes code derived from [Ratatui](https://github.com/ratatui/ratatui), licensed under the MIT license.
Copyright (c) 2016-2022 Florian Dehau
Copyright (c) 2023-2025 The Ratatui Developers

This project includes Meriyah parser assets from [meriyah](https://github.com/meriyah/meriyah), licensed under the ISC license.
Copyright (c) 2019 and later, KFlash and others.
1 change: 0 additions & 1 deletion codex-rs/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
exports_files([
"clippy.toml",
"node-version.txt",
])

filegroup(
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ If the session approval policy uses `Granular` with `request_permissions: false`

`dynamicTools` on `thread/start` and the corresponding `item/tool/call` request/response flow are experimental APIs. To enable them, set `initialize.params.capabilities.experimentalApi = true`.

Each dynamic tool may set `deferLoading`. When omitted, it defaults to `false`. Set it to `true` to keep the tool registered and callable by runtime features such as `js_repl`, while excluding it from the model-facing tool list sent on ordinary turns. When `tool_search` is available, deferred dynamic tools are searchable and can be exposed by a matching search result.
Each dynamic tool may set `deferLoading`. When omitted, it defaults to `false`. Set it to `true` to keep the tool registered and callable by runtime features such as `code_mode`, while excluding it from the model-facing tool list sent on ordinary turns. When `tool_search` is available, deferred dynamic tools are searchable and can be exposed by a matching search result.

When a dynamic tool is invoked during a turn, the server sends an `item/tool/call` JSON-RPC request to the client:

Expand Down
6 changes: 4 additions & 2 deletions codex-rs/config/src/config_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,12 @@ pub struct ConfigToml {
/// Default: `300000` (5 minutes).
pub background_terminal_max_timeout: Option<u64>,

/// Optional absolute path to the Node runtime used by `js_repl`.
/// Deprecated: ignored.
#[schemars(skip)]
pub js_repl_node_path: Option<AbsolutePathBuf>,

/// Ordered list of directories to search for Node modules in `js_repl`.
/// Deprecated: ignored.
#[schemars(skip)]
pub js_repl_node_module_dirs: Option<Vec<AbsolutePathBuf>>,

/// Optional absolute path to patched zsh used by zsh-exec-bridge-backed shell execution.
Expand Down
5 changes: 4 additions & 1 deletion codex-rs/config/src/profile_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ pub struct ConfigProfile {
pub chatgpt_base_url: Option<String>,
/// Optional path to a file containing model instructions.
pub model_instructions_file: Option<AbsolutePathBuf>,
/// Deprecated: ignored.
#[schemars(skip)]
pub js_repl_node_path: Option<AbsolutePathBuf>,
/// Ordered list of directories to search for Node modules in `js_repl`.
/// Deprecated: ignored.
#[schemars(skip)]
pub js_repl_node_module_dirs: Option<Vec<AbsolutePathBuf>>,
/// Optional absolute path to patched zsh used by zsh-exec-bridge-backed shell execution.
pub zsh_path: Option<AbsolutePathBuf>,
Expand Down
4 changes: 1 addition & 3 deletions codex-rs/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ codex_rust_crate(
"Cargo.toml",
],
allow_empty = True,
) + [
"//codex-rs:node-version.txt",
],
),
rustc_env = {
# Keep manifest-root path lookups inside the Bazel execroot for code
# that relies on env!("CARGO_MANIFEST_DIR").
Expand Down
25 changes: 0 additions & 25 deletions codex-rs/core/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -583,16 +583,6 @@
"include_permissions_instructions": {
"type": "boolean"
},
"js_repl_node_module_dirs": {
"description": "Ordered list of directories to search for Node modules in `js_repl`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
},
"js_repl_node_path": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"model": {
"type": "string"
},
Expand Down Expand Up @@ -2849,21 +2839,6 @@
"description": "System instructions.",
"type": "string"
},
"js_repl_node_module_dirs": {
"description": "Ordered list of directories to search for Node modules in `js_repl`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
},
"js_repl_node_path": {
"allOf": [
{
"$ref": "#/definitions/AbsolutePathBuf"
}
],
"description": "Optional absolute path to the Node runtime used by `js_repl`."
},
"log_dir": {
"allOf": [
{
Expand Down
1 change: 0 additions & 1 deletion codex-rs/core/src/agent/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ mod reload {
model_provider: preserve_current_provider.then(|| config.model_provider_id.clone()),
codex_linux_sandbox_exe: config.codex_linux_sandbox_exe.clone(),
main_execve_wrapper_exe: config.main_execve_wrapper_exe.clone(),
js_repl_node_path: config.js_repl_node_path.clone(),
..Default::default()
}
}
Expand Down
42 changes: 0 additions & 42 deletions codex-rs/core/src/agents_md.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,41 +42,6 @@ pub const LOCAL_AGENTS_MD_FILENAME: &str = "AGENTS.override.md";
/// be concatenated with the following separator.
const AGENTS_MD_SEPARATOR: &str = "\n\n--- project-doc ---\n\n";

fn render_js_repl_instructions(config: &Config) -> Option<String> {
if !config.features.enabled(Feature::JsRepl) {
return None;
}

let mut section = String::from("## JavaScript REPL (Node)\n");
section.push_str(
"- Use `js_repl` for Node-backed JavaScript with top-level await in a persistent kernel.\n",
);
section.push_str("- `js_repl` is a freeform/custom tool. Direct `js_repl` calls must send raw JavaScript tool input (optionally with first-line `// codex-js-repl: timeout_ms=15000`). Do not wrap code in JSON (for example `{\"code\":\"...\"}`), quotes, or markdown code fences.\n");
section.push_str(
"- Helpers: `codex.cwd`, `codex.homeDir`, `codex.tmpDir`, `codex.tool(name, args?)`, and `codex.emitImage(imageLike)`.\n",
);
section.push_str("- `codex.tool` executes a normal tool call and resolves to the raw tool output object. Use it for shell and non-shell tools alike. Nested tool outputs stay inside JavaScript unless you emit them explicitly.\n");
section.push_str("- `codex.emitImage(...)` adds one image to the outer `js_repl` function output each time you call it, so you can call it multiple times to emit multiple images. It accepts a data URL, a single `input_image` item, an object like `{ bytes, mimeType }` containing encoded PNG/JPEG/WebP/GIF bytes, or a raw tool response object with exactly one image and no text. It rejects mixed text-and-image content.\n");
section.push_str("- `codex.tool(...)` and `codex.emitImage(...)` keep stable helper identities across cells. Saved references and persisted objects can reuse them in later cells, but async callbacks that fire after a cell finishes still fail because no exec is active.\n");
section.push_str("- Request full-resolution image processing with `detail: \"original\"` only when the `view_image` tool schema includes a `detail` argument. The same availability applies to `codex.emitImage(...)`: if `view_image.detail` is present, you may also pass `detail: \"original\"` there. Use this when high-fidelity image perception or precise localization is needed, especially for CUA agents.\n");
section.push_str("- Raw MCP image blocks can request the same behavior by returning `_meta: { \"codex/imageDetail\": \"original\" }` on the image content item.\n");
section.push_str("- Example of sharing an in-memory Playwright screenshot: `await codex.emitImage({ bytes: await page.screenshot({ type: \"jpeg\", quality: 85 }), mimeType: \"image/jpeg\", detail: \"original\" })`.\n");
section.push_str("- Example of sharing a local image tool result: `await codex.emitImage(codex.tool(\"view_image\", { path: \"/absolute/path\", detail: \"original\" }))`.\n");
section.push_str("- When encoding an image to send with `codex.emitImage(...)` or `view_image`, prefer JPEG at about 85 quality when lossy compression is acceptable; use PNG when transparency or lossless detail matters. Smaller uploads are faster and less likely to hit size limits.\n");
section.push_str("- Top-level bindings persist across cells. If a cell throws, prior bindings remain available and bindings that finished initializing before the throw often remain usable in later cells. For code you plan to reuse across cells, prefer declaring or assigning it in direct top-level statements before operations that might throw. If you hit `SyntaxError: Identifier 'x' has already been declared`, first reuse the existing binding, reassign a previously declared `let`, or pick a new descriptive name. Use `{ ... }` only for a short temporary block when you specifically need local scratch names; do not wrap an entire cell in block scope if you want those names reusable later. Reset the kernel with `js_repl_reset` only when you need a clean state.\n");
section.push_str("- Top-level static import declarations (for example `import x from \"./file.js\"`) are currently unsupported in `js_repl`; use dynamic imports with `await import(\"pkg\")`, `await import(\"./file.js\")`, or `await import(\"/abs/path/file.mjs\")` instead. Imported local files must be ESM `.js`/`.mjs` files and run in the same REPL VM context. Bare package imports always resolve from REPL-global search roots (`CODEX_JS_REPL_NODE_MODULE_DIRS`, then cwd), not relative to the imported file location. Local files may statically import only other local relative/absolute/`file://` `.js`/`.mjs` files; package and builtin imports from local files must stay dynamic. `import.meta.resolve()` returns importable strings such as `file://...`, bare package names, and `node:...` specifiers. Local file modules reload between execs, while top-level bindings persist until `js_repl_reset`.\n");

if config.features.enabled(Feature::JsReplToolsOnly) {
section.push_str("- Do not call tools directly; use `js_repl` + `codex.tool(...)` for all tool calls, including shell commands.\n");
section
.push_str("- MCP tools (if any) can also be called by name via `codex.tool(...)`.\n");
}

section.push_str("- Avoid direct access to `process.stdout` / `process.stderr` / `process.stdin`; it can corrupt the JSON line protocol. Use `console.log`, `codex.tool(...)`, and `codex.emitImage(...)`.");

Some(section)
}

/// Resolves AGENTS.md files into model-visible user instructions and source
/// paths.
pub struct AgentsMdManager<'a> {
Expand Down Expand Up @@ -147,13 +112,6 @@ impl<'a> AgentsMdManager<'a> {
}
};

if let Some(js_repl_section) = render_js_repl_instructions(self.config) {
if !output.is_empty() {
output.push_str("\n\n");
}
output.push_str(&js_repl_section);
}

if self.config.features.enabled(Feature::ChildAgentsMd) {
if !output.is_empty() {
output.push_str("\n\n");
Expand Down
Loading
Loading