systemprompt_models/a2a/
message.rs1use serde::{Deserialize, Serialize};
2use systemprompt_identifiers::{ContextId, MessageId, TaskId};
3
4#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
5#[serde(rename_all = "camelCase")]
6#[allow(clippy::struct_field_names)]
7pub struct Message {
8 pub role: MessageRole,
9 pub parts: Vec<Part>,
10 pub message_id: MessageId,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub task_id: Option<TaskId>,
13 pub context_id: ContextId,
14 pub metadata: Option<serde_json::Value>,
15 pub extensions: Option<Vec<String>>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub reference_task_ids: Option<Vec<TaskId>>,
18}
19
20#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
21pub enum MessageRole {
22 #[serde(rename = "ROLE_USER")]
23 User,
24 #[serde(rename = "ROLE_AGENT")]
25 Agent,
26}
27
28#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
29#[serde(untagged)]
30pub enum Part {
31 Text(TextPart),
32 File(FilePart),
33 Data(DataPart),
34}
35
36#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
37pub struct TextPart {
38 pub text: String,
39}
40
41#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
42pub struct DataPart {
43 pub data: serde_json::Map<String, serde_json::Value>,
44}
45
46#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
47pub struct FilePart {
48 pub file: FileContent,
49}
50
51#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
52#[serde(rename_all = "camelCase")]
53pub struct FileContent {
54 pub name: Option<String>,
55 pub mime_type: Option<String>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub bytes: Option<String>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub url: Option<String>,
60}
61
62impl Part {
63 pub fn as_text(&self) -> Option<&str> {
64 match self {
65 Self::Text(text_part) => Some(&text_part.text),
66 _ => None,
67 }
68 }
69
70 pub fn as_data(&self) -> Option<serde_json::Value> {
71 match self {
72 Self::Data(data_part) => Some(serde_json::Value::Object(data_part.data.clone())),
73 _ => None,
74 }
75 }
76
77 pub fn as_file(&self) -> Option<serde_json::Value> {
78 match self {
79 Self::File(file_part) => serde_json::to_value(&file_part.file).ok(),
80 _ => None,
81 }
82 }
83}