Life of a Task
Interactions in the A2A Protocol range from simple stateless exchanges to complex, long-running processes. When an agent receives a message from a client, it can respond in one of two ways:
- Respond with a stateless
Message: for immediate, self-contained interactions that finish without any further state to manage. - Initiate a stateful
Task: the agent runs theTaskthrough a defined lifecycle, reporting progress and asking for input as needed, until it reaches an interrupted state (such asTASK_STATE_INPUT_REQUIREDorTASK_STATE_AUTH_REQUIRED) or a terminal state (such asTASK_STATE_COMPLETED,TASK_STATE_CANCELED,TASK_STATE_REJECTED, orTASK_STATE_FAILED).
Task states
| State | Type | Meaning |
|---|---|---|
TASK_STATE_SUBMITTED | Active | The task has been submitted |
TASK_STATE_WORKING | Active | The agent is processing |
TASK_STATE_INPUT_REQUIRED | Interrupted | More input is needed from the client |
TASK_STATE_AUTH_REQUIRED | Interrupted | Additional authentication is needed |
TASK_STATE_COMPLETED | Terminal | Finished successfully |
TASK_STATE_FAILED | Terminal | Execution failed |
TASK_STATE_CANCELED | Terminal | Canceled |
TASK_STATE_REJECTED | Terminal | The agent declined to perform the task |
The complete definitions are in the specification .
Group related interactions with contextId
A contextId is a key identifier that groups multiple Task objects and independent Message objects, giving continuity across a series of interactions.
- When a client sends a message for the first time, the agent responds with a new
contextId. If a task is initiated, it also has ataskId. - To continue a previous interaction, the client sends later messages with the same
contextId. - The client can optionally attach a
taskIdto a subsequent message to indicate that it continues that specific task.
The contextId enables collaboration toward a common goal, or a shared session across several tasks that may run at once. Internally, an A2A agent (especially one using an LLM) uses the contextId to manage its conversational state or LLM context.
Agent response: Message or Task
Whether to respond with a Message or a Task depends on the nature of the interaction and the agent’s capabilities:
- Messages for trivial interactions: Transactional interactions need no long-running processing or complex state. An agent might also use messages to agree on the scope of a task before committing to a
Task. - Tasks for stateful interactions: An agent maps an incoming message to a supported capability. When that capability needs substantial, trackable work over a longer period, the agent responds with a
Task.
Conceptually, agents fall into three groups:
- Message-only agents: Always respond with
Messageobjects. They typically do not manage complex state or long-running executions and usecontextIdto tie messages together. These agents often wrap LLM invocations and simple tools directly. - Task-generating agents: Always respond with
Taskobjects. Even plain responses are modeled as completed tasks. Once a task is created, the agent returns onlyTaskobjects, and once a task is complete no more messages can be sent to it. This avoids the Task-versus-Message decision but creates completed task objects even for simple interactions. - Hybrid agents: Generate both
MessageandTaskobjects. They use messages to negotiate capability and scope of work, then create aTaskto track execution and manage states such asinput-requiredor error handling. In other words,Messageobjects carry the lightweight back-and-forth that establishes what should be done, and aTaskis created once there is committed work to execute and observe. As with task-generating agents, once a task is created the agent returns onlyTaskobjects in response to subsequent messages, and once a task is complete no more messages can be sent to it.
For a deeper discussion, see the community article A2A protocol: Demystifying Tasks vs Messages .
Task refinements
Clients often need to send new requests based on task results or refine the outputs of previous tasks. This is modeled by starting another interaction with the same contextId as the original task. The client further hints the agent by referencing the original task through referenceTaskIds in the Message. The agent then responds with either a new Task or a Message.
Task immutability
Once a task reaches a terminal state (completed, canceled, rejected, or failed), it cannot restart. Any subsequent interaction related to that task, such as a refinement, must start a new task within the same contextId. This brings several benefits:
- Immutability: Clients can reliably reference a task and its state, artifacts, and messages. Inputs map cleanly to outputs, which helps orchestration and traceability.
- A clear unit of work: Every new request, refinement, or follow-up becomes a distinct task. This simplifies bookkeeping, allows granular tracking of an agent’s work, and lets you trace each artifact to a specific unit of work.
- Easier implementation: Agent developers no longer have to decide whether to create a new task or restart an existing one.
Parallel follow-ups
A2A supports parallel work by letting agents create distinct, parallel tasks for each follow-up message sent within the same contextId. Clients can track individual tasks and create new dependent tasks as soon as a prerequisite task completes. For example:
- Task 1: Book a flight to Helsinki.
- Task 2: Based on Task 1, book a hotel.
- Task 3: Based on Task 1, book a snowmobile activity.
- Task 4: Based on Task 2, add a spa reservation to the hotel booking.
Referencing previous artifacts
The serving agent infers the relevant artifact from a referenced task or from the contextId. As the domain expert, it is best placed to resolve ambiguity or spot missing information. When something is ambiguous, the agent returns an input-required state to ask the client for clarification. The client then names the artifact in its response, and can add artifact references (artifactId, taskId) in Part metadata.
Tracking artifact mutation
Follow-up or refinement tasks often create new artifacts based on older ones. Track these mutations so later interactions use only the most recent version, like a version history in which each new artifact links to the one before it.
The client is best placed to manage this linkage: it decides what counts as an acceptable result and can accept or reject new versions. So the serving agent should not track artifact mutations, and this linkage is not part of the A2A specification. Clients should keep the version history on their side and show the user the latest acceptable version.
To help client-side tracking, serving agents should reuse a consistent artifact name when they generate a refined version of an existing artifact.
For follow-up or refinement tasks, the client should name the exact artifact it wants to refine, ideally the “latest” version from its perspective. If the client provides no artifact reference, the serving agent can:
- Attempt to infer the intended artifact from the current
contextId. - If there is ambiguity or insufficient context, respond with an
input-requiredtask state to request clarification from the client.
Example follow-up scenario
The following example illustrates a typical task flow with a follow-up (JSON-RPC binding).
1. The client sends a message to the agent:
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "SendMessage",
"params": {
"message": {
"role": "user",
"parts": [
{
"text": "Generate an image of a sailboat on the ocean."
}
],
"messageId": "msg-user-001"
}
}
}2. The agent responds with a boat image (a completed task):
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"task": {
"id": "task-boat-gen-123",
"contextId": "ctx-conversation-abc",
"status": {
"state": "TASK_STATE_COMPLETED"
},
"artifacts": [
{
"artifactId": "artifact-boat-v1-xyz",
"name": "sailboat_image.png",
"description": "A generated image of a sailboat on the ocean.",
"parts": [
{
"filename": "sailboat_image.png",
"mediaType": "image/png",
"raw": "base64_encoded_png_data_of_a_sailboat"
}
]
}
]
}
}
}3. The client asks to color the boat red. This refinement request refers to the previous taskId and uses the same contextId:
{
"jsonrpc": "2.0",
"id": "req-002",
"method": "SendMessage",
"params": {
"message": {
"role": "user",
"messageId": "msg-user-002",
"contextId": "ctx-conversation-abc",
"referenceTaskIds": [
"task-boat-gen-123"
],
"parts": [
{
"text": "Please modify the sailboat to be red."
}
]
}
}
}4. The agent responds with a new image artifact (new task, same context, same artifact name). The agent creates a new task within the same contextId. The new boat image artifact keeps the same name but has a new artifactId.
{
"jsonrpc": "2.0",
"id": "req-002",
"result": {
"task": {
"id": "task-boat-color-456",
"contextId": "ctx-conversation-abc",
"status": {
"state": "TASK_STATE_COMPLETED"
},
"artifacts": [
{
"artifactId": "artifact-boat-v2-red-pqr",
"name": "sailboat_image.png",
"description": "A generated image of a red sailboat on the ocean.",
"parts": [
{
"filename": "sailboat_image.png",
"mediaType": "image/png",
"raw": "base64_encoded_png_data_of_a_RED_sailboat"
}
]
}
]
}
}
}Further reading
- Streaming and Async : real-time progress and offline notifications
- Key concepts
- Specification