# Tasks and streaming (/docs/concepts/tasks-and-streaming)



## The task lifecycle [#the-task-lifecycle]

Sending a message creates a **task**. The wrapper publishes status updates as the backend works, then delivers the result as an **artifact**.

| State            | Meaning                                                                             |
| ---------------- | ----------------------------------------------------------------------------------- |
| `submitted`      | Accepted, not yet running                                                           |
| `working`        | The backend is executing                                                            |
| `input-required` | The agent needs more input from the caller (an interrupted state)                   |
| `auth-required`  | The agent needs the caller to authenticate before continuing (an interrupted state) |
| `completed`      | Finished successfully; artifacts hold the result (terminal)                         |
| `failed`         | Finished with an error (terminal)                                                   |
| `canceled`       | Stopped by the caller (terminal)                                                    |
| `rejected`       | The agent declined to perform the task (terminal)                                   |

In A2A v1.0 these are written `TASK_STATE_SUBMITTED`, `TASK_STATE_WORKING` and so on; the v0.3 names above are still accepted by the wrappers' compatibility layer. The authoritative list is in the [A2A specification](https://a2a-protocol.org/latest/specification/).

## Two ways to call an agent [#two-ways-to-call-an-agent]

**Blocking.** `message/send` with `configuration.blocking: true` returns once the task is done. Simple, and what the [quick start](/docs/getting-started/quickstart) uses.

**Streaming.** `message/stream` returns a stream of events (status updates and artifact chunks) as they happen. Use it for long tasks or live UIs. Agent cards advertise `streaming: true` when supported.

## Buffered versus streamed artifacts [#buffered-versus-streamed-artifacts]

By default wrappers **buffer** the response and publish a single complete artifact at the end. This is the most compatible mode, including with the A2A Inspector.

Set `features.streamArtifactChunks: true` (or `STREAM_ARTIFACTS=true` where supported) to publish incremental chunks with `append: true`. Enable it only if your client correctly handles appending artifact updates.

## Cancellation [#cancellation]

Clients can cancel an in-flight task: `tasks/cancel` on v0.3 JSON-RPC, `CancelTask` on v1.0, or the REST route `POST /a2a/rest/v1/tasks/{taskId}:cancel` (v0.3). The wrapper aborts the backend call using an `AbortController`. Cancelling is idempotent, so repeating it for the same task is safe.

## Turns are serialised per context [#turns-are-serialised-per-context]

Within one `contextId`, turns run one at a time. Concurrent messages on the same context are queued, not run in parallel. Different contexts run independently.

## Long-running background work (a2a-claude) [#long-running-background-work-a2a-claude]

Claude Agent SDK sessions can start background tasks. `a2a-claude` can hold the A2A task open while that work is in flight, so the task stays `working` until the background work finishes rather than completing early. Background task membership is reported through a `background_tasks` event. See the [a2a-claude reference](/docs/reference/packages/a2a-claude).

## Rate limits (a2a-claude) [#rate-limits-a2a-claude]

When Claude reports a rate limit, `a2a-claude` always fails the task rather than hanging, and emits a `rate_limit` event with the reset time when available. Details are in the reference.
