Skip to main content

rucora_a2a/
lib.rs

1//! rucora-a2a - A2A(Agent-to-Agent)协议支持
2
3use async_trait::async_trait;
4use rucora_core::error::ToolError;
5use rucora_core::tool::{Tool, ToolCategory};
6use serde_json::Value;
7use std::sync::Arc;
8
9// 重新导出 ra2a 的客户端和服务器
10pub use ra2a::{client, server};
11
12/// A2A 协议核心数据结构
13pub mod types {
14    pub use ra2a::types::*;
15}
16
17/// A2A 协议模型定义
18pub mod protocol;
19
20/// A2A 传输层
21pub mod transport;
22
23/// A2A 工具适配器
24pub struct A2AToolAdapter {
25    name: String,
26    description: String,
27    parameters: Value,
28    client: Arc<ra2a::client::Client>,
29}
30
31impl A2AToolAdapter {
32    pub fn new(
33        name: String,
34        description: String,
35        parameters: Value,
36        client: ra2a::client::Client,
37    ) -> Self {
38        Self {
39            name,
40            description,
41            parameters,
42            client: Arc::new(client),
43        }
44    }
45}
46
47#[async_trait]
48impl Tool for A2AToolAdapter {
49    fn name(&self) -> &str {
50        &self.name
51    }
52
53    fn description(&self) -> Option<&str> {
54        Some(&self.description)
55    }
56
57    fn categories(&self) -> &'static [ToolCategory] {
58        &[ToolCategory::External]
59    }
60
61    fn input_schema(&self) -> Value {
62        self.parameters.clone()
63    }
64
65    async fn call(&self, input: Value) -> Result<Value, ToolError> {
66        use ra2a::types::{Message, Part, SendMessageRequest};
67
68        let message_text = input.get("message").and_then(|v| v.as_str()).unwrap_or("");
69
70        let msg = Message::user(vec![Part::text(message_text.to_string())]);
71        let req = SendMessageRequest::new(msg);
72
73        let result = self
74            .client
75            .send_message(&req)
76            .await
77            .map_err(|e| ToolError::Message(format!("A2A 调用失败:{e}")))?;
78
79        let result_json = serde_json::to_value(&result)
80            .map_err(|e| ToolError::Message(format!("序列化失败:{e}")))?;
81
82        let response = result_json
83            .get("result")
84            .or_else(|| result_json.get("status"))
85            .or_else(|| result_json.get("message"))
86            .and_then(|v| v.get("message"))
87            .or_else(|| result_json.get("message"))
88            .and_then(|m| m.get("parts"))
89            .and_then(|parts| parts.as_array())
90            .and_then(|arr| arr.first())
91            .and_then(|p| p.get("text"))
92            .and_then(|t| t.as_str())
93            .unwrap_or("无响应")
94            .to_string();
95
96        Ok(serde_json::json!({ "response": response }))
97    }
98}