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>,
112 ) -> A2AEvent {
113 A2AEvent::TaskSubmitted {
114 timestamp: Utc::now(),
115 payload: TaskSubmittedPayload {
116 task_id,
117 context_id,
118 agent_name,
119 input,
120 },
121 }
122 }
123
124 pub fn task_status_update(
125 task_id: TaskId,
126 context_id: ContextId,
127 state: TaskState,
128 message: Option<String>,
129 ) -> A2AEvent {
130 A2AEvent::TaskStatusUpdate {
131 timestamp: Utc::now(),
132 payload: TaskStatusUpdatePayload {
133 task_id,
134 context_id,
135 state,
136 message,
137 },
138 }
139 }
140
141 pub fn artifact_created(
142 task_id: TaskId,
143 context_id: ContextId,
144 artifact: Artifact,
145 ) -> A2AEvent {
146 A2AEvent::ArtifactCreated {
147 timestamp: Utc::now(),
148 payload: Box::new(ArtifactCreatedPayload {
149 task_id,
150 context_id,
151 artifact,
152 }),
153 }
154 }
155
156 pub fn agent_message(
157 task_id: TaskId,
158 context_id: ContextId,
159 message_id: MessageId,
160 content: String,
161 ) -> A2AEvent {
162 A2AEvent::AgentMessage {
163 timestamp: Utc::now(),
164 payload: AgentMessagePayload {
165 task_id,
166 context_id,
167 message_id,
168 content,
169 },
170 }
171 }
172
173 pub fn input_required(task_id: TaskId, context_id: ContextId, prompt: String) -> A2AEvent {
174 A2AEvent::InputRequired {
175 timestamp: Utc::now(),
176 payload: InputRequiredPayload {
177 task_id,
178 context_id,
179 prompt,
180 },
181 }
182 }
183
184 pub fn auth_required(task_id: TaskId, context_id: ContextId, auth_url: String) -> A2AEvent {
185 A2AEvent::AuthRequired {
186 timestamp: Utc::now(),
187 payload: AuthRequiredPayload {
188 task_id,
189 context_id,
190 auth_url,
191 },
192 }
193 }
194
195 pub fn json_rpc_response(id: serde_json::Value, result: serde_json::Value) -> A2AEvent {
196 A2AEvent::JsonRpcResponse {
197 timestamp: Utc::now(),
198 payload: JsonRpcResponsePayload { id, result },
199 }
200 }
201}