1use async_trait::async_trait;
4use rucora_core::error::ToolError;
5use rucora_core::tool::{Tool, ToolCategory};
6use serde_json::Value;
7use std::sync::Arc;
8
9pub use ra2a::{client, server};
11
12pub mod types {
14 pub use ra2a::types::*;
15}
16
17pub mod protocol;
19
20pub mod transport;
22
23pub 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}