use super::*;
#[derive(Debug, Clone)]
pub(super) struct ToolRequestConfiguration {
pub(super) disabled_tool_names: HashSet<String>,
pub(super) subagents_tool_enabled: bool,
pub(super) dynamic_tool_definitions: Vec<serde_json::Value>,
pub(super) resolved_catalog: Option<Vec<serde_json::Value>>,
pub(super) advertised_tool_names: HashSet<String>,
}
fn disabled_tool_names_for_request(tools: Option<&ToolRuntime>) -> HashSet<String> {
let Some(tools) = tools else {
return Default::default();
};
tools.disabled_tool_names().unwrap_or_else(|_| {
crate::tools::MVP_TOOL_CAPABILITIES
.iter()
.map(|tool| tool.canonical_name().to_string())
.chain(
tools
.dynamic_provider_tool_definitions()
.into_iter()
.filter_map(|definition| {
definition
.get("name")
.and_then(serde_json::Value::as_str)
.map(str::to_string)
}),
)
.collect()
})
}
pub(super) fn tool_request_configuration(tools: Option<&ToolRuntime>) -> ToolRequestConfiguration {
if let Some(runtime) =
tools.filter(|runtime| crate::code_mode::catalog::code_mode_available(runtime))
{
use crate::code_mode::catalog::{ToolCatalogSurface, effective_catalog};
let surface = if runtime.code_mode.compact_direct_tools {
ToolCatalogSurface::DirectProviderCompact
} else {
ToolCatalogSurface::DirectProviderFull
};
let definitions = effective_catalog(runtime, surface);
return ToolRequestConfiguration {
disabled_tool_names: disabled_tool_names_for_request(tools),
subagents_tool_enabled: runtime.subagents_schema_enabled(),
advertised_tool_names: definitions
.iter()
.filter_map(|entry| entry["name"].as_str().map(str::to_owned))
.collect(),
dynamic_tool_definitions: Vec::new(),
resolved_catalog: Some(definitions),
};
}
let (disabled_tool_names, subagents_tool_enabled, dynamic_tool_definitions) =
if let Some(tools) = tools {
let disabled_tool_names = disabled_tool_names_for_request(Some(tools));
let dynamic_tool_definitions = tools
.dynamic_provider_tool_definitions()
.into_iter()
.filter(|definition| {
definition
.get("name")
.and_then(serde_json::Value::as_str)
.is_some_and(|name| !disabled_tool_names.contains(name))
})
.collect();
(
disabled_tool_names,
tools.subagents_schema_enabled(),
dynamic_tool_definitions,
)
} else {
(HashSet::new(), true, Vec::new())
};
let mut advertised_tool_names = crate::tools::MVP_TOOL_CAPABILITIES
.iter()
.filter(|tool| {
(subagents_tool_enabled || **tool != crate::tools::ToolCapability::Subagents)
&& !disabled_tool_names.contains(tool.canonical_name())
})
.map(|tool| tool.canonical_name().to_string())
.collect::<HashSet<_>>();
for definition in &dynamic_tool_definitions {
if let Some(name) = definition.get("name").and_then(serde_json::Value::as_str) {
advertised_tool_names.insert(name.to_string());
}
}
ToolRequestConfiguration {
disabled_tool_names,
subagents_tool_enabled,
dynamic_tool_definitions,
resolved_catalog: None,
advertised_tool_names,
}
}