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 the Task through a defined lifecycle, reporting progress and asking for input as needed, until it reaches an interrupted state (such as TASK_STATE_INPUT_REQUIRED or TASK_STATE_AUTH_REQUIRED) or a terminal state (such as TASK_STATE_COMPLETED, TASK_STATE_CANCELED, TASK_STATE_REJECTED, or TASK_STATE_FAILED).

Task states

StateTypeMeaning
TASK_STATE_SUBMITTEDActiveThe task has been submitted
TASK_STATE_WORKINGActiveThe agent is processing
TASK_STATE_INPUT_REQUIREDInterruptedMore input is needed from the client
TASK_STATE_AUTH_REQUIREDInterruptedAdditional authentication is needed
TASK_STATE_COMPLETEDTerminalFinished successfully
TASK_STATE_FAILEDTerminalExecution failed
TASK_STATE_CANCELEDTerminalCanceled
TASK_STATE_REJECTEDTerminalThe 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 a taskId.
  • To continue a previous interaction, the client sends later messages with the same contextId.
  • The client can optionally attach a taskId to 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 Message objects. They typically do not manage complex state or long-running executions and use contextId to tie messages together. These agents often wrap LLM invocations and simple tools directly.
  • Task-generating agents: Always respond with Task objects. Even plain responses are modeled as completed tasks. Once a task is created, the agent returns only Task objects, 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 Message and Task objects. They use messages to negotiate capability and scope of work, then create a Task to track execution and manage states such as input-required or error handling. In other words, Message objects carry the lightweight back-and-forth that establishes what should be done, and a Task is created once there is committed work to execute and observe. As with task-generating agents, once a task is created the agent returns only Task objects 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-required task 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

Source: Official A2A documentation: Life of a Task