## Why This is the next narrow step toward moving concrete tool families out of core. After #22138 introduced `codex-tool-api`, we still needed a real end-to-end seam that lets an extension own an executable tool definition once and have core install it without the temporary `extension-api` wrapper or a dependency on `codex-tools`. `codex-tool-api` is the small extension-facing execution contract, while `codex-tools` still has a different job: host-side shared tool metadata and planning logic that is not “run this contributed tool”, like spec shaping, namespaces, discovery, code-mode augmentation, and MCP/dynamic-to-Responses API conversion ## What changed - Moved the shared leaf tool-spec and JSON Schema types into `codex-tool-api`, so the executable contract now lives with [`ToolBundle`](c538758095/codex-rs/tool-api/src/bundle.rs (L19-L70)). - Replaced the temporary extension-side tool wrapper with direct `ToolBundle` use in `codex-extension-api`. - Taught core to collect contributed bundles, include them in spec planning, register them through [`ToolRegistryBuilder::register_tool_bundle`](c538758095/codex-rs/core/src/tools/registry.rs (L653-L667)), and dispatch them through the existing router/runtime path. - Added focused coverage for contributed tools becoming model-visible and dispatchable, plus spec-planning coverage for contributed function and freeform tools. ## Verification - Added `extension_tool_bundles_are_model_visible_and_dispatchable` in `core/src/tools/router_tests.rs`. - Added spec-plan coverage in `core/src/tools/spec_plan_tests.rs` for contributed extension bundles. ## Related - Follow-up to #22138
3.0 KiB
codex-tools
codex-tools is the host-side support crate for building, adapting, and
planning tool sets outside codex-core.
It is deliberately not the API that external tool owners should depend on.
Crates that contribute ordinary function tools through extensions should use
codex-tool-api, which owns only that small executable-tool seam.
Today this crate owns the host-facing tool models and helpers that no longer
need to live in core/src/tools/spec.rs or core/src/client_common.rs:
- aggregate host models such as
ToolSpec,ConfiguredToolSpec,LoadableToolSpec,ResponsesApiNamespace, andResponsesApiNamespaceTool - host config and discovery models used while assembling tool sets, including
ToolsConfig, discoverable-tool models, and request-plugin-install helpers - host adapters such as schema sanitization, MCP/dynamic conversion, code-mode augmentation, and image-detail normalization
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 host-side tool machinery that is shared by multiple consumers, for example:
- host-visible aggregate tool models
- tool-set planning and discovery helpers
- MCP and dynamic-tool adaptation into Responses API shapes
- code-mode compatibility shims that do not depend on
codex-core - other narrowly scoped host utilities that multiple crates need
The corresponding non-goals are just as important:
- do not become the extension-facing authoring API for executable tools
- do not move
codex-coreorchestration 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:
- Keep ordinary contributed function-tool authoring in
codex-tool-api. - Move host-side planning/adaptation helpers here when they no longer need to
stay coupled to
codex-core. - Leave compatibility-sensitive adapters in
codex-corewhile downstream call sites are updated. - Only extract higher-level host infrastructure after the crate boundaries are clear and independently testable.
Crate conventions
This crate should start with stricter structure than core/src/tools so it
stays easy to grow:
src/lib.rsshould remain exports-only.- Business logic should live in named module files such as
foo.rs. - Unit tests for
foo.rsshould live in a siblingfoo_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.