use echo_agent::a2a::*;
use echo_agent::prelude::*;
use futures::StreamExt;
use std::sync::Arc;
#[tokio::main]
async fn main() -> echo_agent::error::Result<()> {
dotenvy::dotenv().ok();
tracing_subscriber::fmt().with_env_filter("info").init();
println!("=== A2A 协议示例 ===\n");
println!("--- 1. 构建 Agent Card ---\n");
let card = AgentCard::builder("echo-translator", "http://localhost:8080")
.description("多语言翻译 Agent,支持中英文互译")
.version("1.0.0")
.provider(AgentProvider::new("Echo Team").with_url("https://example.com"))
.skill(
AgentSkill::new("translate", "翻译文本")
.with_tags(vec!["nlp", "translation"])
.with_examples(vec!["翻译'你好'为英文", "Translate 'hello' to Chinese"]),
)
.skill(AgentSkill::new("detect_language", "检测文本语言"))
.streaming()
.build();
println!("Agent Card JSON:");
println!("{}\n", serde_json::to_string_pretty(&card).unwrap());
println!("--- 2. 从 Agent 自动生成 Card ---\n");
let agent = ReactAgentBuilder::new()
.model("qwen3-max")
.name("math_agent")
.system_prompt("你是一个数学计算助手")
.enable_tools()
.build()?;
let auto_card = AgentCard::from_agent(&agent, "http://localhost:9090");
println!("自动生成的 Agent Card:");
println!(" 名称: {}", auto_card.name);
println!(" 技能数: {}", auto_card.skills.len());
for skill in &auto_card.skills {
println!(" - {}: {:?}", skill.name, skill.description);
}
println!("\n--- 3. 任务状态机 ---\n");
println!("TaskState 状态转换:");
let transitions = [
(TaskState::Submitted, TaskState::Working),
(TaskState::Working, TaskState::Completed),
(TaskState::Working, TaskState::Failed),
(TaskState::Working, TaskState::InputRequired),
(TaskState::InputRequired, TaskState::Working),
(TaskState::Completed, TaskState::Working),
];
for (from, to) in &transitions {
let ok = from.can_transition_to(*to);
println!(" {} → {} : {}", from, to, if ok { "✅" } else { "❌" });
}
println!("\n终态检查:");
for state in [
TaskState::Submitted,
TaskState::Working,
TaskState::Completed,
TaskState::Failed,
TaskState::Canceled,
] {
println!(" {} : terminal={}", state, state.is_terminal());
}
println!("\n--- 4. A2A Server 处理请求 ---\n");
let server_agent = ReactAgentBuilder::new()
.model("qwen3-max")
.name("a2a_agent")
.system_prompt("你是一个通过 A2A 协议提供服务的助手")
.build()?;
let server = Arc::new(A2AServer::new(card.clone(), server_agent));
println!("Agent Card: {}\n", server.agent_card().name);
let request = serde_json::json!({
"jsonrpc": "2.0",
"id": "req-001",
"method": "tasks/send",
"params": {
"message": {
"role": "user",
"parts": [{"type": "text", "text": "你好,请介绍一下自己"}]
}
}
});
println!(
"发送请求: {}",
serde_json::to_string_pretty(&request).unwrap()
);
let response = server.handle_request(&request.to_string()).await;
let response_json: serde_json::Value = serde_json::from_str(&response)?;
if response_json.get("result").is_none() {
return Err(echo_agent::error::ReactError::Other(
"demo23 验收失败:A2A 同步请求未返回 result".to_string(),
));
}
println!("\n响应: {}\n", response);
println!("--- 5. 流式任务 (tasks/sendSubscribe) ---\n");
let stream_request = serde_json::json!({
"jsonrpc": "2.0",
"id": "req-002",
"method": "tasks/sendSubscribe",
"params": {
"message": {
"role": "user",
"parts": [{"type": "text", "text": "简单介绍 Rust 语言"}]
}
}
});
let mut event_stream = server
.handle_request_stream(&stream_request.to_string())
.await?;
let mut saw_final = false;
let mut artifact_updates = 0usize;
while let Some(event) = event_stream.next().await {
match &event {
A2AStreamEvent::StatusUpdate(e) => {
println!("[状态] {} (final={})", e.status.state, e.is_final);
if e.is_final {
saw_final = true;
break;
}
}
A2AStreamEvent::ArtifactUpdate(e) => {
artifact_updates += 1;
let text: String = e
.artifact
.parts
.iter()
.filter_map(|p| match p {
A2APart::Text { text } => Some(text.as_str()),
_ => None,
})
.collect();
let label = if e.artifact.append {
"追加"
} else {
"新建"
};
println!(
"[产出 #{} {}] {}",
e.artifact.index.unwrap_or(0),
label,
text
);
}
}
}
if !saw_final && artifact_updates == 0 {
return Err(echo_agent::error::ReactError::Other(
"demo23 验收失败:A2A 流式请求既没有终态也没有任何产出".to_string(),
));
}
println!("\n--- 6. A2A Client(演示 API)---\n");
let _client = A2AClient::new();
println!("A2AClient 已创建,可用方法:");
println!(" - discover(url): 发现远程 Agent");
println!(" - send_task(url, message): 同步发送任务");
println!(" - send_task_streaming(url, message): 流式发送任务");
println!(" - get_task(url, task_id): 查询任务状态");
println!(" - cancel_task(url, task_id): 取消任务");
println!("\n=== A2A 协议示例完成 ===");
Ok(())
}