mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
tools: simplify default tool search text (#27526)
## Why
Default tool search text currently derives identity from both `ToolName`
and `ToolSpec`. For function and namespace specs, this indexes the same
names more than once and also adds a flattened `{namespace}{name}` token
that is not model-visible.
## What changed
- Derive default search text entirely from `ToolSpec` while preserving
names, descriptions, namespace metadata, and recursive schema metadata.
- Keep the default search-text builder private and remove the unused
`ToolName` argument.
- Add coverage for the exact search text generated for a namespaced tool
with nested schema metadata.
## Example
For the `codex_app` namespace and `automation_update` tool (schema terms
omitted):
- Before: `codex_appautomation_update automation update codex_app
codex_app Manage Codex automations. automation_update automation update
...`
- After: `codex_app Manage Codex automations. automation_update
automation update ...`
## Testing
- `just test -p codex-tools`
This commit is contained in:
committed by
GitHub
Unverified
parent
f1f9d0c3b5
commit
728b8243a9
@@ -100,7 +100,6 @@ pub use tool_output::ToolOutput;
|
||||
pub use tool_payload::ToolPayload;
|
||||
pub use tool_search::ToolSearchEntry;
|
||||
pub use tool_search::ToolSearchInfo;
|
||||
pub use tool_search::default_tool_search_text;
|
||||
pub use tool_spec::ResponsesApiWebSearchFilters;
|
||||
pub use tool_spec::ResponsesApiWebSearchUserLocation;
|
||||
pub use tool_spec::ToolSpec;
|
||||
|
||||
@@ -58,7 +58,7 @@ pub trait ToolExecutor<Invocation>: Send + Sync {
|
||||
|
||||
fn search_info(&self) -> Option<ToolSearchInfo> {
|
||||
let spec = self.spec();
|
||||
ToolSearchInfo::from_tool_spec(&self.tool_name(), spec, /*source_info*/ None)
|
||||
ToolSearchInfo::from_tool_spec(spec, /*source_info*/ None)
|
||||
}
|
||||
|
||||
fn supports_parallel_tool_calls(&self) -> bool {
|
||||
|
||||
@@ -2,7 +2,6 @@ use crate::JsonSchema;
|
||||
use crate::LoadableToolSpec;
|
||||
use crate::ResponsesApiNamespaceTool;
|
||||
use crate::ResponsesApiTool;
|
||||
use crate::ToolName;
|
||||
use crate::ToolSearchSourceInfo;
|
||||
use crate::ToolSpec;
|
||||
use crate::default_namespace_description;
|
||||
@@ -21,11 +20,10 @@ pub struct ToolSearchInfo {
|
||||
|
||||
impl ToolSearchInfo {
|
||||
pub fn from_tool_spec(
|
||||
tool_name: &ToolName,
|
||||
spec: ToolSpec,
|
||||
source_info: Option<ToolSearchSourceInfo>,
|
||||
) -> Option<Self> {
|
||||
let search_text = default_tool_search_text(tool_name, &spec);
|
||||
let search_text = default_tool_search_text(&spec);
|
||||
Self::from_spec(search_text, spec, source_info)
|
||||
}
|
||||
|
||||
@@ -67,13 +65,8 @@ impl ToolSearchInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_tool_search_text(tool_name: &ToolName, spec: &ToolSpec) -> String {
|
||||
fn default_tool_search_text(spec: &ToolSpec) -> String {
|
||||
let mut parts = Vec::new();
|
||||
push_search_part(&mut parts, tool_name.to_string());
|
||||
push_search_part(&mut parts, tool_name.name.replace('_', " "));
|
||||
if let Some(namespace) = &tool_name.namespace {
|
||||
push_search_part(&mut parts, namespace.clone());
|
||||
}
|
||||
|
||||
match spec {
|
||||
ToolSpec::Function(tool) => append_function_search_text(tool, &mut parts),
|
||||
@@ -137,3 +130,7 @@ fn push_search_part(parts: &mut Vec<String>, part: String) {
|
||||
parts.push(part.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "tool_search_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[test]
|
||||
fn default_search_text_uses_model_visible_namespace_metadata_once() {
|
||||
let mut schedule_schema = JsonSchema::object(
|
||||
BTreeMap::from([(
|
||||
"timezone".to_string(),
|
||||
JsonSchema::string(Some("IANA timezone.".to_string())),
|
||||
)]),
|
||||
/*required*/ None,
|
||||
/*additional_properties*/ None,
|
||||
);
|
||||
schedule_schema.description = Some("Schedule settings.".to_string());
|
||||
let mut parameters = JsonSchema::object(
|
||||
BTreeMap::from([
|
||||
(
|
||||
"mode".to_string(),
|
||||
JsonSchema::string(Some("Update mode.".to_string())),
|
||||
),
|
||||
("schedule".to_string(), schedule_schema),
|
||||
]),
|
||||
/*required*/ None,
|
||||
/*additional_properties*/ None,
|
||||
);
|
||||
parameters.description = Some("Automation options.".to_string());
|
||||
let spec = ToolSpec::Namespace(crate::ResponsesApiNamespace {
|
||||
name: "codex_app".to_string(),
|
||||
description: "Manage Codex automations.".to_string(),
|
||||
tools: vec![ResponsesApiNamespaceTool::Function(ResponsesApiTool {
|
||||
name: "automation_update".to_string(),
|
||||
description: "Create or update automations.".to_string(),
|
||||
strict: false,
|
||||
defer_loading: None,
|
||||
parameters,
|
||||
output_schema: None,
|
||||
})],
|
||||
});
|
||||
|
||||
let search_info = ToolSearchInfo::from_tool_spec(spec, /*source_info*/ None)
|
||||
.expect("namespace should be searchable");
|
||||
|
||||
assert_eq!(
|
||||
search_info.entry.search_text,
|
||||
"codex_app Manage Codex automations. automation_update automation update Create or update automations. Automation options. mode Update mode. schedule Schedule settings. timezone IANA timezone."
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user