[codex] Remove async_trait from ToolExecutor (#27304)

## Why

We're now [discouraging use of
`async_trait`](https://github.com/openai/codex/pull/20242).

Removing use of `async_trait` from `ToolExecutor` yields a `codex_core`
debug test build speedup of ~78% (from 227.5s to 50.3s) on my machine.

Stacked on #27299, this PR applies the trait change after the handler
bodies have been outlined.

## What

Changed `ToolExecutor::handle` to return an explicit boxed
`ToolExecutorFuture` instead of using `async_trait`.

Updated ToolExecutor implementors to return `Box::pin(...)`, reexported
the future alias through `codex-tools` and `codex-extension-api`, and
removed `codex-tools` direct `async-trait` dependency.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-10 10:26:53 -07:00
committed by GitHub
Unverified
parent d3abd8774e
commit 2704ecea9a
56 changed files with 161 additions and 357 deletions
-5
View File
@@ -3047,7 +3047,6 @@ name = "codex-goal-extension"
version = "0.0.0"
dependencies = [
"anyhow",
"async-trait",
"chrono",
"codex-analytics",
"codex-core",
@@ -3101,7 +3100,6 @@ dependencies = [
name = "codex-image-generation-extension"
version = "0.0.0"
dependencies = [
"async-trait",
"codex-api",
"codex-core",
"codex-extension-api",
@@ -3301,7 +3299,6 @@ dependencies = [
name = "codex-memories-extension"
version = "0.0.0"
dependencies = [
"async-trait",
"codex-core",
"codex-extension-api",
"codex-features",
@@ -3916,7 +3913,6 @@ dependencies = [
name = "codex-tools"
version = "0.0.0"
dependencies = [
"async-trait",
"codex-app-server-protocol",
"codex-code-mode",
"codex-features",
@@ -4297,7 +4293,6 @@ dependencies = [
name = "codex-web-search-extension"
version = "0.0.0"
dependencies = [
"async-trait",
"codex-api",
"codex-core",
"codex-extension-api",
@@ -91,7 +91,6 @@ impl CodeModeExecuteHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for CodeModeExecuteHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(PUBLIC_TOOL_NAME)
@@ -101,11 +100,8 @@ impl ToolExecutor<ToolInvocation> for CodeModeExecuteHandler {
self.spec.clone()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -44,7 +44,6 @@ where
})
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for CodeModeWaitHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(WAIT_TOOL_NAME)
@@ -54,11 +53,8 @@ impl ToolExecutor<ToolInvocation> for CodeModeWaitHandler {
create_wait_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -13,7 +13,6 @@ use super::*;
pub struct ReportAgentJobResultHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ReportAgentJobResultHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("report_agent_job_result")
@@ -23,11 +22,8 @@ impl ToolExecutor<ToolInvocation> for ReportAgentJobResultHandler {
create_report_agent_job_result_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -14,7 +14,6 @@ use super::*;
pub struct SpawnAgentsOnCsvHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for SpawnAgentsOnCsvHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("spawn_agents_on_csv")
@@ -24,11 +23,8 @@ impl ToolExecutor<ToolInvocation> for SpawnAgentsOnCsvHandler {
create_spawn_agents_on_csv_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -305,7 +305,6 @@ async fn effective_patch_permissions(
)
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ApplyPatchHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("apply_patch")
@@ -315,11 +314,8 @@ impl ToolExecutor<ToolInvocation> for ApplyPatchHandler {
create_apply_patch_freeform_tool(self.multi_environment)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
+2 -6
View File
@@ -61,7 +61,6 @@ impl DynamicToolHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for DynamicToolHandler {
fn tool_name(&self) -> ToolName {
self.tool_name.clone()
@@ -86,11 +85,8 @@ impl ToolExecutor<ToolInvocation> for DynamicToolHandler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -11,13 +11,11 @@ use codex_tools::ToolSpec;
use codex_tools::TurnItemEmissionFuture;
use codex_tools::TurnItemEmitter;
use crate::function_tool::FunctionCallError;
use crate::session::session::Session;
use crate::session::turn_context::TurnContext;
use crate::stream_events_utils::TurnItemContributorPolicy;
use crate::stream_events_utils::finalize_turn_item;
use crate::tools::context::ToolInvocation;
use crate::tools::context::ToolOutput;
use crate::tools::context::ToolPayload;
use crate::tools::registry::CoreToolRuntime;
use crate::tools::registry::ToolExecutor;
@@ -30,7 +28,6 @@ impl ExtensionToolAdapter {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ExtensionToolAdapter {
fn tool_name(&self) -> ToolName {
self.0.tool_name()
@@ -52,11 +49,8 @@ impl ToolExecutor<ToolInvocation> for ExtensionToolAdapter {
self.0.search_info()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
self.0.handle(to_extension_call(&invocation).await).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move { self.0.handle(to_extension_call(&invocation).await).await })
}
}
@@ -162,7 +156,6 @@ mod tests {
struct StubExtensionExecutor;
#[async_trait::async_trait]
impl codex_extension_api::ToolExecutor<codex_tools::ToolCall> for StubExtensionExecutor {
fn tool_name(&self) -> codex_tools::ToolName {
codex_tools::ToolName::plain("extension_echo")
@@ -187,13 +180,13 @@ mod tests {
})
}
async fn handle(
&self,
_call: codex_tools::ToolCall,
) -> Result<Box<dyn codex_tools::ToolOutput>, codex_tools::FunctionCallError> {
Ok(Box::new(codex_tools::JsonToolOutput::new(
json!({ "ok": true }),
)))
fn handle(&self, _call: codex_tools::ToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async {
Ok(
Box::new(codex_tools::JsonToolOutput::new(json!({ "ok": true })))
as Box<dyn codex_tools::ToolOutput>,
)
})
}
}
@@ -201,7 +194,6 @@ mod tests {
captured_call: Arc<Mutex<Option<codex_tools::ToolCall>>>,
}
#[async_trait::async_trait]
impl codex_extension_api::ToolExecutor<codex_tools::ToolCall> for CapturingExtensionExecutor {
fn tool_name(&self) -> codex_tools::ToolName {
codex_tools::ToolName::plain("extension_echo")
@@ -218,11 +210,8 @@ mod tests {
})
}
async fn handle(
&self,
call: codex_tools::ToolCall,
) -> Result<Box<dyn codex_tools::ToolOutput>, codex_tools::FunctionCallError> {
self.handle_call(call).await
fn handle(&self, call: codex_tools::ToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
@@ -242,9 +231,10 @@ mod tests {
call.turn_item_emitter.emit_started(item.clone()).await;
call.turn_item_emitter.emit_completed(item).await;
*self.captured_call.lock().await = Some(call);
Ok(Box::new(codex_tools::JsonToolOutput::new(
json!({ "ok": true }),
)))
Ok(
Box::new(codex_tools::JsonToolOutput::new(json!({ "ok": true })))
as Box<dyn codex_tools::ToolOutput>,
)
}
}
@@ -441,7 +431,6 @@ mod tests {
);
}
#[async_trait::async_trait]
impl codex_extension_api::ToolExecutor<codex_tools::ToolCall> for ImageGenerationExtensionExecutor {
fn tool_name(&self) -> codex_tools::ToolName {
codex_tools::ToolName::namespaced("image_gen", "imagegen")
@@ -458,11 +447,8 @@ mod tests {
})
}
async fn handle(
&self,
call: codex_tools::ToolCall,
) -> Result<Box<dyn codex_tools::ToolOutput>, codex_tools::FunctionCallError> {
self.handle_call(call).await
fn handle(&self, call: codex_tools::ToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
@@ -493,9 +479,10 @@ mod tests {
},
))
.await;
Ok(Box::new(codex_tools::JsonToolOutput::new(
json!({ "ok": true }),
)))
Ok(
Box::new(codex_tools::JsonToolOutput::new(json!({ "ok": true })))
as Box<dyn codex_tools::ToolOutput>,
)
}
}
@@ -54,7 +54,6 @@ impl ListAvailablePluginsToInstallHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ListAvailablePluginsToInstallHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(LIST_AVAILABLE_PLUGINS_TO_INSTALL_TOOL_NAME)
@@ -68,11 +67,8 @@ impl ToolExecutor<ToolInvocation> for ListAvailablePluginsToInstallHandler {
false
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
+2 -6
View File
@@ -64,7 +64,6 @@ fn ensure_mcp_prefix(name: &str) -> String {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for McpHandler {
fn tool_name(&self) -> ToolName {
self.tool_info.canonical_tool_name()
@@ -113,11 +112,8 @@ impl ToolExecutor<ToolInvocation> for McpHandler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -26,7 +26,6 @@ use super::serialize_function_output;
pub struct ListMcpResourceTemplatesHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ListMcpResourceTemplatesHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("list_mcp_resource_templates")
@@ -40,11 +39,8 @@ impl ToolExecutor<ToolInvocation> for ListMcpResourceTemplatesHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -26,7 +26,6 @@ use super::serialize_function_output;
pub struct ListMcpResourcesHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ListMcpResourcesHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("list_mcp_resources")
@@ -40,11 +39,8 @@ impl ToolExecutor<ToolInvocation> for ListMcpResourcesHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -26,7 +26,6 @@ use super::serialize_function_output;
pub struct ReadMcpResourceHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ReadMcpResourceHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("read_mcp_resource")
@@ -40,11 +39,8 @@ impl ToolExecutor<ToolInvocation> for ReadMcpResourceHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -6,7 +6,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(MULTI_AGENT_V1_NAMESPACE, "close_agent")
@@ -23,11 +22,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
handle_close_agent(invocation).await.map(boxed_tool_output)
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move { handle_close_agent(invocation).await.map(boxed_tool_output) })
}
}
@@ -7,7 +7,6 @@ use std::sync::Arc;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(MULTI_AGENT_V1_NAMESPACE, "resume_agent")
@@ -24,11 +23,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
handle_resume_agent(invocation).await.map(boxed_tool_output)
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move { handle_resume_agent(invocation).await.map(boxed_tool_output) })
}
}
@@ -6,7 +6,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(MULTI_AGENT_V1_NAMESPACE, "send_input")
@@ -23,11 +22,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -22,7 +22,6 @@ impl Handler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(MULTI_AGENT_V1_NAMESPACE, "spawn_agent")
@@ -39,11 +38,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
handle_spawn_agent(invocation).await.map(boxed_tool_output)
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move { handle_spawn_agent(invocation).await.map(boxed_tool_output) })
}
}
@@ -27,7 +27,6 @@ impl Handler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(MULTI_AGENT_V1_NAMESPACE, "wait_agent")
@@ -44,11 +43,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -7,7 +7,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("followup_task")
@@ -17,11 +16,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_followup_task_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -6,7 +6,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("interrupt_agent")
@@ -16,13 +15,12 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_interrupt_agent_tool_v2()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
handle_interrupt_agent(invocation)
.await
.map(boxed_tool_output)
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move {
handle_interrupt_agent(invocation)
.await
.map(boxed_tool_output)
})
}
}
@@ -5,7 +5,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("list_agents")
@@ -15,11 +14,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_list_agents_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -7,7 +7,6 @@ use codex_tools::ToolSpec;
pub(crate) struct Handler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("send_message")
@@ -17,11 +16,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_send_message_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -22,7 +22,6 @@ impl Handler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("spawn_agent")
@@ -32,11 +31,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_spawn_agent_tool_v2(self.options.clone())
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
handle_spawn_agent(invocation).await.map(boxed_tool_output)
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async move { handle_spawn_agent(invocation).await.map(boxed_tool_output) })
}
}
@@ -19,7 +19,6 @@ impl Handler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for Handler {
fn tool_name(&self) -> ToolName {
ToolName::plain("wait_agent")
@@ -29,11 +28,8 @@ impl ToolExecutor<ToolInvocation> for Handler {
create_wait_agent_tool_v2(self.options)
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
+2 -6
View File
@@ -45,7 +45,6 @@ impl ToolOutput for PlanToolOutput {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for PlanHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("update_plan")
@@ -55,11 +54,8 @@ impl ToolExecutor<ToolInvocation> for PlanHandler {
create_update_plan_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -25,7 +25,6 @@ struct RequestPermissionsEnvironmentArgs {
environment_id: Option<String>,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for RequestPermissionsHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("request_permissions")
@@ -35,11 +34,8 @@ impl ToolExecutor<ToolInvocation> for RequestPermissionsHandler {
create_request_permissions_tool(request_permissions_tool_description())
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -48,7 +48,6 @@ impl RequestPluginInstallHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for RequestPluginInstallHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(REQUEST_PLUGIN_INSTALL_TOOL_NAME)
@@ -62,11 +61,8 @@ impl ToolExecutor<ToolInvocation> for RequestPluginInstallHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -20,7 +20,6 @@ pub struct RequestUserInputHandler {
pub available_modes: Vec<ModeKind>,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for RequestUserInputHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(REQUEST_USER_INPUT_TOOL_NAME)
@@ -30,11 +29,8 @@ impl ToolExecutor<ToolInvocation> for RequestUserInputHandler {
create_request_user_input_tool(request_user_input_tool_description(&self.available_modes))
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -124,7 +124,6 @@ impl From<ShellCommandBackendConfig> for ShellCommandHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ShellCommandHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("shell_command")
@@ -141,11 +140,8 @@ impl ToolExecutor<ToolInvocation> for ShellCommandHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -57,7 +57,6 @@ fn barrier_map() -> &'static tokio::sync::Mutex<HashMap<String, BarrierState>> {
BARRIERS.get_or_init(|| tokio::sync::Mutex::new(HashMap::new()))
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for TestSyncHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("test_sync_tool")
@@ -71,11 +70,8 @@ impl ToolExecutor<ToolInvocation> for TestSyncHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -53,7 +53,6 @@ impl ToolSearchHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ToolSearchHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain(TOOL_SEARCH_TOOL_NAME)
@@ -67,11 +66,8 @@ impl ToolExecutor<ToolInvocation> for ToolSearchHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -71,7 +71,6 @@ impl ExecCommandHandler {
}
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ExecCommandHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("exec_command")
@@ -92,11 +91,8 @@ impl ToolExecutor<ToolInvocation> for ExecCommandHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -31,7 +31,6 @@ struct WriteStdinArgs {
pub struct WriteStdinHandler;
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for WriteStdinHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("write_stdin")
@@ -41,11 +40,8 @@ impl ToolExecutor<ToolInvocation> for WriteStdinHandler {
create_write_stdin_tool()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -64,7 +64,6 @@ enum ViewImageDetail {
Original,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ViewImageHandler {
fn tool_name(&self) -> ToolName {
ToolName::plain("view_image")
@@ -78,11 +77,8 @@ impl ToolExecutor<ToolInvocation> for ViewImageHandler {
true
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
+10 -16
View File
@@ -257,7 +257,6 @@ mod tests {
tool_name: codex_tools::ToolName,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ImmediateHandler {
fn tool_name(&self) -> codex_tools::ToolName {
self.tool_name.clone()
@@ -274,14 +273,13 @@ mod tests {
})
}
async fn handle(
&self,
_invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
Ok(Box::new(FunctionToolOutput::from_text(
"ok".to_string(),
Some(true),
)))
fn handle(&self, _invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async {
Ok(
Box::new(FunctionToolOutput::from_text("ok".to_string(), Some(true)))
as Box<dyn crate::tools::context::ToolOutput>,
)
})
}
}
@@ -294,7 +292,6 @@ mod tests {
allow_cleanup: Arc<Notify>,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for CancellationCleanupHandler {
fn tool_name(&self) -> codex_tools::ToolName {
self.tool_name.clone()
@@ -311,11 +308,8 @@ mod tests {
})
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(invocation))
}
}
@@ -345,7 +339,7 @@ mod tests {
Ok(Box::new(FunctionToolOutput::from_text(
"cleanup complete".to_string(),
Some(false),
)))
)) as Box<dyn crate::tools::context::ToolOutput>)
}
}
+2 -6
View File
@@ -250,7 +250,6 @@ struct ExposureOverride {
exposure: ToolExposure,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for ExposureOverride {
fn tool_name(&self) -> ToolName {
self.handler.tool_name()
@@ -272,11 +271,8 @@ impl ToolExecutor<ToolInvocation> for ExposureOverride {
self.handler.search_info()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
self.handler.handle(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
self.handler.handle(invocation)
}
}
+13 -15
View File
@@ -5,7 +5,6 @@ struct TestHandler {
tool_name: codex_tools::ToolName,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for TestHandler {
fn tool_name(&self) -> codex_tools::ToolName {
self.tool_name.clone()
@@ -15,13 +14,15 @@ impl ToolExecutor<ToolInvocation> for TestHandler {
test_spec(&self.tool_name)
}
async fn handle(
&self,
_invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
Ok(Box::new(
crate::tools::context::FunctionToolOutput::from_text("ok".to_string(), Some(true)),
))
fn handle(&self, _invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async {
Ok(
Box::new(crate::tools::context::FunctionToolOutput::from_text(
"ok".to_string(),
Some(true),
)) as Box<dyn crate::tools::context::ToolOutput>,
)
})
}
}
@@ -38,7 +39,6 @@ struct LifecycleTestHandler {
result: LifecycleTestResult,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for LifecycleTestHandler {
fn tool_name(&self) -> codex_tools::ToolName {
self.tool_name.clone()
@@ -48,11 +48,8 @@ impl ToolExecutor<ToolInvocation> for LifecycleTestHandler {
test_spec(&self.tool_name)
}
async fn handle(
&self,
_invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
self.handle_call().await
fn handle(&self, _invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call())
}
}
@@ -66,7 +63,8 @@ impl LifecycleTestHandler {
"ok".to_string(),
Some(success),
),
)),
)
as Box<dyn crate::tools::context::ToolOutput>),
LifecycleTestResult::Err => Err(FunctionCallError::RespondToModel(
"handler failed".to_string(),
)),
+3 -7
View File
@@ -44,7 +44,6 @@ impl codex_extension_api::ToolContributor for ExtensionEchoContributor {
struct ExtensionEchoExecutor;
#[async_trait::async_trait]
impl ToolExecutor<ExtensionToolCall> for ExtensionEchoExecutor {
fn tool_name(&self) -> ToolName {
ToolName::namespaced("extension/", "echo")
@@ -73,11 +72,8 @@ impl ToolExecutor<ExtensionToolCall> for ExtensionEchoExecutor {
})
}
async fn handle(
&self,
call: ExtensionToolCall,
) -> Result<Box<dyn codex_tools::ToolOutput>, codex_tools::FunctionCallError> {
self.handle_call(call).await
fn handle(&self, call: ExtensionToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
@@ -93,7 +89,7 @@ impl ExtensionEchoExecutor {
"callId": call.call_id,
"conversationHistory": call.conversation_history.items(),
"ok": true,
}))))
}))) as Box<dyn codex_tools::ToolOutput>)
}
}
+2 -7
View File
@@ -72,7 +72,6 @@ use codex_tools::ToolCall as ExtensionToolCall;
use codex_tools::ToolEnvironmentMode;
use codex_tools::ToolExecutor;
use codex_tools::ToolName;
use codex_tools::ToolOutput;
use codex_tools::ToolSearchInfo;
use codex_tools::ToolSpec;
use codex_tools::UnifiedExecShellMode;
@@ -946,7 +945,6 @@ struct MultiAgentV2NamespaceOverride {
namespace: String,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for MultiAgentV2NamespaceOverride {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(self.namespace.clone(), self.handler.tool_name().name)
@@ -975,11 +973,8 @@ impl ToolExecutor<ToolInvocation> for MultiAgentV2NamespaceOverride {
self.handler.search_info()
}
async fn handle(
&self,
invocation: ToolInvocation,
) -> Result<Box<dyn ToolOutput>, codex_tools::FunctionCallError> {
self.handler.handle(invocation).await
fn handle(&self, invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
self.handler.handle(invocation)
}
}
+6 -12
View File
@@ -285,7 +285,6 @@ fn use_bedrock_provider(turn: &mut TurnContext) {
struct WebRunExtensionTool;
#[async_trait::async_trait]
impl ToolExecutor<ExtensionToolCall> for WebRunExtensionTool {
fn tool_name(&self) -> ToolName {
ToolName::namespaced("web", "run")
@@ -306,17 +305,15 @@ impl ToolExecutor<ExtensionToolCall> for WebRunExtensionTool {
})
}
async fn handle(
&self,
_call: ExtensionToolCall,
) -> Result<Box<dyn ToolOutput>, codex_tools::FunctionCallError> {
Ok(Box::new(codex_tools::JsonToolOutput::new(json!({}))))
fn handle(&self, _call: ExtensionToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async {
Ok(Box::new(codex_tools::JsonToolOutput::new(json!({}))) as Box<dyn ToolOutput>)
})
}
}
struct DeferredExtensionTool;
#[async_trait::async_trait]
impl ToolExecutor<ExtensionToolCall> for DeferredExtensionTool {
fn tool_name(&self) -> ToolName {
ToolName::plain("extension_echo")
@@ -344,11 +341,8 @@ impl ToolExecutor<ExtensionToolCall> for DeferredExtensionTool {
ToolExposure::Deferred
}
async fn handle(
&self,
_call: ExtensionToolCall,
) -> Result<Box<dyn ToolOutput>, codex_tools::FunctionCallError> {
panic!("spec planning should not execute extension tools")
fn handle(&self, _call: ExtensionToolCall) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async { panic!("spec planning should not execute extension tools") })
}
}
@@ -30,7 +30,6 @@ struct TestHandler {
tool_name: codex_tools::ToolName,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolInvocation> for TestHandler {
fn tool_name(&self) -> codex_tools::ToolName {
self.tool_name.clone()
@@ -47,14 +46,13 @@ impl ToolExecutor<ToolInvocation> for TestHandler {
})
}
async fn handle(
&self,
_invocation: ToolInvocation,
) -> Result<Box<dyn crate::tools::context::ToolOutput>, FunctionCallError> {
Ok(Box::new(FunctionToolOutput::from_text(
"ok".to_string(),
Some(true),
)))
fn handle(&self, _invocation: ToolInvocation) -> codex_tools::ToolExecutorFuture<'_> {
Box::pin(async {
Ok(
Box::new(FunctionToolOutput::from_text("ok".to_string(), Some(true)))
as Box<dyn crate::tools::context::ToolOutput>,
)
})
}
}
+1
View File
@@ -20,6 +20,7 @@ pub use codex_tools::NoopTurnItemEmitter;
pub use codex_tools::ResponsesApiTool;
pub use codex_tools::ToolCall;
pub use codex_tools::ToolExecutor;
pub use codex_tools::ToolExecutorFuture;
pub use codex_tools::ToolName;
pub use codex_tools::ToolOutput;
pub use codex_tools::ToolPayload;
-1
View File
@@ -14,7 +14,6 @@ doctest = false
workspace = true
[dependencies]
async-trait = { workspace = true }
codex-analytics = { workspace = true }
codex-core = { workspace = true }
codex-extension-api = { workspace = true }
+8 -8
View File
@@ -1,6 +1,5 @@
use std::sync::Arc;
use async_trait::async_trait;
use codex_extension_api::FunctionCallError;
use codex_extension_api::JsonToolOutput;
use codex_extension_api::ToolCall;
@@ -132,7 +131,6 @@ impl GoalToolExecutor {
}
}
#[async_trait]
impl ToolExecutor<ToolCall> for GoalToolExecutor {
fn tool_name(&self) -> ToolName {
ToolName::plain(match self.kind {
@@ -150,12 +148,14 @@ impl ToolExecutor<ToolCall> for GoalToolExecutor {
}
}
async fn handle(&self, invocation: ToolCall) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
match self.kind {
GoalToolKind::Get => self.handle_get(invocation).await,
GoalToolKind::Create => self.handle_create(invocation).await,
GoalToolKind::Update => self.handle_update(invocation).await,
}
fn handle(&self, invocation: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(async move {
match self.kind {
GoalToolKind::Get => self.handle_get(invocation).await,
GoalToolKind::Create => self.handle_create(invocation).await,
GoalToolKind::Update => self.handle_update(invocation).await,
}
})
}
}
-1
View File
@@ -13,7 +13,6 @@ doctest = false
workspace = true
[dependencies]
async-trait = { workspace = true }
codex-api = { workspace = true }
codex-core = { workspace = true }
codex-extension-api = { workspace = true }
+2 -3
View File
@@ -78,7 +78,6 @@ struct ImagegenArgs {
num_last_images_to_include: Option<usize>,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolCall> for ImageGenerationTool {
/// Keeps the tool in the existing image-generation Responses namespace.
fn tool_name(&self) -> ToolName {
@@ -96,8 +95,8 @@ impl ToolExecutor<ToolCall> for ImageGenerationTool {
}
/// Executes the selected image operation and returns the completed image result.
async fn handle(&self, call: ToolCall) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
-1
View File
@@ -13,7 +13,6 @@ doctest = false
workspace = true
[dependencies]
async-trait = { workspace = true }
codex-core = { workspace = true }
codex-extension-api = { workspace = true }
codex-features = { workspace = true }
@@ -41,7 +41,6 @@ pub(super) struct AddAdHocNoteTool<B> {
pub(super) metrics_client: Option<MetricsClient>,
}
#[async_trait::async_trait]
impl<B> ToolExecutor<ToolCall> for AddAdHocNoteTool<B>
where
B: MemoriesBackend,
@@ -57,12 +56,8 @@ where
)
}
async fn handle(
&self,
call: ToolCall,
) -> Result<Box<dyn codex_extension_api::ToolOutput>, codex_extension_api::FunctionCallError>
{
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
+2 -7
View File
@@ -39,7 +39,6 @@ pub(super) struct ListTool<B> {
pub(super) metrics_client: Option<MetricsClient>,
}
#[async_trait::async_trait]
impl<B> ToolExecutor<ToolCall> for ListTool<B>
where
B: MemoriesBackend,
@@ -55,12 +54,8 @@ where
)
}
async fn handle(
&self,
call: ToolCall,
) -> Result<Box<dyn codex_extension_api::ToolOutput>, codex_extension_api::FunctionCallError>
{
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
+2 -7
View File
@@ -38,7 +38,6 @@ pub(super) struct ReadTool<B> {
pub(super) metrics_client: Option<MetricsClient>,
}
#[async_trait::async_trait]
impl<B> ToolExecutor<ToolCall> for ReadTool<B>
where
B: MemoriesBackend,
@@ -54,12 +53,8 @@ where
)
}
async fn handle(
&self,
call: ToolCall,
) -> Result<Box<dyn codex_extension_api::ToolOutput>, codex_extension_api::FunctionCallError>
{
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
+2 -7
View File
@@ -47,7 +47,6 @@ pub(super) struct SearchTool<B> {
pub(super) metrics_client: Option<MetricsClient>,
}
#[async_trait::async_trait]
impl<B> ToolExecutor<ToolCall> for SearchTool<B>
where
B: MemoriesBackend,
@@ -63,12 +62,8 @@ where
)
}
async fn handle(
&self,
call: ToolCall,
) -> Result<Box<dyn codex_extension_api::ToolOutput>, codex_extension_api::FunctionCallError>
{
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
-1
View File
@@ -13,7 +13,6 @@ doctest = false
workspace = true
[dependencies]
async-trait = { workspace = true }
codex-api = { workspace = true }
codex-core = { workspace = true }
codex-extension-api = { workspace = true }
+2 -3
View File
@@ -39,7 +39,6 @@ pub(crate) struct WebSearchTool {
pub(crate) settings: SearchSettings,
}
#[async_trait::async_trait]
impl ToolExecutor<ToolCall> for WebSearchTool {
fn tool_name(&self) -> ToolName {
ToolName::namespaced(WEB_NAMESPACE, RUN_TOOL_NAME)
@@ -74,8 +73,8 @@ impl ToolExecutor<ToolCall> for WebSearchTool {
true
}
async fn handle(&self, call: ToolCall) -> Result<Box<dyn ToolOutput>, FunctionCallError> {
self.handle_call(call).await
fn handle(&self, call: ToolCall) -> codex_extension_api::ToolExecutorFuture<'_> {
Box::pin(self.handle_call(call))
}
}
-1
View File
@@ -8,7 +8,6 @@ version.workspace = true
workspace = true
[dependencies]
async-trait = { workspace = true }
codex-app-server-protocol = { workspace = true }
codex-code-mode = { workspace = true }
codex-features = { workspace = true }
+1
View File
@@ -93,6 +93,7 @@ pub use tool_discovery::ToolSearchSourceInfo;
pub use tool_discovery::collect_request_plugin_install_entries;
pub use tool_discovery::filter_request_plugin_install_discoverable_tools_for_client;
pub use tool_executor::ToolExecutor;
pub use tool_executor::ToolExecutorFuture;
pub use tool_executor::ToolExposure;
pub use tool_output::JsonToolOutput;
pub use tool_output::ToolOutput;
+7 -5
View File
@@ -3,6 +3,12 @@ use crate::ToolName;
use crate::ToolOutput;
use crate::ToolSearchInfo;
use crate::ToolSpec;
use std::future::Future;
use std::pin::Pin;
/// The boxed future returned by [`ToolExecutor::handle`].
pub type ToolExecutorFuture<'a> =
Pin<Box<dyn Future<Output = Result<Box<dyn ToolOutput>, FunctionCallError>> + Send + 'a>>;
/// Controls where a tool is exposed to the model.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -40,7 +46,6 @@ impl ToolExposure {
/// Implementations keep the model-visible spec tied to the executable runtime.
/// Host crates can layer routing, hooks, telemetry, or other orchestration on
/// top without reopening the spec/runtime split.
#[async_trait::async_trait]
pub trait ToolExecutor<Invocation>: Send + Sync {
/// The concrete tool name handled by this runtime instance.
fn tool_name(&self) -> ToolName;
@@ -60,8 +65,5 @@ pub trait ToolExecutor<Invocation>: Send + Sync {
false
}
async fn handle(
&self,
invocation: Invocation,
) -> Result<Box<dyn ToolOutput>, FunctionCallError>;
fn handle(&self, invocation: Invocation) -> ToolExecutorFuture<'_>;
}