use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentCard {
pub name: String,
pub description: String,
pub url: String,
#[serde(default)]
pub input_content_types: Vec<String>,
#[serde(default)]
pub output_content_types: Vec<String>,
#[serde(default)]
pub skills: Vec<AgentSkill>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentSkill {
pub name: String,
pub description: String,
#[serde(default)]
pub examples: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct RemoteA2aAgentConfig {
pub timeout_secs: u64,
pub full_history_when_stateless: bool,
}
impl Default for RemoteA2aAgentConfig {
fn default() -> Self {
Self {
timeout_secs: 30,
full_history_when_stateless: false,
}
}
}
#[derive(Debug, Clone)]
pub struct RemoteA2aAgent {
name: String,
agent_card: AgentCard,
config: RemoteA2aAgentConfig,
}
impl RemoteA2aAgent {
pub fn new(name: impl Into<String>, agent_card: AgentCard) -> Self {
Self {
name: name.into(),
agent_card,
config: RemoteA2aAgentConfig::default(),
}
}
pub fn with_config(mut self, config: RemoteA2aAgentConfig) -> Self {
self.config = config;
self
}
pub fn name(&self) -> &str {
&self.name
}
pub fn agent_card(&self) -> &AgentCard {
&self.agent_card
}
pub fn url(&self) -> &str {
&self.agent_card.url
}
}
#[cfg(test)]
mod tests {
use super::*;
fn test_card() -> AgentCard {
AgentCard {
name: "remote-helper".into(),
description: "A helpful remote agent".into(),
url: "https://example.com/a2a".into(),
input_content_types: vec!["text/plain".into()],
output_content_types: vec!["text/plain".into()],
skills: vec![AgentSkill {
name: "search".into(),
description: "Search the web".into(),
examples: vec!["Find information about...".into()],
}],
}
}
#[test]
fn create_remote_agent() {
let agent = RemoteA2aAgent::new("helper", test_card());
assert_eq!(agent.name(), "helper");
assert_eq!(agent.url(), "https://example.com/a2a");
}
#[test]
fn agent_card_serde() {
let card = test_card();
let json = serde_json::to_string(&card).unwrap();
let deserialized: AgentCard = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.name, "remote-helper");
assert_eq!(deserialized.skills.len(), 1);
}
#[test]
fn default_config() {
let config = RemoteA2aAgentConfig::default();
assert_eq!(config.timeout_secs, 30);
assert!(!config.full_history_when_stateless);
}
}