use jsonschema::Validator;
use once_cell::sync::OnceCell;
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Mutex;
use crate::types::{Tool, ToolCall};
fn validator(schema: &Value) -> Option<Validator> {
static CACHE: OnceCell<Mutex<HashMap<u64, Validator>>> = OnceCell::new();
let cache = CACHE.get_or_init(|| Mutex::new(HashMap::new()));
let key = {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
schema.to_string().hash(&mut hasher);
hasher.finish()
};
let mut guard = cache.lock().ok()?;
if let std::collections::hash_map::Entry::Vacant(e) = guard.entry(key) {
let compiled = Validator::new(schema).ok()?;
e.insert(compiled);
}
guard.remove(&key)
}
pub fn validate_tool_call(tool: &Tool, call: &ToolCall) -> Result<(), String> {
let Some(schema) = validator(&tool.parameters) else {
return Ok(());
};
if let Err(error) = schema.validate(&call.arguments) {
return Err(error.to_string());
}
Ok(())
}