use crate::platform::container::arsenal::handoff_error::HandoffError;
use crate::platform::container::paladin::Paladin;
use serde_json::{Value, json};
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct HandoffTool {
specialists: Vec<Arc<Paladin>>,
}
impl HandoffTool {
pub fn new(specialists: Vec<Arc<Paladin>>) -> Self {
Self { specialists }
}
pub fn get_schema(&self) -> Value {
let agent_names: Vec<Value> = self
.specialists
.iter()
.map(|p| json!(p.node.name.clone()))
.collect();
json!({
"type": "function",
"function": {
"name": "handoff_to_agent",
"description": "Delegate the current task to a specialist agent",
"parameters": {
"type": "object",
"properties": {
"agent_name": {
"type": "string",
"description": "Name of the specialist agent to delegate to",
"enum": agent_names
},
"message": {
"type": "string",
"description": "Task description and context to pass to the specialist agent"
}
},
"required": ["agent_name", "message"]
}
}
})
}
pub fn validate_parameters(&self, params: &HashMap<String, Value>) -> Result<(), HandoffError> {
let agent_name = params
.get("agent_name")
.and_then(|v| v.as_str())
.ok_or_else(|| {
HandoffError::ConfigurationError(
"Missing or invalid agent_name parameter".to_string(),
)
})?;
let agent_exists = self.specialists.iter().any(|p| p.node.name == agent_name);
if !agent_exists {
return Err(HandoffError::InvalidAgent {
agent_name: agent_name.to_string(),
});
}
let message = params
.get("message")
.and_then(|v| v.as_str())
.ok_or_else(|| {
HandoffError::ConfigurationError("Missing or invalid message parameter".to_string())
})?;
if message.trim().is_empty() {
return Err(HandoffError::ConfigurationError(
"Message parameter cannot be empty".to_string(),
));
}
Ok(())
}
pub fn specialists(&self) -> &Vec<Arc<Paladin>> {
&self.specialists
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_handoff_tool() {
let tool = HandoffTool::new(vec![]);
assert_eq!(tool.specialists().len(), 0);
}
#[test]
fn test_specialists_accessor() {
let tool = HandoffTool::new(vec![]);
let specialists = tool.specialists();
assert_eq!(specialists.len(), 0);
}
}