use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use super::agent_card::AgentCard;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct GetExtendedAgentCardRequest {
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub metadata: BTreeMap<String, serde_json::Value>,
}
impl GetExtendedAgentCardRequest {
#[must_use]
pub const fn new() -> Self {
Self {
metadata: BTreeMap::new(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct GetExtendedAgentCardResponse(pub AgentCard);
impl From<AgentCard> for GetExtendedAgentCardResponse {
fn from(card: AgentCard) -> Self {
Self(card)
}
}
impl std::ops::Deref for GetExtendedAgentCardResponse {
type Target = AgentCard;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::{GetExtendedAgentCardRequest, GetExtendedAgentCardResponse};
use crate::domain::a2a::agent_card::AgentCardBuilder;
type TestError = Box<dyn std::error::Error>;
#[test]
fn request_serialises_as_empty_object() -> Result<(), TestError> {
let request = GetExtendedAgentCardRequest::new();
let value = serde_json::to_value(&request)?;
let obj = value
.as_object()
.ok_or("a GetExtendedAgentCardRequest must serialise to a JSON object")?;
assert!(obj.is_empty(), "expected `{{}}`, got {value}");
Ok(())
}
#[test]
fn response_serialises_as_card_object() -> Result<(), TestError> {
let interface = crate::domain::a2a::agent_card::AgentInterface {
url: url::Url::parse("https://example.com/a2a/v1")
.map_err(|e| -> Box<dyn std::error::Error> { Box::new(e) })?,
protocol_binding: crate::domain::a2a::agent_card::JSONRPC.clone(),
protocol_version: crate::domain::a2a::A2aVersion::V1_0,
tenant: None,
};
let card = AgentCardBuilder::new()
.with_name("test-agent")
.with_description("An A2A test agent.")
.with_version("0.1.0")
.with_interface(interface)
.with_input_mode("text/plain")
.with_output_mode("text/plain")
.build()
.map_err(|e| -> Box<dyn std::error::Error> { Box::new(e) })?;
let response = GetExtendedAgentCardResponse::from(card);
let value = serde_json::to_value(&response)?;
let obj = value
.as_object()
.ok_or("a GetExtendedAgentCardResponse must serialise to a JSON object")?;
assert_eq!(
obj.get("name").and_then(serde_json::Value::as_str),
Some("test-agent")
);
Ok(())
}
#[test]
fn response_from_card_via_into_works() -> Result<(), TestError> {
let interface = crate::domain::a2a::agent_card::AgentInterface {
url: url::Url::parse("https://example.com/a2a/v1")
.map_err(|e| -> Box<dyn std::error::Error> { Box::new(e) })?,
protocol_binding: crate::domain::a2a::agent_card::JSONRPC.clone(),
protocol_version: crate::domain::a2a::A2aVersion::V1_0,
tenant: None,
};
let card = AgentCardBuilder::new()
.with_name("test-agent")
.with_description("An A2A test agent.")
.with_version("0.1.0")
.with_interface(interface)
.with_input_mode("text/plain")
.with_output_mode("text/plain")
.build()
.map_err(|e| -> Box<dyn std::error::Error> { Box::new(e) })?;
let response: GetExtendedAgentCardResponse = card.clone().into();
assert_eq!(response.0, card);
Ok(())
}
}