systemprompt_models/events/
a2a_event.rs1use chrono::{DateTime, Utc};
12use serde::{Deserialize, Serialize};
13use systemprompt_identifiers::{ContextId, MessageId, TaskId};
14
15use super::a2a_event_type::A2AEventType;
16use super::payloads::a2a::{
17 AgentMessagePayload, ArtifactCreatedPayload, ArtifactUpdatedPayload, AuthRequiredPayload,
18 InputRequiredPayload, JsonRpcErrorPayload, JsonRpcResponsePayload, TaskStatusUpdatePayload,
19 TaskSubmittedPayload,
20};
21use crate::a2a::{Artifact, TaskState};
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24#[serde(tag = "type", rename_all = "SCREAMING_SNAKE_CASE")]
25pub enum A2AEvent {
26 TaskSubmitted {
27 timestamp: DateTime<Utc>,
28 #[serde(flatten)]
29 payload: TaskSubmittedPayload,
30 },
31 TaskStatusUpdate {
32 timestamp: DateTime<Utc>,
33 #[serde(flatten)]
34 payload: TaskStatusUpdatePayload,
35 },
36 ArtifactCreated {
37 timestamp: DateTime<Utc>,
38 #[serde(flatten)]
39 payload: Box<ArtifactCreatedPayload>,
40 },
41 ArtifactUpdated {
42 timestamp: DateTime<Utc>,
43 #[serde(flatten)]
44 payload: ArtifactUpdatedPayload,
45 },
46 AgentMessage {
47 timestamp: DateTime<Utc>,
48 #[serde(flatten)]
49 payload: AgentMessagePayload,
50 },
51 InputRequired {
52 timestamp: DateTime<Utc>,
53 #[serde(flatten)]
54 payload: InputRequiredPayload,
55 },
56 AuthRequired {
57 timestamp: DateTime<Utc>,
58 #[serde(flatten)]
59 payload: AuthRequiredPayload,
60 },
61 JsonRpcResponse {
62 timestamp: DateTime<Utc>,
63 #[serde(flatten)]
64 payload: JsonRpcResponsePayload,
65 },
66 JsonRpcError {
67 timestamp: DateTime<Utc>,
68 #[serde(flatten)]
69 payload: JsonRpcErrorPayload,
70 },
71}
72
73impl A2AEvent {
74 pub const fn event_type(&self) -> A2AEventType {
75 match self {
76 Self::TaskSubmitted { .. } => A2AEventType::TaskSubmitted,
77 Self::TaskStatusUpdate { .. } => A2AEventType::TaskStatusUpdate,
78 Self::ArtifactCreated { .. } => A2AEventType::ArtifactCreated,
79 Self::ArtifactUpdated { .. } => A2AEventType::ArtifactUpdated,
80 Self::AgentMessage { .. } => A2AEventType::AgentMessage,
81 Self::InputRequired { .. } => A2AEventType::InputRequired,
82 Self::AuthRequired { .. } => A2AEventType::AuthRequired,
83 Self::JsonRpcResponse { .. } => A2AEventType::JsonRpcResponse,
84 Self::JsonRpcError { .. } => A2AEventType::JsonRpcError,
85 }
86 }
87
88 pub const fn timestamp(&self) -> DateTime<Utc> {
89 match self {
90 Self::TaskSubmitted { timestamp, .. }
91 | Self::TaskStatusUpdate { timestamp, .. }
92 | Self::ArtifactCreated { timestamp, .. }
93 | Self::ArtifactUpdated { timestamp, .. }
94 | Self::AgentMessage { timestamp, .. }
95 | Self::InputRequired { timestamp, .. }
96 | Self::AuthRequired { timestamp, .. }
97 | Self::JsonRpcResponse { timestamp, .. }
98 | Self::JsonRpcError { timestamp, .. } => *timestamp,
99 }
100 }
101}
102
103#[derive(Debug, Clone, Copy)]
104pub struct A2AEventBuilder;
105
106impl A2AEventBuilder {
107 pub fn task_submitted(
108 task_id: TaskId,
109 context_id: ContextId,
110 agent_name: String,
111 input: Option<serde_json::Value>,
113 ) -> A2AEvent {
114 A2AEvent::TaskSubmitted {
115 timestamp: Utc::now(),
116 payload: TaskSubmittedPayload {
117 task_id,
118 context_id,
119 agent_name,
120 input,
121 },
122 }
123 }
124
125 pub fn task_status_update(
126 task_id: TaskId,
127 context_id: ContextId,
128 state: TaskState,
129 message: Option<String>,
130 ) -> A2AEvent {
131 A2AEvent::TaskStatusUpdate {
132 timestamp: Utc::now(),
133 payload: TaskStatusUpdatePayload {
134 task_id,
135 context_id,
136 state,
137 message,
138 },
139 }
140 }
141
142 pub fn artifact_created(
143 task_id: TaskId,
144 context_id: ContextId,
145 artifact: Artifact,
146 ) -> A2AEvent {
147 A2AEvent::ArtifactCreated {
148 timestamp: Utc::now(),
149 payload: Box::new(ArtifactCreatedPayload {
150 task_id,
151 context_id,
152 artifact,
153 }),
154 }
155 }
156
157 pub fn agent_message(
158 task_id: TaskId,
159 context_id: ContextId,
160 message_id: MessageId,
161 content: String,
162 ) -> A2AEvent {
163 A2AEvent::AgentMessage {
164 timestamp: Utc::now(),
165 payload: AgentMessagePayload {
166 task_id,
167 context_id,
168 message_id,
169 content,
170 },
171 }
172 }
173
174 pub fn input_required(task_id: TaskId, context_id: ContextId, prompt: String) -> A2AEvent {
175 A2AEvent::InputRequired {
176 timestamp: Utc::now(),
177 payload: InputRequiredPayload {
178 task_id,
179 context_id,
180 prompt,
181 },
182 }
183 }
184
185 pub fn auth_required(task_id: TaskId, context_id: ContextId, auth_url: String) -> A2AEvent {
186 A2AEvent::AuthRequired {
187 timestamp: Utc::now(),
188 payload: AuthRequiredPayload {
189 task_id,
190 context_id,
191 auth_url,
192 },
193 }
194 }
195
196 pub fn json_rpc_response(id: serde_json::Value, result: serde_json::Value) -> A2AEvent {
198 A2AEvent::JsonRpcResponse {
199 timestamp: Utc::now(),
200 payload: JsonRpcResponsePayload { id, result },
201 }
202 }
203}