use super::tool::Tool;
use crate::types::TaskContext;
#[derive(Debug, Clone)]
pub struct CompatibilityResult {
pub overall_score: f32,
pub historical_success_rate: f32,
pub context_compatibility: f32,
pub capability_match: f32,
}
pub fn analyze_capability_match(tool: &Tool, context: &TaskContext) -> f32 {
if tool.capabilities.is_empty() {
return 0.5; }
let expected_capabilities = get_expected_capabilities_for_context(context);
if expected_capabilities.is_empty() {
return 1.0; }
let mut matched_capabilities = 0;
for capability in &tool.capabilities {
if expected_capabilities.contains(capability) {
matched_capabilities += 1;
}
}
for tool_cap in &tool.capabilities {
for expected_cap in &expected_capabilities {
if tool_cap.contains(expected_cap) || expected_cap.contains(tool_cap) {
matched_capabilities += 1;
break; }
}
}
let match_ratio = matched_capabilities as f32 / expected_capabilities.len() as f32;
let domain_bonus = match context.domain.as_str() {
"api_development" => {
if tool
.capabilities
.iter()
.any(|c| c.contains("rust") || c.contains("compiler"))
{
0.2
} else {
0.0
}
}
_ => 0.0,
};
(match_ratio + domain_bonus).min(1.0)
}
pub fn get_expected_capabilities_for_context(context: &TaskContext) -> Vec<String> {
let mut capabilities = Vec::new();
match context.domain.as_str() {
"api_development" => {
capabilities.extend(vec!["http_client".to_string(), "json_parser".to_string()]);
}
"data_processing" => {
capabilities.extend(vec!["file_reader".to_string(), "data_analyzer".to_string()]);
}
"debugging" => {
capabilities.extend(vec!["error_analyzer".to_string(), "log_viewer".to_string()]);
}
"testing" => {
capabilities.extend(vec![
"test_runner".to_string(),
"assertion_checker".to_string(),
]);
}
_ => {
capabilities.push("general_processor".to_string());
}
}
if let Some(lang) = &context.language {
capabilities.push(format!("{lang}_compiler"));
capabilities.push(format!("{lang}_linter"));
}
if let Some(framework) = &context.framework {
capabilities.push(format!("{framework}_integration"));
}
capabilities
}