mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
672cc1f669
## 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`](https://github.com/openai/codex/blob/c538758095337d4fe0a52a172363ccede4066bda/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`](https://github.com/openai/codex/blob/c538758095337d4fe0a52a172363ccede4066bda/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
64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use std::future::Future;
|
|
|
|
use codex_protocol::items::TurnItem;
|
|
use codex_tool_api::ToolBundle;
|
|
|
|
use crate::ExtensionData;
|
|
|
|
mod prompt;
|
|
|
|
pub use prompt::PromptFragment;
|
|
pub use prompt::PromptSlot;
|
|
|
|
/// Contributor that receives host-owned thread-start input before later
|
|
/// contributors read from extension stores.
|
|
pub trait ThreadStartContributor<C>: Send + Sync {
|
|
fn contribute(&self, input: &C, session_store: &ExtensionData, thread_store: &ExtensionData);
|
|
}
|
|
|
|
/// Extension contribution that adds prompt fragments during prompt assembly.
|
|
pub trait ContextContributor: Send + Sync {
|
|
fn contribute(
|
|
&self,
|
|
session_store: &ExtensionData,
|
|
thread_store: &ExtensionData,
|
|
) -> Vec<PromptFragment>;
|
|
}
|
|
|
|
/// Extension contribution that exposes native tools owned by a feature.
|
|
pub trait ToolContributor: Send + Sync {
|
|
/// Returns the native tools visible for the supplied extension stores.
|
|
fn tools(&self, session_store: &ExtensionData, thread_store: &ExtensionData)
|
|
-> Vec<ToolBundle>;
|
|
}
|
|
|
|
/// Future returned by one ordered turn-item contribution.
|
|
pub type TurnItemContributionFuture<'a> =
|
|
std::pin::Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>>;
|
|
|
|
/// Ordered post-processing contribution for one parsed turn item.
|
|
///
|
|
/// Implementations may mutate the item before it is emitted and may use the
|
|
/// explicitly exposed thread- and turn-lifetime stores when they need durable
|
|
/// extension-private state.
|
|
pub trait TurnItemContributor: Send + Sync {
|
|
fn contribute<'a>(
|
|
&'a self,
|
|
thread_store: &'a ExtensionData,
|
|
turn_store: &'a ExtensionData,
|
|
item: &'a mut TurnItem,
|
|
) -> TurnItemContributionFuture<'a>;
|
|
}
|
|
|
|
// TODO: WIP (do not consider)
|
|
/// Extension contribution that can claim approval requests for a runtime context.
|
|
/// (ideally we can replace it by a session lifecycle thing or a request contributor?)
|
|
pub trait ApprovalInterceptorContributor: Send + Sync {
|
|
/// Returns whether this contributor should intercept approvals in `context`.
|
|
fn intercepts_approvals(
|
|
&self,
|
|
thread_store: &ExtensionData,
|
|
turn_store: &ExtensionData,
|
|
) -> bool;
|
|
}
|