use std::sync::OnceLock;
use crate::tools::handlers::PlanningWorkflowState;
use vtcode_config::{WebFetchConfig, WebSearchConfig};
use super::registration::ToolRegistration;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ToolConfigSnapshot {
pub web_search: WebSearchConfig,
pub web_fetch: WebFetchConfig,
}
static TOOL_CONFIG: OnceLock<ToolConfigSnapshot> = OnceLock::new();
pub fn install_tool_config(snapshot: ToolConfigSnapshot) {
match TOOL_CONFIG.set(snapshot) {
Ok(()) => {}
Err(new) => {
let existing = TOOL_CONFIG.get().expect("set failed; lock should be initialized");
if existing != &new {
panic!(
"install_tool_config called with a different snapshot; \
first install and second install disagree on the user config"
);
}
}
}
}
pub fn tool_config() -> Option<&'static ToolConfigSnapshot> {
TOOL_CONFIG.get()
}
#[allow(dead_code)]
pub type BuiltinToolFactory = fn(Option<&PlanningWorkflowState>) -> ToolRegistration;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn install_tool_config_re_install_with_same_snapshot_is_a_noop() {
install_tool_config(ToolConfigSnapshot::default());
}
#[test]
#[should_panic(expected = "install_tool_config called with a different snapshot")]
fn install_tool_config_panics_on_diverging_snapshot() {
let divergent = ToolConfigSnapshot {
web_search: WebSearchConfig { max_results: 999, ..WebSearchConfig::default() },
..ToolConfigSnapshot::default()
};
install_tool_config(ToolConfigSnapshot::default());
install_tool_config(divergent);
}
}
#[linkme::distributed_slice]
pub static BUILTIN_TOOLS: [BuiltinToolFactory] = [..];