mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
codex-tools: extract discoverable tool models (#16254)
## Why `#16193` moved the pure `tool_search` and `tool_suggest` spec builders into `codex-tools`, but `codex-core` still owned the shared discoverable-tool model that those builders and the `tool_suggest` runtime both depend on. This change continues the migration by moving that reusable model boundary out of `codex-core` as well, so the discovery/suggestion stack uses one shared set of types and `core/src/tools` no longer needs its own `discoverable.rs` module. ## What changed - Moved `DiscoverableTool`, `DiscoverablePluginInfo`, and `filter_tool_suggest_discoverable_tools_for_client()` into `codex-rs/tools/src/tool_discovery.rs` alongside the extracted discovery/suggestion spec builders. - Added `codex-app-server-protocol` as a `codex-tools` dependency so the shared discoverable-tool model can own the connector-side `AppInfo` variant directly. - Updated `core/src/tools/handlers/tool_suggest.rs`, `core/src/tools/spec.rs`, `core/src/tools/router.rs`, `core/src/connectors.rs`, and `core/src/codex.rs` to consume the shared `codex-tools` model instead of the old core-local declarations. - Changed `core/src/plugins/discoverable.rs` to return `DiscoverablePluginInfo` directly, moved the pure client-filter coverage into `tool_discovery_tests.rs`, and deleted the old `core/src/tools/discoverable.rs` module. - Updated `codex-rs/tools/README.md` so the crate boundary documents that `codex-tools` now owns the discoverable-tool models in addition to the discovery/suggestion spec builders. ## Test plan - `cargo test -p codex-tools` - `CARGO_TARGET_DIR=/tmp/codex-core-discoverable-model cargo test -p codex-core --lib tools::handlers::tool_suggest::` - `CARGO_TARGET_DIR=/tmp/codex-core-discoverable-model cargo test -p codex-core --lib tools::spec::` - `CARGO_TARGET_DIR=/tmp/codex-core-discoverable-model cargo test -p codex-core --lib plugins::discoverable::` - `just bazel-lock-check` - `just argument-comment-lint` ## References - #16193 - #16154 - #15923 - #15928 - #15944 - #15953 - #16031 - #16047 - #16129 - #16132 - #16138 - #16141
This commit is contained in:
@@ -1,94 +0,0 @@
|
||||
use crate::plugins::PluginCapabilitySummary;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use codex_tools::DiscoverableToolType;
|
||||
|
||||
const TUI_CLIENT_NAME: &str = "codex-tui";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub(crate) enum DiscoverableTool {
|
||||
Connector(Box<AppInfo>),
|
||||
Plugin(Box<DiscoverablePluginInfo>),
|
||||
}
|
||||
|
||||
impl DiscoverableTool {
|
||||
pub(crate) fn tool_type(&self) -> DiscoverableToolType {
|
||||
match self {
|
||||
Self::Connector(_) => DiscoverableToolType::Connector,
|
||||
Self::Plugin(_) => DiscoverableToolType::Plugin,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn id(&self) -> &str {
|
||||
match self {
|
||||
Self::Connector(connector) => connector.id.as_str(),
|
||||
Self::Plugin(plugin) => plugin.id.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::Connector(connector) => connector.name.as_str(),
|
||||
Self::Plugin(plugin) => plugin.name.as_str(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn install_url(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Connector(connector) => connector.install_url.as_deref(),
|
||||
Self::Plugin(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AppInfo> for DiscoverableTool {
|
||||
fn from(value: AppInfo) -> Self {
|
||||
Self::Connector(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DiscoverablePluginInfo> for DiscoverableTool {
|
||||
fn from(value: DiscoverablePluginInfo) -> Self {
|
||||
Self::Plugin(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn filter_tool_suggest_discoverable_tools_for_client(
|
||||
discoverable_tools: Vec<DiscoverableTool>,
|
||||
app_server_client_name: Option<&str>,
|
||||
) -> Vec<DiscoverableTool> {
|
||||
if app_server_client_name != Some(TUI_CLIENT_NAME) {
|
||||
return discoverable_tools;
|
||||
}
|
||||
|
||||
discoverable_tools
|
||||
.into_iter()
|
||||
.filter(|tool| !matches!(tool, DiscoverableTool::Plugin(_)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct DiscoverablePluginInfo {
|
||||
pub(crate) id: String,
|
||||
pub(crate) name: String,
|
||||
pub(crate) description: Option<String>,
|
||||
pub(crate) has_skills: bool,
|
||||
pub(crate) mcp_server_names: Vec<String>,
|
||||
pub(crate) app_connector_ids: Vec<String>,
|
||||
}
|
||||
|
||||
impl From<PluginCapabilitySummary> for DiscoverablePluginInfo {
|
||||
fn from(value: PluginCapabilitySummary) -> Self {
|
||||
Self {
|
||||
id: value.config_name,
|
||||
name: value.display_name,
|
||||
description: value.description,
|
||||
has_skills: value.has_skills,
|
||||
mcp_server_names: value.mcp_server_names,
|
||||
app_connector_ids: value
|
||||
.app_connector_ids
|
||||
.into_iter()
|
||||
.map(|connector_id| connector_id.0)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,10 @@ use codex_app_server_protocol::McpElicitationSchema;
|
||||
use codex_app_server_protocol::McpServerElicitationRequest;
|
||||
use codex_app_server_protocol::McpServerElicitationRequestParams;
|
||||
use codex_rmcp_client::ElicitationAction;
|
||||
use codex_tools::DiscoverableTool;
|
||||
use codex_tools::DiscoverableToolAction;
|
||||
use codex_tools::DiscoverableToolType;
|
||||
use codex_tools::filter_tool_suggest_discoverable_tools_for_client;
|
||||
use rmcp::model::RequestId;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -22,8 +24,6 @@ use crate::mcp::CODEX_APPS_MCP_SERVER_NAME;
|
||||
use crate::tools::context::FunctionToolOutput;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::discoverable::DiscoverableTool;
|
||||
use crate::tools::discoverable::filter_tool_suggest_discoverable_tools_for_client;
|
||||
use crate::tools::handlers::parse_arguments;
|
||||
use crate::tools::registry::ToolHandler;
|
||||
use crate::tools::registry::ToolKind;
|
||||
|
||||
@@ -5,9 +5,9 @@ use crate::plugins::test_support::load_plugins_config;
|
||||
use crate::plugins::test_support::write_curated_plugin_sha;
|
||||
use crate::plugins::test_support::write_openai_curated_marketplace;
|
||||
use crate::plugins::test_support::write_plugins_feature_config;
|
||||
use crate::tools::discoverable::DiscoverablePluginInfo;
|
||||
use crate::tools::discoverable::filter_tool_suggest_discoverable_tools_for_client;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
use codex_tools::DiscoverableTool;
|
||||
use codex_tools::DiscoverableToolAction;
|
||||
use codex_tools::DiscoverableToolType;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -161,54 +161,6 @@ fn build_tool_suggestion_meta_uses_expected_shape() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filter_tool_suggest_discoverable_tools_for_codex_tui_omits_plugins() {
|
||||
let discoverable_tools = vec![
|
||||
DiscoverableTool::Connector(Box::new(AppInfo {
|
||||
id: "connector_google_calendar".to_string(),
|
||||
name: "Google Calendar".to_string(),
|
||||
description: Some("Plan events and schedules.".to_string()),
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://example.test/google-calendar".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
plugin_display_names: Vec::new(),
|
||||
})),
|
||||
DiscoverableTool::Plugin(Box::new(DiscoverablePluginInfo {
|
||||
id: "slack@openai-curated".to_string(),
|
||||
name: "Slack".to_string(),
|
||||
description: Some("Search Slack messages".to_string()),
|
||||
has_skills: true,
|
||||
mcp_server_names: vec!["slack".to_string()],
|
||||
app_connector_ids: vec!["connector_slack".to_string()],
|
||||
})),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
filter_tool_suggest_discoverable_tools_for_client(discoverable_tools, Some("codex-tui"),),
|
||||
vec![DiscoverableTool::Connector(Box::new(AppInfo {
|
||||
id: "connector_google_calendar".to_string(),
|
||||
name: "Google Calendar".to_string(),
|
||||
description: Some("Plan events and schedules.".to_string()),
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://example.test/google-calendar".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
plugin_display_names: Vec::new(),
|
||||
}))]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verified_connector_suggestion_completed_requires_accessible_connector() {
|
||||
let accessible_connectors = vec![AppInfo {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
pub mod code_mode;
|
||||
pub mod context;
|
||||
pub(crate) mod discoverable;
|
||||
pub mod events;
|
||||
pub(crate) mod handlers;
|
||||
pub mod js_repl;
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::sandboxing::SandboxPermissions;
|
||||
use crate::tools::context::SharedTurnDiffTracker;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::discoverable::DiscoverableTool;
|
||||
use crate::tools::registry::AnyToolResult;
|
||||
use crate::tools::registry::ToolRegistry;
|
||||
use crate::tools::spec::ToolsConfig;
|
||||
@@ -18,6 +17,7 @@ use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::models::SearchToolCallParams;
|
||||
use codex_protocol::models::ShellToolCallParams;
|
||||
use codex_tools::ConfiguredToolSpec;
|
||||
use codex_tools::DiscoverableTool;
|
||||
use rmcp::model::Tool;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -7,7 +7,6 @@ use crate::shell::Shell;
|
||||
use crate::shell::ShellType;
|
||||
use crate::tools::code_mode::PUBLIC_TOOL_NAME;
|
||||
use crate::tools::code_mode::WAIT_TOOL_NAME;
|
||||
use crate::tools::discoverable::DiscoverableTool;
|
||||
use crate::tools::handlers::PLAN_TOOL;
|
||||
use crate::tools::handlers::TOOL_SEARCH_DEFAULT_LIMIT;
|
||||
use crate::tools::handlers::TOOL_SEARCH_TOOL_NAME;
|
||||
@@ -38,6 +37,7 @@ use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::SubAgentSource;
|
||||
use codex_tools::CommandToolOptions;
|
||||
use codex_tools::DiscoverableTool;
|
||||
use codex_tools::DiscoverableToolType;
|
||||
use codex_tools::ShellToolOptions;
|
||||
use codex_tools::SpawnAgentToolOptions;
|
||||
|
||||
@@ -4,7 +4,6 @@ use crate::models_manager::model_info::with_config_overrides;
|
||||
use crate::shell::Shell;
|
||||
use crate::shell::ShellType;
|
||||
use crate::tools::ToolRouter;
|
||||
use crate::tools::discoverable::DiscoverablePluginInfo;
|
||||
use crate::tools::router::ToolRouterParams;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use codex_protocol::models::VIEW_IMAGE_TOOL_NAME;
|
||||
@@ -14,6 +13,8 @@ use codex_protocol::openai_models::ModelsResponse;
|
||||
use codex_tools::AdditionalProperties;
|
||||
use codex_tools::CommandToolOptions;
|
||||
use codex_tools::ConfiguredToolSpec;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
use codex_tools::DiscoverableTool;
|
||||
use codex_tools::FreeformTool;
|
||||
use codex_tools::ResponsesApiTool;
|
||||
use codex_tools::ResponsesApiWebSearchFilters;
|
||||
|
||||
Reference in New Issue
Block a user