Why architecture matters here

The architectural question streaming answers is: where does a long-running task's truth live? Synchronous RPC ties the task to the connection — the connection dies, the work's observability dies with it, and 'is it still running?' has no answer. A2A's design separates them: the task is a durable server-side entity with an id and a state machine; the stream is just a view onto its event log. That separation is what makes every hard case tractable — reconnection (resubscribe to the entity), handoff (another process can watch the same task), audit (the event history is the record), and webhooks (a different delivery channel for the same events). Protocols that skip the task-as-entity step rediscover these needs as bolted-on job IDs and polling endpoints; A2A bakes them into the contract.

The input-required state is the underrated piece. Real delegated work is conversational: the researcher agent needs to know 'which region matters more?', the booking agent needs a seat preference, the coding agent needs a decision between two approaches. Without a protocol-level way to pause and ask, implementers choose between failing the task (wasteful), guessing (dangerous), or inventing side channels (fragmentation). With it, a task becomes a structured multi-turn exchange — the remote agent parks in input-required, the client (or its human) answers via a follow-up message bound to the same task, and execution resumes — while the state machine keeps both sides honest about whose move it is.

And the two delivery modes — SSE and webhooks — reflect a real bimodality in agent workloads. Interactive delegation (seconds to minutes, a user watching) wants streaming: progress bars, partial artifacts, low-latency state changes. Batch delegation (hours, nobody watching) wants callbacks: holding an SSE connection open across a four-hour analysis is fragile and wasteful; a signed webhook on completion is exactly right. Architectures that support only one mode force the other's workloads into the wrong shape — the protocol supporting both, over the same task entity, is what lets one remote agent serve both a chat UI and a nightly pipeline without special cases.

Advertisement

The architecture: every piece explained

Top row: the streaming contract. The client agent (any A2A client — an orchestrator, a host app) calls message/stream with a message; the response is an SSE stream. First event: the created task with its id and initial state. Then the lifecycle plays out as typed events: status-update events move the state machine (submitted → working → one of completed/failed/canceled/rejected, or the pause states input-required and auth-required) and may carry progress messages; a final flag marks the stream's semantic end. The state machine is the protocol's spine — implementations must emit legal transitions, and clients drive UI and orchestration logic off states, not message prose.

Middle row: results and the long haul. Artifact-update events deliver output incrementally: named artifacts (a report, a dataset, code) arrive in chunks with append/last-chunk semantics, so a 40-page document streams as it is written rather than materializing at the end — and partial results survive a task that later fails. input-required pauses execution with a question payload; the client answers by sending a new message carrying the same task id (the multi-turn binding), and the task returns to working. resubscribe (tasks/resubscribe) reattaches a dropped client to the live event stream — implementations pair it with tasks/get for a state snapshot, covering the gap between last-seen event and resubscription. Push notifications handle connectionless operation: the client registers a webhook URL (with a token) via tasks/pushNotificationConfig/set; the server POSTs signed notifications on state changes; the client verifies signatures (and the server validates the webhook target at registration — SSRF defense) before trusting a callback, then fetches authoritative state via tasks/get rather than acting on the callback body alone.

Bottom rows: the executor and its context. The remote agent runs the actual work — in practice an agent framework (ADK, LangGraph, custom) wrapped in an A2A server that maps internal progress to protocol events; a durable task store backs the entity (in-memory for demos, database for production), and multi-turn context binds follow-up messages to task history so the resumed execution remembers the exchange. The ops strip carries the production concerns: idle/expiry policies for tasks nobody resumed, webhook endpoint verification and retry policy, and event-log durability sized to resubscription windows.

A2A streaming — long-running tasks with live updatesSSE streams + push notifications between agentsClient agentdelegates a taskmessage/streamSSE subscriptionTask lifecyclesubmitted → working → doneStatus updatesstate + progress eventsArtifact updatesincremental resultsinput-requiredmid-task questionsresubscribereconnect to a live taskPush notificationswebhooks for the long haulRemote agentexecutes, emits eventsMulti-turn taskscontext across exchangesOps — idle timeouts + webhook verification + task store durabilityreceiveanswerresumenotifyexecutecontinuecallbackoperateoperate
A2A streaming: a delegating agent subscribes to a task's SSE stream for status and artifact events; push notifications cover tasks that outlive connections.
Advertisement

End-to-end flow

Run a delegation end to end. An enterprise orchestrator delegates 'analyze Q2 churn and draft a mitigation plan' to a specialist analytics agent (another team's service, discovered via its agent card, authenticated via OAuth per the A2A auth spec). The orchestrator calls message/stream; the SSE stream opens: task created (task-7c21, submitted), then working with a status message ('pulling cohort data'). The orchestrator's UI shows a live progress panel fed purely by status events.

Nine minutes in, artifacts begin: churn-analysis.md streams in chunks — the user reads the first sections while later ones are still computing. Then the pause: input-required, with the question 'mitigation budget assumptions: conservative (<$50k) or aggressive?'. The orchestrator surfaces it to the human, who picks conservative; the answer goes back as a message on task-7c21; the stream resumes working. Midway, the orchestrator pod restarts on a deploy — the SSE connection dies with it. On recovery, the orchestrator's task-watcher finds task-7c21 in its own durable list, calls tasks/get (state: working, artifacts so far), then resubscribes; it missed two progress events and nothing of substance — the task entity, not the connection, was always the truth. Completion arrives with the final artifact chunk flagged last; the state machine closes at completed; the orchestrator archives the artifacts and the event history into its audit store.

The same specialist serves the batch shape that night. A pipeline delegates 'full-year churn deep-dive' — hours of work. The pipeline registers a push-notification config (webhook + token) and disconnects entirely. At 03:40 the analytics agent completes; its notifier POSTs the signed callback; the pipeline's endpoint verifies the signature and token, calls tasks/get for the authoritative final state (never trusting the callback payload as the result itself), pulls artifacts, and triggers downstream jobs. When, a week later, the analytics team's postmortem asks 'what exactly did we send task-7c21's requester and when?', the answer is the task's event log — the protocol's durable spine doing double duty as the audit trail.