Skip to main content

brainwires_a2a/
streaming.rs

1//! Streaming event types for A2A.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6use crate::task::{Task, TaskStatus};
7use crate::types::{Artifact, Message};
8
9/// Event notifying a change in task status.
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
11pub struct TaskStatusUpdateEvent {
12    /// Task identifier.
13    #[serde(rename = "taskId")]
14    pub task_id: String,
15    /// Context identifier.
16    #[serde(rename = "contextId")]
17    pub context_id: String,
18    /// New task status.
19    pub status: TaskStatus,
20    /// Optional metadata.
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub metadata: Option<HashMap<String, serde_json::Value>>,
23}
24
25/// Event notifying an artifact update.
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
27pub struct TaskArtifactUpdateEvent {
28    /// Task identifier.
29    #[serde(rename = "taskId")]
30    pub task_id: String,
31    /// Context identifier.
32    #[serde(rename = "contextId")]
33    pub context_id: String,
34    /// The artifact.
35    pub artifact: Artifact,
36    /// Index of this artifact within the task's artifact list.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub index: Option<u32>,
39    /// If true, append to previously sent artifact with same ID.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub append: Option<bool>,
42    /// If true, this is the final chunk.
43    #[serde(rename = "lastChunk", skip_serializing_if = "Option::is_none")]
44    pub last_chunk: Option<bool>,
45    /// Optional metadata.
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub metadata: Option<HashMap<String, serde_json::Value>>,
48}
49
50/// Wrapper-based stream response (exactly one field should be set).
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
52pub struct StreamResponse {
53    /// Full task snapshot.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub task: Option<Task>,
56    /// Agent message.
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub message: Option<Message>,
59    /// Task status change.
60    #[serde(skip_serializing_if = "Option::is_none", rename = "statusUpdate")]
61    pub status_update: Option<TaskStatusUpdateEvent>,
62    /// Artifact update.
63    #[serde(skip_serializing_if = "Option::is_none", rename = "artifactUpdate")]
64    pub artifact_update: Option<TaskArtifactUpdateEvent>,
65}
66
67/// Response for `message/send` — wrapper-based (exactly one field should be set).
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
69pub struct SendMessageResponse {
70    /// A task was created or updated.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub task: Option<Task>,
73    /// A direct message response.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub message: Option<Message>,
76}