Track remote tasks beyond a single response
How to study this lesson
Read one section, trace the worked example, and try the knowledge check. Bookmark saves a shortcut; notes appear in My notebook. Mark lesson complete is your own assessment and does not mark its lab passed.
By the end, you can
- Distinguish messages, task state, and artifacts.
- Handle input-required and terminal states explicitly.
- Recover monitoring after stream interruption.
A remote task has its own lifetime
A network response can arrive before a remote agent finishes its work. A task identifier gives the client a stable handle for later status checks, additional input, cancellation, and result retrieval. Do not equate an accepted request with a completed task. The user-facing application should be able to show accepted, working, waiting for input, and finished without guessing from the tone of a progress message.
A2A separates conversational messages, task state, and output artifacts. Its task lifecycle supports states including working, input required, authentication required, and terminal outcomes. [A2A task lifecycle documentation](https://a2a-protocol.org/latest/topics/life-of-a-task/). This lesson uses readable local status names to teach state transitions. Real integrations must map to the exact enum names, envelopes, and semantics of their pinned protocol version rather than sending these local records directly.
Model interrupted and terminal states differently
A task waiting for input has paused because more information is needed. It may resume when the client supplies that information. A completed task has reached a terminal outcome and should not be casually mutated back into working. The same distinction applies to failed, canceled, and rejected outcomes. A new request can create a new task linked to the old one, preserving the history of what actually happened.
Consider a report task that asks which quarter to analyze. The client records input required, presents the question, and resumes the same logical interaction after receiving Q2. If the client instead creates another unrelated task, it may lose context or duplicate expensive work. Conversely, an old delayed working event must not overwrite a completed task. State version checks and event ordering rules are necessary even when every individual message is valid JSON.
Artifacts are outputs with identity
A progress message saying the report is ready is not the report itself. Model output artifacts with identifiers, types, and enough metadata to validate and retrieve them. A report could have a summary artifact and a structured evidence artifact, each with a schema version and provenance. Validate the artifacts against the task contract before claiming success, and preserve a distinction between the remote task completing and your local acceptance check passing.
Streaming artifacts may arrive in parts. The receiver needs to understand which artifact each part belongs to and whether the payload replaces or extends previous content according to the selected protocol. A truncated connection should not produce a polished but incomplete final report. Keep provisional artifacts separate from accepted ones until completion and validation criteria hold. The teaching code below demonstrates a local task state reducer, not artifact wire assembly.
A disconnected stream is a monitoring problem
If a status stream disconnects, the remote task may continue running. Reconnecting or querying task state is usually different from resubmitting the original work. Persist the remote task ID before the client starts depending on future updates. On recovery, retrieve authoritative current state and reconcile local progress. Do not assume every intermediate status notification is replayable unless the chosen protocol and service explicitly guarantee that behavior.
Suppose the client last saw working, the agent completed, and the network failed before the terminal event arrived. Starting a new task can create duplicate work. Fetching the known task can reveal its completed state and artifacts. A local sequence number can help detect missing events within your application, but inventing such a field does not add a delivery guarantee to the remote protocol. Mark application-level reliability mechanisms separately from standard protocol fields.
Cancellation is a request with an outcome
Asking a remote task to cancel does not necessarily erase effects already performed. The task may finish before cancellation arrives, reject cancellation, or stop only future steps. Your UI should show cancellation requested until the remote outcome is known. If the task involved an external write, recovery may require a compensating action with its own authorization and audit record, rather than pretending the write never happened.
Test the client with traces that include pause and resume, terminal events arriving late, duplicate notifications, and a disconnect after the remote commit. Assert that local state never regresses from accepted completion and that artifacts remain tied to the correct task. A protocol makes communication consistent, but your application still needs a durable local model of what it knows and what it has not yet confirmed. That model is the basis for reliable collaboration across independently operated agents.
Work through the code
This teaching simulation uses a deliberately limited local lifecycle. It is not a normative A2A transition validator and its status strings are not version-pinned wire enums. It illustrates pause/resume and terminal-state protection with a deterministic trace.
transitions = {
'submitted': {'working', 'rejected', 'canceled'},
'working': {'input_required', 'completed', 'failed', 'canceled'},
'input_required': {'working', 'canceled'},
'completed': set(), 'failed': set(),
'rejected': set(), 'canceled': set(),
}
task = {'id': 't7', 'status': 'submitted', 'revision': 0}
def advance(new_status):
if new_status not in transitions[task['status']]:
return False
task['status'] = new_status
task['revision'] += 1
return True
for state in ('working', 'input_required', 'working', 'completed'):
print(state, advance(state))
print('late working:', advance('working'))
print('final:', task['status'], task['revision'])
working True input_required True working True completed True late working: False final: completed 4
Run Python snippets locally with the prerequisites named above. The module coding lab runs directly in your browser.
Pause and reason
A task stream disconnects after you saw working. You have the remote task ID. What is the first recovery action, and why?
Check your understanding
A completed task receives a delayed working notification. What should the local client do?
Your notes
Explain the mechanism in your own words. Add a failure you want to test.