mirror of
https://github.com/openai/codex.git
synced 2026-10-25 18:28:38 +00:00
register all mcps w/ namespace
This commit is contained in:
@@ -120,6 +120,7 @@ pub use tool_registry_plan_types::ToolHandlerSpec;
|
||||
pub use tool_registry_plan_types::ToolNamespace;
|
||||
pub use tool_registry_plan_types::ToolRegistryPlan;
|
||||
pub use tool_registry_plan_types::ToolRegistryPlanDeferredTool;
|
||||
pub use tool_registry_plan_types::ToolRegistryPlanMcpTool;
|
||||
pub use tool_registry_plan_types::ToolRegistryPlanParams;
|
||||
pub use tool_spec::ConfiguredToolSpec;
|
||||
pub use tool_spec::ResponsesApiWebSearchFilters;
|
||||
|
||||
@@ -61,7 +61,6 @@ use crate::request_user_input_tool_description;
|
||||
use crate::tool_registry_plan_types::agent_type_description;
|
||||
use codex_protocol::openai_models::ApplyPatchToolType;
|
||||
use codex_protocol::openai_models::ConfigShellToolType;
|
||||
use rmcp::model::Tool as McpTool;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub fn build_tool_registry_plan(
|
||||
@@ -471,25 +470,26 @@ pub fn build_tool_registry_plan(
|
||||
}
|
||||
|
||||
if let Some(mcp_tools) = params.mcp_tools {
|
||||
let mut entries: Vec<(String, &McpTool)> = mcp_tools
|
||||
.iter()
|
||||
.map(|(name, tool)| (name.clone(), tool))
|
||||
.collect();
|
||||
entries.sort_by(|left, right| left.0.cmp(&right.0));
|
||||
let mut entries = mcp_tools.to_vec();
|
||||
entries.sort_by(|left, right| left.qualified_name.cmp(&right.qualified_name));
|
||||
|
||||
for (name, tool) in entries {
|
||||
match mcp_tool_to_responses_api_tool(name.clone(), tool) {
|
||||
for tool in entries {
|
||||
let qualified_name = tool.qualified_name.clone();
|
||||
match mcp_tool_to_responses_api_tool(qualified_name.clone(), tool.tool) {
|
||||
Ok(converted_tool) => {
|
||||
plan.push_spec(
|
||||
ToolSpec::Function(converted_tool),
|
||||
/*supports_parallel_tool_calls*/ false,
|
||||
config.code_mode_enabled,
|
||||
);
|
||||
plan.register_handler(name, ToolHandlerKind::Mcp);
|
||||
plan.register_handler(
|
||||
ToolName::namespaced(tool.callable_namespace, tool.callable_name),
|
||||
ToolHandlerKind::Mcp,
|
||||
);
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::error!(
|
||||
"Failed to convert {name:?} MCP tool to OpenAI tool: {error:?}"
|
||||
"Failed to convert {qualified_name:?} MCP tool to OpenAI tool: {error:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use crate::ResponsesApiWebSearchUserLocation;
|
||||
use crate::ToolHandlerSpec;
|
||||
use crate::ToolNamespace;
|
||||
use crate::ToolRegistryPlanDeferredTool;
|
||||
use crate::ToolRegistryPlanMcpTool;
|
||||
use crate::ToolsConfigParams;
|
||||
use crate::WaitAgentTimeoutOptions;
|
||||
use crate::mcp_call_tool_result_output_schema;
|
||||
@@ -1890,10 +1891,29 @@ fn build_specs_with_optional_tool_namespaces<'a>(
|
||||
discoverable_tools: Option<Vec<DiscoverableTool>>,
|
||||
dynamic_tools: &[DynamicToolSpec],
|
||||
) -> (Vec<ConfiguredToolSpec>, Vec<ToolHandlerSpec>) {
|
||||
let mcp_tool_inputs = mcp_tools.as_ref().map(|mcp_tools| {
|
||||
mcp_tools
|
||||
.iter()
|
||||
.map(|(qualified_name, tool)| {
|
||||
let raw_tool_name = tool.name.as_ref();
|
||||
let callable_namespace = qualified_name
|
||||
.strip_suffix(raw_tool_name)
|
||||
.filter(|namespace| !namespace.is_empty())
|
||||
.unwrap_or("mcp__test_server__");
|
||||
|
||||
ToolRegistryPlanMcpTool {
|
||||
qualified_name: qualified_name.clone(),
|
||||
callable_name: raw_tool_name.to_string(),
|
||||
callable_namespace: callable_namespace.to_string(),
|
||||
tool,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let plan = build_tool_registry_plan(
|
||||
config,
|
||||
ToolRegistryPlanParams {
|
||||
mcp_tools: mcp_tools.as_ref(),
|
||||
mcp_tools: mcp_tool_inputs.as_deref(),
|
||||
deferred_mcp_tools: deferred_mcp_tools.as_deref(),
|
||||
tool_namespaces: tool_namespaces.as_ref(),
|
||||
discoverable_tools: discoverable_tools.as_deref(),
|
||||
|
||||
@@ -6,7 +6,6 @@ use crate::ToolsConfig;
|
||||
use crate::WaitAgentTimeoutOptions;
|
||||
use crate::augment_tool_spec_for_code_mode;
|
||||
use codex_protocol::dynamic_tools::DynamicToolSpec;
|
||||
use rmcp::model::Tool as McpTool;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
@@ -58,7 +57,7 @@ pub struct ToolRegistryPlan {
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ToolRegistryPlanParams<'a> {
|
||||
pub mcp_tools: Option<&'a HashMap<String, McpTool>>,
|
||||
pub mcp_tools: Option<&'a [ToolRegistryPlanMcpTool<'a>]>,
|
||||
pub deferred_mcp_tools: Option<&'a [ToolRegistryPlanDeferredTool<'a>]>,
|
||||
pub tool_namespaces: Option<&'a HashMap<String, ToolNamespace>>,
|
||||
pub discoverable_tools: Option<&'a [DiscoverableTool]>,
|
||||
@@ -73,6 +72,16 @@ pub struct ToolNamespace {
|
||||
pub description: Option<String>,
|
||||
}
|
||||
|
||||
/// Direct MCP tool metadata needed to expose the flat Responses API tool while
|
||||
/// registering its runtime handler with the canonical namespace/name split.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ToolRegistryPlanMcpTool<'a> {
|
||||
pub qualified_name: String,
|
||||
pub callable_name: String,
|
||||
pub callable_namespace: String,
|
||||
pub tool: &'a rmcp::model::Tool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ToolRegistryPlanDeferredTool<'a> {
|
||||
pub tool_name: &'a str,
|
||||
|
||||
Reference in New Issue
Block a user