Files
codex/codex-rs/tools
T
Michael Bolin 9f71d57a65 Extract code-mode nested tool collection into codex-tools (#16509)
## Why
This is another small step in the `codex-core` -> `codex-tools`
migration described in `AGENTS.md`.

`core/src/tools/spec.rs` and `core/src/tools/code_mode/mod.rs` were both
hand-rolling the same pure transformation: convert visible `ToolSpec`s
into code-mode nested tool definitions, then sort and deduplicate by
tool name. That logic does not depend on core runtime state or handlers,
so keeping it in `codex-core` makes `spec.rs` harder to peel out later
than it needs to be.

## What Changed
- Add `collect_code_mode_tool_definitions()` to
`codex-rs/tools/src/code_mode.rs`.
- Reuse that helper from `codex-rs/core/src/tools/spec.rs` when
assembling the `exec` tool description.
- Reuse the same helper from `codex-rs/core/src/tools/code_mode/mod.rs`
when exposing nested tool metadata to the code-mode runtime.

This is intended to be a straight refactor with no behavior change and
no new test surface.

## Verification
- `cargo test -p codex-tools`
- `cargo test -p codex-core tools::spec::tests`
- `cargo test -p codex-core code_mode_only_`
9f71d57a65 ยท 2026-04-01 22:17:55 -07:00
History
..

codex-tools

codex-tools is intended to become the home for tool-related code that is shared across multiple crates and does not need to stay coupled to codex-core.

Today this crate is intentionally small. It currently owns the shared tool schema and Responses API tool primitives that no longer need to live in core/src/tools/spec.rs or core/src/client_common.rs:

  • JsonSchema
  • AdditionalProperties
  • ToolDefinition
  • ToolSpec
  • ConfiguredToolSpec
  • ResponsesApiTool
  • FreeformTool
  • FreeformToolFormat
  • ToolSearchOutputTool
  • ResponsesApiWebSearchFilters
  • ResponsesApiWebSearchUserLocation
  • ResponsesApiNamespace
  • ResponsesApiNamespaceTool
  • code-mode ToolSpec adapters and exec / wait spec builders
  • JS REPL spec builders
  • MCP resource, list_dir, and test_sync_tool spec builders
  • local host tool spec builders for shell/exec/request-permissions/view-image
  • collaboration and agent-job ToolSpec builders for spawn/send/wait/close, request_user_input, and CSV fanout/reporting
  • discoverable-tool models, client filtering, and ToolSpec builders for tool_search and tool_suggest
  • parse_tool_input_schema()
  • parse_dynamic_tool()
  • parse_mcp_tool()
  • create_tools_json_for_responses_api()
  • mcp_call_tool_result_output_schema()
  • tool_definition_to_responses_api_tool()
  • dynamic_tool_to_responses_api_tool()
  • mcp_tool_to_responses_api_tool()
  • mcp_tool_to_deferred_responses_api_tool()
  • augment_tool_spec_for_code_mode()
  • tool_spec_to_code_mode_tool_definition()

That extraction is the first step in a longer migration. The goal is not to move all of core/src/tools into this crate in one shot. Instead, the plan is to peel off reusable pieces in reviewable increments while keeping compatibility-sensitive orchestration in codex-core until the surrounding boundaries are ready.

Vision

Over time, this crate should hold tool-facing primitives that are shared by multiple consumers, for example:

  • schema and spec data models
  • tool input/output parsing helpers
  • tool metadata and compatibility shims that do not depend on codex-core
  • other narrowly scoped utility code that multiple crates need

The corresponding non-goals are just as important:

  • do not move codex-core orchestration here prematurely
  • do not pull Session / TurnContext / approval flow / runtime execution logic into this crate unless those dependencies have first been split into stable shared interfaces
  • do not turn this crate into a grab-bag for unrelated helper code

Migration approach

The expected migration shape is:

  1. Move low-coupling tool primitives here.
  2. Switch non-core consumers to depend on codex-tools directly.
  3. Leave compatibility-sensitive adapters in codex-core while downstream call sites are updated.
  4. Only extract higher-level tool infrastructure after the crate boundaries are clear and independently testable.

That means it is normal for codex-core to temporarily re-export types or helpers from codex-tools during the transition.

Crate conventions

This crate should start with stricter structure than core/src/tools so it stays easy to grow:

  • src/lib.rs should remain exports-only.
  • Business logic should live in named module files such as foo.rs.
  • Unit tests for foo.rs should live in a sibling foo_tests.rs.
  • The implementation file should wire tests with:
#[cfg(test)]
#[path = "foo_tests.rs"]
mod tests;

If this crate starts accumulating code that needs runtime state from codex-core, that is a sign to revisit the extraction boundary before adding more here.