pub struct Task {
pub id: TaskId,
pub context_id: ContextId,
pub status: TaskStatus,
pub history: Option<Vec<Message>>,
pub artifacts: Option<Vec<Artifact>>,
pub metadata: Option<Value>,
}Expand description
A unit of work managed by an A2A agent.
The wire kind field ("task") is injected by enclosing discriminated
unions such as crate::events::StreamResponse and
crate::responses::SendMessageResponse. Standalone Task values received
over the wire may include kind; serde silently tolerates unknown fields, so
no action is needed on the receiving side.
Fields§
§id: TaskIdUnique task identifier.
context_id: ContextIdConversation context this task belongs to.
status: TaskStatusCurrent status of the task.
history: Option<Vec<Message>>Historical messages exchanged during this task.
artifacts: Option<Vec<Artifact>>Artifacts produced by this task.
metadata: Option<Value>Arbitrary metadata.
Implementations§
Source§impl Task
impl Task
Sourcepub fn new(
id: impl Into<TaskId>,
context_id: impl Into<ContextId>,
status: TaskStatus,
) -> Task
pub fn new( id: impl Into<TaskId>, context_id: impl Into<ContextId>, status: TaskStatus, ) -> Task
A task in status, with no history, artifacts or metadata — what a
custom store or a test builds.
The struct is not #[non_exhaustive], so a literal still compiles;
this is the form that keeps compiling when a field is added (N16).
use a2a_protocol_types::task::{Task, TaskState, TaskStatus};
let task = Task::new("t1", "c1", TaskStatus::new(TaskState::Working));
assert_eq!(task.id.as_ref(), "t1");
assert!(task.artifacts.is_none());Sourcepub fn text(&self) -> Option<&str>
pub fn text(&self) -> Option<&str>
Returns the text of the first text Part in
this task’s artifacts, or None if it produced no text.
Reading the answer out of a finished task is what a caller does with
every delegated result, and Task previously had no inherent methods
at all, so each caller wrote the walk by hand. Six files under
examples/ had written the same artifacts → first → text chain.
This skips artifacts with no text rather than stopping at the
first, which is where it differs from the hand-written chain: a task
whose first artifact is a file and whose second is text yields that
text here and None from artifacts.first().and_then(Artifact::text).
It is the same rule Message::text
already applies across parts.
It reads artifacts only. A failure reason lives on the status message
instead, at task.status.message.
use a2a_protocol_types::artifact::Artifact;
use a2a_protocol_types::message::Part;
use a2a_protocol_types::task::{ContextId, Task, TaskState, TaskStatus};
let task = Task {
id: "t1".into(),
context_id: ContextId::new("c1"),
status: TaskStatus::new(TaskState::Completed),
history: None,
artifacts: Some(vec![
Artifact::new("chart", vec![Part::url("https://example.com/c.png")]),
Artifact::new("summary", vec![Part::text("revenue rose 4%")]),
]),
metadata: None,
};
assert_eq!(task.text(), Some("revenue rose 4%"));Sourcepub fn failure_class(&self) -> Option<FailureClass>
pub fn failure_class(&self) -> Option<FailureClass>
Why this task failed, when the agent classified it.
Reads the class off the status message, so a caller can branch on a value rather than on prose:
match task.failure_class() {
Some(c) if c.is_retryable() => { /* back off and try again */ }
Some(c) if c.needs_human() => { /* escalate, do not retry */ }
_ => { /* give up, or inspect `task.status.message` */ }
}None means the agent classified nothing — an older peer, or one
that does not implement the extension. It does not mean the task
succeeded; status says that.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Task
impl<'de> Deserialize<'de> for Task
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Task, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Task, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for Task
Source§impl Serialize for Task
impl Serialize for Task
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for Task
Auto Trait Implementations§
impl Freeze for Task
impl RefUnwindSafe for Task
impl Send for Task
impl Sync for Task
impl Unpin for Task
impl UnsafeUnpin for Task
impl UnwindSafe for Task
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request