a2a_client/components/
task_viewer.rs1use a2a_rs::domain::{Part as MessagePart, Task};
4use serde::Serialize;
5
6#[derive(Debug, Serialize, Clone)]
8pub struct TaskView {
9 pub task_id: String,
10 pub state: String,
11 pub message_count: usize,
12 pub last_message_preview: Option<String>,
13}
14
15impl TaskView {
16 pub fn from_task(task: Task) -> Self {
18 let message_count = task.history.as_ref().map(|h| h.len()).unwrap_or(0);
19 let last_message_preview = task.history.as_ref().and_then(|h| {
20 h.last().and_then(|msg| {
21 msg.parts.iter().find_map(|part| match part {
22 MessagePart::Text { text, .. } => {
23 Some(text.chars().take(100).collect::<String>())
24 }
25 _ => None,
26 })
27 })
28 });
29
30 Self {
31 task_id: task.id,
32 state: format!("{:?}", task.status.state),
33 message_count,
34 last_message_preview,
35 }
36 }
37}
38
39#[derive(Debug, Serialize, Clone)]
41pub struct MessageView {
42 pub id: String,
43 pub role: String,
44 pub content: String,
45}
46
47impl MessageView {
48 pub fn from_message(msg: a2a_rs::domain::Message) -> Self {
50 let content = msg
52 .parts
53 .iter()
54 .map(|part| match part {
55 MessagePart::Text { text, .. } => text.clone(),
56 MessagePart::File { file, .. } => format!(
57 "[File: {}]",
58 file.name.as_ref().unwrap_or(&"unnamed".to_string())
59 ),
60 MessagePart::Data { data, .. } => {
61 let name = data
62 .get("name")
63 .and_then(|v| v.as_str())
64 .unwrap_or("unnamed");
65 format!("[Data: {}]", name)
66 }
67 })
68 .collect::<Vec<_>>()
69 .join("\n");
70
71 Self {
72 id: msg.message_id,
73 role: format!("{:?}", msg.role),
74 content,
75 }
76 }
77
78 pub fn from_message_with_json_parsing(msg: a2a_rs::domain::Message) -> Self {
80 let content = msg
81 .parts
82 .iter()
83 .filter_map(|part| match part {
84 MessagePart::Text { text, .. } => Some(text.clone()),
85 _ => None,
86 })
87 .collect::<Vec<_>>()
88 .join("\n");
89
90 let display_content =
92 if let Ok(json_value) = serde_json::from_str::<serde_json::Value>(&content) {
93 if let Some(obj) = json_value.as_object() {
94 match obj.get("type").and_then(|v| v.as_str()) {
95 Some("form") => obj
96 .get("instructions")
97 .and_then(|v| v.as_str())
98 .unwrap_or("Please fill out the form.")
99 .to_string(),
100 Some("result") => {
101 let message = obj
102 .get("message")
103 .and_then(|v| v.as_str())
104 .unwrap_or("Request processed.");
105 let status = obj
106 .get("status")
107 .and_then(|v| v.as_str())
108 .unwrap_or("unknown");
109 format!("{}\n\nStatus: {}", message, status)
110 }
111 _ => serde_json::to_string_pretty(&json_value).unwrap_or(content.clone()),
112 }
113 } else {
114 content.clone()
115 }
116 } else {
117 content.clone()
118 };
119
120 Self {
121 id: msg.message_id,
122 role: format!("{:?}", msg.role),
123 content: display_content,
124 }
125 }
126}