1use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "kebab-case")]
14pub enum TaskState {
15 Submitted,
16 Working,
17 Completed,
18 Failed,
19 Cancelled,
20 InputRequired,
21 Rejected,
22 AuthRequired,
23}
24
25impl TaskState {
26 pub fn is_terminal(&self) -> bool {
28 matches!(
29 self,
30 TaskState::Completed | TaskState::Failed | TaskState::Cancelled | TaskState::Rejected
31 )
32 }
33
34 pub fn is_active(&self) -> bool {
36 !self.is_terminal()
37 }
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct Task {
44 pub id: String,
45 pub context_id: Option<String>,
46 pub status: TaskStatus,
47 #[serde(default)]
48 pub artifacts: Vec<Artifact>,
49 #[serde(default)]
50 pub history: Vec<Message>,
51 #[serde(default)]
52 pub metadata: HashMap<String, serde_json::Value>,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct TaskStatus {
59 pub state: TaskState,
60 #[serde(default)]
61 pub message: Option<Message>,
62 pub timestamp: Option<String>,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct Message {
69 pub message_id: String,
70 pub role: MessageRole,
71 pub parts: Vec<Part>,
72 #[serde(default)]
73 pub context_id: Option<String>,
74 #[serde(default)]
75 pub task_id: Option<String>,
76 #[serde(default)]
77 pub metadata: HashMap<String, serde_json::Value>,
78 #[serde(default, skip_serializing_if = "Vec::is_empty")]
80 pub extensions: Vec<String>,
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
84#[serde(rename_all = "lowercase")]
85pub enum MessageRole {
86 User,
87 Agent,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(tag = "kind", rename_all = "camelCase")]
93pub enum Part {
94 #[serde(rename = "text")]
95 Text { text: String },
96 #[serde(rename = "file")]
97 File { file: FileContent },
98 #[serde(rename = "data")]
99 Data { data: serde_json::Value },
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase")]
105pub struct FileContent {
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub bytes: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
109 pub uri: Option<String>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub mime_type: Option<String>,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub name: Option<String>,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118#[serde(rename_all = "camelCase")]
119pub struct Artifact {
120 pub artifact_id: String,
121 pub parts: Vec<Part>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub name: Option<String>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub description: Option<String>,
126 #[serde(default)]
127 pub metadata: HashMap<String, serde_json::Value>,
128 #[serde(default, skip_serializing_if = "Vec::is_empty")]
130 pub extensions: Vec<String>,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
135#[serde(rename_all = "camelCase")]
136pub struct AgentCard {
137 pub name: String,
138 pub description: String,
139 pub url: String,
140 pub version: String,
141 #[serde(default = "default_protocol_version")]
142 pub protocol_version: String,
143 #[serde(default, skip_serializing_if = "Option::is_none")]
145 pub preferred_transport: Option<String>,
146 #[serde(default, skip_serializing_if = "Vec::is_empty")]
148 pub additional_interfaces: Vec<AgentInterface>,
149 pub capabilities: AgentCapabilities,
150 pub skills: Vec<AgentSkill>,
151 #[serde(default)]
152 pub default_input_modes: Vec<String>,
153 #[serde(default)]
154 pub default_output_modes: Vec<String>,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub provider: Option<AgentProvider>,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub icon_url: Option<String>,
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub documentation_url: Option<String>,
161 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
163 pub security_schemes: HashMap<String, SecurityScheme>,
164 #[serde(default, skip_serializing_if = "Vec::is_empty")]
166 pub security: Vec<SecurityRequirement>,
167 #[serde(default)]
169 pub supports_authenticated_extended_card: bool,
170 #[serde(default, skip_serializing_if = "Vec::is_empty")]
172 pub signatures: Vec<AgentCardSignature>,
173}
174
175fn default_protocol_version() -> String {
176 "0.3.0".to_string()
177}
178
179#[derive(Debug, Clone, Default, Serialize, Deserialize)]
180#[serde(rename_all = "camelCase")]
181pub struct AgentCapabilities {
182 #[serde(default)]
183 pub streaming: bool,
184 #[serde(default)]
185 pub push_notifications: bool,
186 #[serde(default)]
187 pub state_transition_history: bool,
188 #[serde(default, skip_serializing_if = "Vec::is_empty")]
190 pub extensions: Vec<AgentExtension>,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct AgentSkill {
196 pub id: String,
197 pub name: String,
198 pub description: String,
199 #[serde(default)]
200 pub tags: Vec<String>,
201 #[serde(default)]
202 pub examples: Vec<String>,
203 #[serde(default)]
204 pub input_modes: Vec<String>,
205 #[serde(default)]
206 pub output_modes: Vec<String>,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct AgentProvider {
211 pub organization: String,
212 pub url: String,
213}
214
215#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct JsonRpcRequest {
218 pub jsonrpc: String,
219 pub id: serde_json::Value,
220 pub method: String,
221 #[serde(default)]
222 pub params: serde_json::Value,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct JsonRpcResponse {
228 pub jsonrpc: String,
229 pub id: serde_json::Value,
230 #[serde(skip_serializing_if = "Option::is_none")]
231 pub result: Option<serde_json::Value>,
232 #[serde(skip_serializing_if = "Option::is_none")]
233 pub error: Option<JsonRpcError>,
234}
235
236#[derive(Debug, Clone, Serialize, Deserialize)]
237pub struct JsonRpcError {
238 pub code: i32,
239 pub message: String,
240 #[serde(skip_serializing_if = "Option::is_none")]
241 pub data: Option<serde_json::Value>,
242}
243
244#[allow(dead_code)]
245impl JsonRpcError {
246 pub fn parse_error(msg: impl Into<String>) -> Self {
248 Self {
249 code: PARSE_ERROR,
250 message: msg.into(),
251 data: None,
252 }
253 }
254
255 pub fn invalid_request(msg: impl Into<String>) -> Self {
257 Self {
258 code: INVALID_REQUEST,
259 message: msg.into(),
260 data: None,
261 }
262 }
263
264 pub fn method_not_found(method: &str) -> Self {
266 Self {
267 code: METHOD_NOT_FOUND,
268 message: format!("Method not found: {}", method),
269 data: None,
270 }
271 }
272
273 pub fn invalid_params(msg: impl Into<String>) -> Self {
275 Self {
276 code: INVALID_PARAMS,
277 message: msg.into(),
278 data: None,
279 }
280 }
281
282 pub fn internal_error(msg: impl Into<String>) -> Self {
284 Self {
285 code: INTERNAL_ERROR,
286 message: msg.into(),
287 data: None,
288 }
289 }
290
291 pub fn unsupported_operation(msg: impl Into<String>) -> Self {
293 Self {
294 code: UNSUPPORTED_OPERATION,
295 message: msg.into(),
296 data: None,
297 }
298 }
299}
300
301#[allow(dead_code)]
303pub const PARSE_ERROR: i32 = -32700;
304#[allow(dead_code)]
305pub const INVALID_REQUEST: i32 = -32600;
306pub const METHOD_NOT_FOUND: i32 = -32601;
307pub const INVALID_PARAMS: i32 = -32602;
308pub const INTERNAL_ERROR: i32 = -32603;
309
310pub const TASK_NOT_FOUND: i32 = -32001;
312pub const TASK_NOT_CANCELABLE: i32 = -32002;
313#[allow(dead_code)]
314pub const PUSH_NOT_SUPPORTED: i32 = -32003;
315pub const UNSUPPORTED_OPERATION: i32 = -32004;
316#[allow(dead_code)]
317pub const CONTENT_TYPE_NOT_SUPPORTED: i32 = -32005;
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321#[serde(rename_all = "camelCase")]
322pub struct MessageSendParams {
323 pub message: Message,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub configuration: Option<MessageSendConfiguration>,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
329#[serde(rename_all = "camelCase")]
330pub struct MessageSendConfiguration {
331 #[serde(default)]
332 pub accepted_output_modes: Vec<String>,
333 #[serde(skip_serializing_if = "Option::is_none")]
334 pub blocking: Option<bool>,
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub history_length: Option<usize>,
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub push_notification_config: Option<PushNotificationConfig>,
339}
340
341#[derive(Debug, Clone, Serialize, Deserialize)]
342#[serde(rename_all = "camelCase")]
343pub struct PushNotificationConfig {
344 pub url: String,
345 #[serde(skip_serializing_if = "Option::is_none")]
346 pub token: Option<String>,
347 #[serde(skip_serializing_if = "Option::is_none")]
348 pub id: Option<String>,
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize)]
353#[serde(rename_all = "camelCase")]
354pub struct TaskQueryParams {
355 pub id: String,
356 #[serde(skip_serializing_if = "Option::is_none")]
357 pub history_length: Option<usize>,
358}
359
360#[derive(Debug, Clone, Serialize, Deserialize)]
364#[serde(rename_all = "camelCase")]
365pub struct TaskStatusUpdateEvent {
366 pub id: String,
367 pub status: TaskStatus,
368 #[serde(default, rename = "final")]
369 pub is_final: bool,
370 #[serde(default)]
371 pub metadata: HashMap<String, serde_json::Value>,
372}
373
374#[derive(Debug, Clone, Serialize, Deserialize)]
376#[serde(rename_all = "camelCase")]
377pub struct TaskArtifactUpdateEvent {
378 pub id: String,
379 pub artifact: Artifact,
380 #[serde(default)]
381 pub metadata: HashMap<String, serde_json::Value>,
382}
383
384#[derive(Debug, Clone, Serialize, Deserialize)]
386#[serde(untagged)]
387pub enum StreamEvent {
388 StatusUpdate(TaskStatusUpdateEvent),
389 ArtifactUpdate(TaskArtifactUpdateEvent),
390}
391
392#[derive(Debug, Clone, Serialize, Deserialize)]
394#[serde(untagged)]
395pub enum SendMessageResponse {
396 Task(Task),
397 Message(Message),
398}
399
400#[derive(Debug, Clone, Serialize, Deserialize)]
404#[serde(tag = "type", rename_all = "camelCase")]
405pub enum SecurityScheme {
406 #[serde(rename = "apiKey")]
407 ApiKey {
408 #[serde(skip_serializing_if = "Option::is_none")]
409 description: Option<String>,
410 name: String,
411 #[serde(rename = "in")]
412 location: String, },
414 #[serde(rename = "http")]
415 Http {
416 #[serde(skip_serializing_if = "Option::is_none")]
417 description: Option<String>,
418 scheme: String,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 bearer_format: Option<String>,
421 },
422 #[serde(rename = "oauth2")]
423 OAuth2 {
424 #[serde(skip_serializing_if = "Option::is_none")]
425 description: Option<String>,
426 flows: OAuthFlows,
427 },
428 #[serde(rename = "openIdConnect")]
429 OpenIdConnect {
430 #[serde(skip_serializing_if = "Option::is_none")]
431 description: Option<String>,
432 open_id_connect_url: String,
433 },
434 #[serde(rename = "mutualTLS")]
435 MutualTls {
436 #[serde(skip_serializing_if = "Option::is_none")]
437 description: Option<String>,
438 },
439}
440
441#[derive(Debug, Clone, Default, Serialize, Deserialize)]
443#[serde(rename_all = "camelCase")]
444pub struct OAuthFlows {
445 #[serde(skip_serializing_if = "Option::is_none")]
446 pub implicit: Option<OAuthFlowImplicit>,
447 #[serde(skip_serializing_if = "Option::is_none")]
448 pub authorization_code: Option<OAuthFlowAuthorizationCode>,
449 #[serde(skip_serializing_if = "Option::is_none")]
450 pub client_credentials: Option<OAuthFlowClientCredentials>,
451 #[serde(skip_serializing_if = "Option::is_none")]
452 pub device_code: Option<OAuthFlowDeviceCode>,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456#[serde(rename_all = "camelCase")]
457pub struct OAuthFlowImplicit {
458 pub authorization_url: String,
459 #[serde(skip_serializing_if = "Option::is_none")]
460 pub refresh_url: Option<String>,
461 #[serde(default)]
462 pub scopes: HashMap<String, String>,
463}
464
465#[derive(Debug, Clone, Serialize, Deserialize)]
466#[serde(rename_all = "camelCase")]
467pub struct OAuthFlowAuthorizationCode {
468 pub authorization_url: String,
469 pub token_url: String,
470 #[serde(skip_serializing_if = "Option::is_none")]
471 pub refresh_url: Option<String>,
472 #[serde(default)]
473 pub scopes: HashMap<String, String>,
474}
475
476#[derive(Debug, Clone, Serialize, Deserialize)]
477#[serde(rename_all = "camelCase")]
478pub struct OAuthFlowClientCredentials {
479 pub token_url: String,
480 #[serde(skip_serializing_if = "Option::is_none")]
481 pub refresh_url: Option<String>,
482 #[serde(default)]
483 pub scopes: HashMap<String, String>,
484}
485
486#[derive(Debug, Clone, Serialize, Deserialize)]
487#[serde(rename_all = "camelCase")]
488pub struct OAuthFlowDeviceCode {
489 pub device_authorization_url: String,
490 pub token_url: String,
491 #[serde(skip_serializing_if = "Option::is_none")]
492 pub refresh_url: Option<String>,
493 #[serde(default)]
494 pub scopes: HashMap<String, String>,
495}
496
497pub type SecurityRequirement = HashMap<String, Vec<String>>;
499
500#[derive(Debug, Clone, Serialize, Deserialize)]
504#[serde(rename_all = "camelCase")]
505pub struct AgentExtension {
506 pub uri: String,
508 #[serde(skip_serializing_if = "Option::is_none")]
509 pub description: Option<String>,
510 #[serde(default)]
512 pub required: bool,
513 #[serde(default, skip_serializing_if = "Option::is_none")]
515 pub params: Option<serde_json::Value>,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize)]
520#[serde(rename_all = "camelCase")]
521pub struct AgentCardSignature {
522 pub signature: String,
524 #[serde(skip_serializing_if = "Option::is_none")]
526 pub algorithm: Option<String>,
527 #[serde(skip_serializing_if = "Option::is_none")]
529 pub key_id: Option<String>,
530}
531
532#[derive(Debug, Clone, Serialize, Deserialize)]
534#[serde(rename_all = "camelCase")]
535pub struct AgentInterface {
536 pub transport: String,
538 pub url: String,
540 #[serde(default, skip_serializing_if = "Vec::is_empty")]
542 pub content_types: Vec<String>,
543}
544
545#[derive(Debug, Clone, Serialize, Deserialize)]
549#[serde(rename_all = "camelCase")]
550pub struct TaskPushNotificationConfig {
551 pub id: String, pub push_notification_config: PushNotificationConfig,
553}
554
555#[derive(Debug, Clone, Serialize, Deserialize)]
557#[serde(rename_all = "camelCase")]
558pub struct AuthenticationInfo {
559 #[serde(default, skip_serializing_if = "Vec::is_empty")]
560 pub schemes: Vec<String>,
561 #[serde(skip_serializing_if = "Option::is_none")]
562 pub credentials: Option<String>,
563}