mirror of
https://github.com/openai/codex.git
synced 2026-10-31 19:28:49 +00:00
update
This commit is contained in:
@@ -4,7 +4,7 @@ use codex_protocol::protocol::APPS_INSTRUCTIONS_OPEN_TAG;
|
||||
|
||||
pub(crate) fn render_apps_section() -> String {
|
||||
let body = format!(
|
||||
"## Apps (Connectors)\nApps (Connectors) can be explicitly triggered in user messages in the format `[$app-name](app://{{connector_id}})`. Apps can also be implicitly triggered as long as the context suggests usage of available apps, the available apps will be listed by the `tool_search` tool.\nAn app is equivalent to a set of MCP tools within the `{CODEX_APPS_MCP_SERVER_NAME}` MCP.\nAn installed app's MCP tools are either provided to you already, or can be lazy-loaded through the `tool_search` tool.\nDo not additionally call list_mcp_resources or list_mcp_resource_templates for apps."
|
||||
"## Apps (Connectors)\nApps (Connectors) can be explicitly triggered in user messages in the format `[$app-name](app://{{connector_id}})`. Apps can also be implicitly triggered as long as the context suggests usage of available apps, the available apps will be listed by the `tool_search_tool` tool.\nAn app is equivalent to a set of MCP tools within the `{CODEX_APPS_MCP_SERVER_NAME}` MCP.\nAn installed app's MCP tools are either provided to you already, or can be lazy-loaded through the `tool_search_tool` tool.\nDo not additionally call list_mcp_resources or list_mcp_resource_templates for apps."
|
||||
);
|
||||
format!("{APPS_INSTRUCTIONS_OPEN_TAG}\n{body}\n{APPS_INSTRUCTIONS_CLOSE_TAG}")
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ pub(crate) mod tools {
|
||||
pub(crate) fn name(&self) -> &str {
|
||||
match self {
|
||||
ToolSpec::Function(tool) => tool.name.as_str(),
|
||||
ToolSpec::ToolSearch { .. } => "tool_search",
|
||||
ToolSpec::ToolSearch { .. } => "tool_search_tool",
|
||||
ToolSpec::LocalShell {} => "local_shell",
|
||||
ToolSpec::ImageGeneration { .. } => "image_generation",
|
||||
ToolSpec::WebSearch { .. } => "web_search",
|
||||
|
||||
@@ -6394,8 +6394,9 @@ pub(crate) async fn built_tools(
|
||||
mcp_tools = selected_mcp_tools;
|
||||
}
|
||||
|
||||
// Expose app tools directly when tool_search is disabled, or when tool_search
|
||||
// is enabled but the accessible app tool set stays below the direct-exposure threshold.
|
||||
// Expose app tools directly when the search tool is disabled, or when the
|
||||
// search tool is enabled but the accessible app tool set stays below the
|
||||
// direct-exposure threshold.
|
||||
let expose_app_tools_directly = !turn_context.tools_config.search_tool
|
||||
|| app_tools
|
||||
.as_ref()
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct ToolSearchHandler {
|
||||
tools: HashMap<String, ToolInfo>,
|
||||
}
|
||||
|
||||
pub(crate) const TOOL_SEARCH_TOOL_NAME: &str = "tool_search";
|
||||
pub(crate) const TOOL_SEARCH_TOOL_NAME: &str = "tool_search_tool";
|
||||
pub(crate) const DEFAULT_LIMIT: usize = 8;
|
||||
|
||||
impl ToolSearchHandler {
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::tools::context::SharedTurnDiffTracker;
|
||||
use crate::tools::context::ToolInvocation;
|
||||
use crate::tools::context::ToolPayload;
|
||||
use crate::tools::discoverable::DiscoverableTool;
|
||||
use crate::tools::handlers::TOOL_SEARCH_TOOL_NAME;
|
||||
use crate::tools::registry::AnyToolResult;
|
||||
use crate::tools::registry::ConfiguredToolSpec;
|
||||
use crate::tools::registry::ToolRegistry;
|
||||
@@ -159,7 +160,7 @@ impl ToolRouter {
|
||||
))
|
||||
})?;
|
||||
Ok(Some(ToolCall {
|
||||
tool_name: "tool_search".to_string(),
|
||||
tool_name: TOOL_SEARCH_TOOL_NAME.to_string(),
|
||||
tool_namespace: None,
|
||||
call_id,
|
||||
payload: ToolPayload::ToolSearch { arguments },
|
||||
|
||||
@@ -261,7 +261,7 @@ fn deferred_responses_api_tool_serializes_with_defer_loading() {
|
||||
fn tool_name(tool: &ToolSpec) -> &str {
|
||||
match tool {
|
||||
ToolSpec::Function(ResponsesApiTool { name, .. }) => name,
|
||||
ToolSpec::ToolSearch { .. } => "tool_search",
|
||||
ToolSpec::ToolSearch { .. } => "tool_search_tool",
|
||||
ToolSpec::LocalShell {} => "local_shell",
|
||||
ToolSpec::ImageGeneration { .. } => "image_generation",
|
||||
ToolSpec::WebSearch { .. } => "web_search",
|
||||
@@ -1894,7 +1894,7 @@ fn search_tool_description_lists_each_codex_apps_connector_once() {
|
||||
|
||||
let search_tool = find_tool(&tools, TOOL_SEARCH_TOOL_NAME);
|
||||
let ToolSpec::ToolSearch { description, .. } = &search_tool.spec else {
|
||||
panic!("expected tool_search tool");
|
||||
panic!("expected tool_search_tool tool");
|
||||
};
|
||||
let description = description.as_str();
|
||||
assert!(description.contains("- Calendar: Plan events and manage your calendar."));
|
||||
@@ -2013,7 +2013,7 @@ fn search_tool_description_handles_no_enabled_apps() {
|
||||
let (tools, _) = build_specs(&tools_config, None, Some(HashMap::new()), &[]).build();
|
||||
let search_tool = find_tool(&tools, TOOL_SEARCH_TOOL_NAME);
|
||||
let ToolSpec::ToolSearch { description, .. } = &search_tool.spec else {
|
||||
panic!("expected tool_search tool");
|
||||
panic!("expected tool_search_tool tool");
|
||||
};
|
||||
|
||||
assert!(description.contains("None currently enabled."));
|
||||
@@ -2061,7 +2061,7 @@ fn search_tool_description_falls_back_to_connector_name_without_description() {
|
||||
.build();
|
||||
let search_tool = find_tool(&tools, TOOL_SEARCH_TOOL_NAME);
|
||||
let ToolSpec::ToolSearch { description, .. } = &search_tool.spec else {
|
||||
panic!("expected tool_search tool");
|
||||
panic!("expected tool_search_tool tool");
|
||||
};
|
||||
|
||||
assert!(description.contains("- Calendar"));
|
||||
|
||||
@@ -4,4 +4,4 @@ Searches over apps/connectors tool metadata with BM25 and exposes matching tools
|
||||
|
||||
You have access to all the tools of the following apps/connectors:
|
||||
{{app_descriptions}}
|
||||
Some of the tools may not have been provided to you upfront, and you should use this tool (`tool_search`) to search for the required tools and load them for the apps mentioned above. For the apps mentioned above, always use `tool_search` instead of `list_mcp_resources` or `list_mcp_resource_templates` for tool discovery.
|
||||
Some of the tools may not have been provided to you upfront, and you should use this tool (`tool_search_tool`) to search for the required tools and load them for the apps mentioned above. For the apps mentioned above, always use `tool_search_tool` instead of `list_mcp_resources` or `list_mcp_resource_templates` for tool discovery.
|
||||
|
||||
@@ -4,7 +4,7 @@ Suggests a discoverable connector or plugin when the user clearly wants a capabi
|
||||
|
||||
Use this ONLY when:
|
||||
- There's no available tool to handle the user's request
|
||||
- And tool_search fails to find a good match
|
||||
- And tool_search_tool fails to find a good match, if tool_search_tool is available
|
||||
- AND the user's request strongly matches one of the discoverable tools listed below.
|
||||
|
||||
Tool suggestions should only use the discoverable tools listed here. DO NOT explore or recommend tools that are not on this list.
|
||||
|
||||
@@ -35,7 +35,7 @@ const SEARCH_TOOL_DESCRIPTION_SNIPPETS: [&str; 2] = [
|
||||
"You have access to all the tools of the following apps/connectors",
|
||||
"- Calendar: Plan events and manage your calendar.",
|
||||
];
|
||||
const TOOL_SEARCH_TOOL_NAME: &str = "tool_search";
|
||||
const TOOL_SEARCH_TOOL_TYPE: &str = "tool_search";
|
||||
const CALENDAR_CREATE_TOOL: &str = "mcp__codex_apps__calendar_create_event";
|
||||
const CALENDAR_LIST_TOOL: &str = "mcp__codex_apps__calendar_list_events";
|
||||
const SEARCH_CALENDAR_NAMESPACE: &str = "mcp__codex_apps__calendar";
|
||||
@@ -63,7 +63,7 @@ fn tool_search_description(body: &Value) -> Option<String> {
|
||||
.and_then(Value::as_array)
|
||||
.and_then(|tools| {
|
||||
tools.iter().find_map(|tool| {
|
||||
if tool.get("type").and_then(Value::as_str) == Some(TOOL_SEARCH_TOOL_NAME) {
|
||||
if tool.get("type").and_then(Value::as_str) == Some(TOOL_SEARCH_TOOL_TYPE) {
|
||||
tool.get("description")
|
||||
.and_then(Value::as_str)
|
||||
.map(str::to_string)
|
||||
@@ -144,7 +144,7 @@ async fn search_tool_flag_adds_tool_search() -> Result<()> {
|
||||
.expect("tools array should exist");
|
||||
let tool_search = tools
|
||||
.iter()
|
||||
.find(|tool| tool.get("type").and_then(Value::as_str) == Some(TOOL_SEARCH_TOOL_NAME))
|
||||
.find(|tool| tool.get("type").and_then(Value::as_str) == Some(TOOL_SEARCH_TOOL_TYPE))
|
||||
.cloned()
|
||||
.expect("tool_search should be present");
|
||||
|
||||
@@ -200,8 +200,8 @@ async fn search_tool_is_hidden_for_api_key_auth() -> Result<()> {
|
||||
let body = mock.single_request().body_json();
|
||||
let tools = tool_names(&body);
|
||||
assert!(
|
||||
!tools.iter().any(|name| name == TOOL_SEARCH_TOOL_NAME),
|
||||
"tools list should not include {TOOL_SEARCH_TOOL_NAME} for API key auth: {tools:?}"
|
||||
!tools.iter().any(|name| name == TOOL_SEARCH_TOOL_TYPE),
|
||||
"tools list should not include {TOOL_SEARCH_TOOL_TYPE} for API key auth: {tools:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
@@ -241,6 +241,14 @@ async fn search_tool_adds_discovery_instructions_to_tool_description() -> Result
|
||||
.all(|snippet| description.contains(snippet)),
|
||||
"tool_search description should include the updated workflow: {description:?}"
|
||||
);
|
||||
assert!(
|
||||
description.contains("`tool_search_tool`"),
|
||||
"tool_search description should mention the callable tool name: {description:?}"
|
||||
);
|
||||
assert!(
|
||||
!description.contains("`tool_search`"),
|
||||
"tool_search description should not mention the legacy callable tool name: {description:?}"
|
||||
);
|
||||
assert!(
|
||||
!description.contains("remainder of the current session/thread"),
|
||||
"tool_search description should not mention legacy client-side persistence: {description:?}"
|
||||
@@ -277,7 +285,7 @@ async fn search_tool_hides_apps_tools_without_search() -> Result<()> {
|
||||
|
||||
let body = mock.single_request().body_json();
|
||||
let tools = tool_names(&body);
|
||||
assert!(tools.iter().any(|name| name == TOOL_SEARCH_TOOL_NAME));
|
||||
assert!(tools.iter().any(|name| name == TOOL_SEARCH_TOOL_TYPE));
|
||||
assert!(!tools.iter().any(|name| name == CALENDAR_CREATE_TOOL));
|
||||
assert!(!tools.iter().any(|name| name == CALENDAR_LIST_TOOL));
|
||||
|
||||
@@ -461,7 +469,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() -
|
||||
assert!(
|
||||
first_request_tools
|
||||
.iter()
|
||||
.any(|name| name == TOOL_SEARCH_TOOL_NAME),
|
||||
.any(|name| name == TOOL_SEARCH_TOOL_TYPE),
|
||||
"first request should advertise tool_search: {first_request_tools:?}"
|
||||
);
|
||||
assert!(
|
||||
|
||||
Reference in New Issue
Block a user