use crate::tools::Tool;
use std::boxed::Box;
use serde_json::Value;
use std::collections::HashMap;
use crate::agents::{AgentOutput, AgentAction, AgentFinish};
pub fn find_matching_tool_index(tools: &[Box<dyn Tool + Send + Sync>], requested_tool: &str) -> Option<String> {
if let Some(tool) = tools.iter().find(|t| {
t.name() == requested_tool
}) {
return Some(tool.name().to_string());
}
let requested_lower = requested_tool.to_lowercase();
for tool in tools {
let tool_name_lower = tool.name().to_lowercase();
if tool_name_lower.contains(&requested_lower) || requested_lower.contains(&tool_name_lower) {
return Some(tool.name().to_string());
}
}
if requested_lower.contains("weather") || requested_lower.contains("天气") {
if let Some(tool) = tools.iter().find(|t| t.name().to_lowercase().contains("weather") || t.name().to_lowercase().contains("天气")) {
return Some(tool.name().to_string());
}
}
let has_calc_keywords = requested_lower.contains("calculate") || requested_lower.contains("计算") ||
requested_lower.contains("plus") || requested_lower.contains("minus") ||
requested_lower.contains("times") || requested_lower.contains("divided");
let has_math_operators = requested_lower.contains("+") || requested_lower.contains("-") ||
requested_lower.contains("*") || requested_lower.contains("/") ||
requested_lower.contains("plus") || requested_lower.contains("minus") ||
requested_lower.contains("times") || requested_lower.contains("divided");
if has_calc_keywords && has_math_operators {
if let Some(tool) = tools.iter().find(|t| t.name().to_lowercase().contains("calculate") || t.name().to_lowercase().contains("计算")) {
return Some(tool.name().to_string());
}
}
None
}
pub fn parse_model_output(content: &str) -> Result<AgentOutput, anyhow::Error> {
if let Ok(value) = serde_json::from_str::<Value>(content) {
if let Some(call_tool) = value.get("call_tool") {
if let Some(tool_name) = call_tool.get("name") {
let tool_name = tool_name.as_str().unwrap_or("unknown").to_string();
let parameters = call_tool.get("parameters").cloned().unwrap_or(Value::Object(serde_json::Map::new()));
let tool_input = parameters.to_string();
return Ok(AgentOutput::Action(AgentAction {
tool: tool_name,
tool_input,
log: "Call tool".to_string(),
thought: Some("Call tool based on model output".to_string()),
}));
}
}
if let Some(content_value) = value.get("content") {
let content_text = content_value.as_str().unwrap_or("").to_string();
let mut return_values = HashMap::new();
return_values.insert("answer".to_string(), content_text);
return Ok(AgentOutput::Finish(AgentFinish {
return_values,
}));
}
}
Err(anyhow::anyhow!("Failed to parse model output"))
}