A2A Task Lifecycle
Purpose
This functional area lets a caller send work to the platform as an A2A Task, retrieve that task's
outcome afterward, watch it happen live over a stream, and cancel it — the same lifecycle concepts the A2A
specification defines, scoped to what this platform actually does today.
Main Capabilities
- send a message and receive the resulting task synchronously (
SendMessage) - send a message and watch the task's status stream live (
SendStreamingMessage) - retrieve a previously created task by id (
GetTask) - reconnect to a task's status stream after the fact (
SubscribeToTask) - request cancellation of a task (
CancelTask)
How It Works
Every task this platform creates maps to exactly one governed downstream call. For the server direction —
a Mapping-backed tool invocation, the same one MCP's tools/call already performs — that call is a single
synchronous HTTP or SOAP request/response, so a task's entire lifetime, from submitted to a terminal
state, happens within the time it takes to make one downstream call: no background execution, no queue,
no polling. The concentrator direction is the exception: AgentInvocationService drives an outbound task
through a genuine working transition (persisted, push-notification-eligible like any other status
change) before it makes the actual outbound call to the remote agent, so that task really does sit in
working for the duration of that call — bounded to one HTTP round trip, not an open-ended background
execution, but real nonetheless.
This shapes every capability in this area:
SendMessageperforms the call, then returns the task already in a terminal state (completedorfailed), with the response captured as the task's one artifact.SendStreamingMessageperforms the identical call, but reports it as a two-frame stream: asubmittedevent immediately, then the terminal event a moment later. A client that specifically asked for streaming semantics sees the shape it expects, even though nothing about the underlying execution is actually asynchronous.GetTasklooks up whatever was persisted by a priorSendMessage/SendStreamingMessagecall. There is no scenario yet where a secondGetTaskcall would see a different status than the first — every task is already terminal by the time its creator's response has been sent.SubscribeToTaskreconnects to a task by id and immediately re-emits its current status as one stream event, then closes. For the vast majority of tasks — the server direction, already terminal by the time a caller could plausibly reconnect — that status iscompleted/failed. The concentrator direction (calling out to another agent, where the remote agent's response timing decides when the task leavesworking) is where this capability can genuinely observe a task still inworking; either way,SubscribeToTaskitself behaves identically — one event reflecting whatever the current persisted status is, then close.CancelTaskalmost always returns a "not cancelable" error today, because by the time a caller could plausibly race a cancel against the task's own execution, the task has already reached a terminal state. This is correct A2A behavior, not a stub — a spec-compliant client is expected to handle this response, and it accurately reflects that this platform has nothing left to cancel once the call completes.
Persistence
Every task is recorded (A2aTaskRecord) the moment it's created, tenant/client-scoped, keyed by the
external task id the caller sees on the wire. This is what makes GetTask/SubscribeToTask possible
after the fact — without it, a task's outcome would only ever be visible in the original SendMessage
response, with no way to look it up again.
Streaming Transport
SendStreamingMessage and SubscribeToTask answer over Server-Sent Events, reusing the exact same
session/stream infrastructure the MCP protocol's Streamable HTTP transport already uses — extracted into a
shared, protocol-neutral form specifically so A2A could add streaming without re-deriving or duplicating
proven session, backplane, and multi-instance delivery machinery. See Runtime Protocols And MCP
Support for how that underlying transport behaves; A2A's
streaming endpoints behave the same way, under their own session identity and rate-limit policy.
Functional Value
This area gives an A2A caller the same reliable request/response and stream-based interaction model MCP callers already have, expressed in A2A's own task vocabulary — without this platform needing to build or operate a second execution engine to back it.
