use crate::error::{Error, Result};
use crate::message::MessageConverter;
use a2a_rs::domain::agent::{AgentCard, Skill};
use rmcp::{Tool, ToolCall, ToolResponse};
use std::collections::HashMap;
use std::sync::Arc;
pub struct AgentToToolAdapter {
converter: Arc<MessageConverter>,
agent_cache: HashMap<String, AgentCard>,
}
impl AgentToToolAdapter {
pub fn new() -> Self {
Self {
converter: Arc::new(MessageConverter::new()),
agent_cache: HashMap::new(),
}
}
pub fn add_agent(&mut self, url: String, card: AgentCard) {
self.agent_cache.insert(url, card);
}
pub fn get_agent(&self, url: &str) -> Option<&AgentCard> {
self.agent_cache.get(url)
}
pub fn generate_tools(&self, agent: &AgentCard, agent_url: &str) -> Vec<Tool> {
agent.skills.iter().map(|skill| {
self.skill_to_tool(skill, agent, agent_url)
}).collect()
}
fn skill_to_tool(&self, skill: &Skill, agent: &AgentCard, agent_url: &str) -> Tool {
let tool_name = format!("{}:{}", agent_url, skill.name);
Tool {
name: tool_name,
description: format!("{} - {}", agent.description, skill.description),
parameters: None, }
}
pub fn tool_call_to_task(&self, call: &ToolCall, agent_card: &AgentCard, method: &str) -> Result<a2a_rs::domain::task::Task> {
let message = self.converter.tool_call_to_message(call)?;
Ok(a2a_rs::domain::task::Task {
id: uuid::Uuid::new_v4().to_string(),
status: a2a_rs::domain::task::TaskStatus {
state: a2a_rs::domain::task::TaskState::Submitted,
message: Some("Task submitted from RMCP tool call".to_string()),
},
messages: vec![message],
artifacts: Vec::new(),
history_ttl: Some(3600), metadata: Some(serde_json::json!({
"skill": method,
"agent": agent_card.name.clone(),
})),
})
}
pub fn task_to_tool_response(&self, task: &a2a_rs::domain::task::Task) -> Result<ToolResponse> {
let agent_message = self.converter.extract_agent_message(task)?;
self.converter.message_to_tool_response(agent_message)
}
pub fn parse_tool_method(&self, tool_method: &str) -> Result<(String, String)> {
let parts: Vec<&str> = tool_method.splitn(2, ':').collect();
if parts.len() != 2 {
return Err(Error::InvalidToolMethod(tool_method.to_string()));
}
Ok((parts[0].to_string(), parts[1].to_string()))
}
}