Files
codex/codex-rs/tool-api
jif-oai 672cc1f669 feat: wire extension tool bundles into core (#22147)
## 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
2026-05-11 16:42:29 +02:00
..

codex-tool-api

codex-tool-api is the minimal extension-facing contract for contributed function tools that can be injected into Codex without making codex-core depend on the tool owner's crate.

Crates that define contributed tools should depend on this crate. It owns:

  • the executable bundle contract: ToolBundle, ToolExecutor, ToolCall, and ToolError
  • the one model-visible spec an extension may contribute directly: FunctionToolSpec

The contract is intentionally narrow: contributed tools receive a call id plus raw JSON arguments and return a JSON value. If a feature needs richer host integration, its extension is expected to do that wiring before exposing the tool rather than widening this crate around the hardest native tools.

The intended dependency direction is:

tool-owning extension crate --> codex-tool-api <-- codex-core

codex-tools has a different job. It remains the host-side owner of Responses API tool models, schema parsing, namespaces, discovery, MCP/dynamic conversion, code-mode shaping, and other aggregate host concerns. A crate that only wants to contribute one ordinary function tool through an extension should not need to depend on codex-tools.