a2a 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.agent-docs/ROADMAP.md +423 -0
- data/.agent-docs/index.md +124 -0
- data/.agent-docs/llms.txt +318 -0
- data/.agent-docs/specification/json.json +2575 -0
- data/.agent-docs/specification.md +1924 -0
- data/.agent-docs/topics/a2a-and-mcp.md +132 -0
- data/.agent-docs/topics/agent-discovery.md +96 -0
- data/.agent-docs/topics/enterprise-ready.md +139 -0
- data/.agent-docs/topics/extensions.md +260 -0
- data/.agent-docs/topics/key-concepts.md +99 -0
- data/.agent-docs/topics/life-of-a-task.md +255 -0
- data/.agent-docs/topics/streaming-and-async.md +111 -0
- data/.agent-docs/topics/what-is-a2a.md +218 -0
- data/.agent-docs/tutorials/index.md +31 -0
- data/.agent-docs/tutorials/python/1-introduction.md +32 -0
- data/.agent-docs/tutorials/python/2-setup.md +55 -0
- data/.agent-docs/tutorials/python/3-agent-skills-and-card.md +48 -0
- data/.agent-docs/tutorials/python/4-agent-executor.md +57 -0
- data/.agent-docs/tutorials/python/5-start-server.md +55 -0
- data/.agent-docs/tutorials/python/6-interact-with-server.md +95 -0
- data/.agent-docs/tutorials/python/7-streaming-and-multiturn.md +97 -0
- data/.agent-docs/tutorials/python/8-next-steps.md +40 -0
- data/.agent-docs/types.ts +1544 -0
- data/.agent-docs/types_mapping.md +196 -0
- data/.claude/commands/gemfile/update.md +52 -0
- data/.claude/settings.local.json +23 -0
- data/.tool-versions +1 -1
- data/CHANGELOG.md +68 -1
- data/CLAUDE.md +98 -0
- data/README.md +20 -14
- data/Rakefile +1 -3
- data/WARP.md +115 -0
- data/lib/a2a/extensions/json_deserialization.rb +1 -3
- data/lib/a2a/types/agent_capabilities.rb +3 -0
- data/lib/a2a/types/agent_card.rb +49 -17
- data/lib/a2a/types/agent_card_signature.rb +17 -0
- data/lib/a2a/types/agent_extension.rb +19 -0
- data/lib/a2a/types/agent_interface.rb +13 -0
- data/lib/a2a/types/agent_provider.rb +2 -2
- data/lib/a2a/types/agent_skill.rb +11 -4
- data/lib/a2a/types/api_key_security_scheme.rb +15 -0
- data/lib/a2a/types/artifact.rb +10 -15
- data/lib/a2a/types/authenticated_extended_card_not_configured_error.rb +43 -0
- data/lib/a2a/types/authorization_code_oauth_flow.rb +22 -0
- data/lib/a2a/types/cancel_task_request.rb +5 -2
- data/lib/a2a/types/cancel_task_response.rb +3 -3
- data/lib/a2a/types/client_credentials_oauth_flow.rb +16 -0
- data/lib/a2a/types/content_type_not_supported_error.rb +42 -0
- data/lib/a2a/types/data_part.rb +5 -8
- data/lib/a2a/types/delete_task_push_notification_config_params.rb +9 -0
- data/lib/a2a/types/delete_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/delete_task_push_notification_config_response.rb +13 -0
- data/lib/a2a/types/error.rb +19 -0
- data/lib/a2a/types/error_codes.rb +6 -0
- data/lib/a2a/types/file_base.rb +12 -0
- data/lib/a2a/types/file_part.rb +7 -9
- data/lib/a2a/types/file_with_bytes.rb +9 -0
- data/lib/a2a/types/file_with_uri.rb +9 -0
- data/lib/a2a/types/get_authenticated_extended_card_request.rb +15 -0
- data/lib/a2a/types/get_authenticated_extended_card_response.rb +13 -0
- data/lib/a2a/types/get_task_push_notification_config_params.rb +9 -0
- data/lib/a2a/types/get_task_push_notification_config_request.rb +21 -0
- data/lib/a2a/types/get_task_push_notification_request.rb +5 -2
- data/lib/a2a/types/get_task_push_notification_response.rb +4 -4
- data/lib/a2a/types/get_task_request.rb +5 -2
- data/lib/a2a/types/get_task_response.rb +3 -3
- data/lib/a2a/types/http_auth_security_scheme.rb +18 -0
- data/lib/a2a/types/implicit_oauth_flow.rb +16 -0
- data/lib/a2a/types/invalid_agent_response_error.rb +41 -0
- data/lib/a2a/types/list_task_push_notification_config_params.rb +8 -0
- data/lib/a2a/types/list_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/list_task_push_notification_config_response.rb +13 -0
- data/lib/a2a/types/message.rb +24 -4
- data/lib/a2a/types/message_send_configuration.rb +20 -0
- data/lib/a2a/types/message_send_params.rb +16 -0
- data/lib/a2a/types/mutual_tls_security_scheme.rb +9 -0
- data/lib/a2a/types/oauth2_security_scheme.rb +16 -0
- data/lib/a2a/types/oauth_flows.rb +20 -0
- data/lib/a2a/types/openid_connect_security_scheme.rb +12 -0
- data/lib/a2a/types/part.rb +2 -1
- data/lib/a2a/types/part_base.rb +9 -0
- data/lib/a2a/types/password_oauth_flow.rb +16 -0
- data/lib/a2a/types/push_notification_authentication_info.rb +12 -0
- data/lib/a2a/types/push_notification_config.rb +11 -6
- data/lib/a2a/types/push_notification_not_supported_error.rb +37 -10
- data/lib/a2a/types/request.rb +15 -0
- data/lib/a2a/types/security_scheme.rb +11 -0
- data/lib/a2a/types/security_scheme_base.rb +9 -0
- data/lib/a2a/types/send_message_request.rb +18 -0
- data/lib/a2a/types/send_message_response.rb +13 -0
- data/lib/a2a/types/send_streaming_message_request.rb +18 -0
- data/lib/a2a/types/send_streaming_message_response.rb +15 -0
- data/lib/a2a/types/set_task_push_notification_config_request.rb +18 -0
- data/lib/a2a/types/set_task_push_notification_request.rb +5 -2
- data/lib/a2a/types/set_task_push_notification_response.rb +4 -4
- data/lib/a2a/types/task.rb +15 -11
- data/lib/a2a/types/task_artifact_update_event.rb +18 -7
- data/lib/a2a/types/task_not_cancelable_error.rb +37 -10
- data/lib/a2a/types/task_not_found_error.rb +37 -10
- data/lib/a2a/types/task_resubscription_request.rb +5 -2
- data/lib/a2a/types/task_state.rb +2 -1
- data/lib/a2a/types/task_status_update_event.rb +13 -6
- data/lib/a2a/types/text_part.rb +5 -8
- data/lib/a2a/types/transport_protocol.rb +6 -0
- data/lib/a2a/types/unsupported_operation_error.rb +37 -10
- data/lib/a2a/types.rb +13 -0
- data/lib/a2a/version.rb +1 -1
- data/lib/a2a.rb +15 -5
- metadata +101 -19
- data/lib/a2a/types/agent_authentication.rb +0 -13
- data/lib/a2a/types/authentication_info.rb +0 -9
- data/lib/a2a/types/file_content.rb +0 -18
- data/lib/a2a/types/internal_error.rb +0 -15
- data/lib/a2a/types/invalid_params_error.rb +0 -15
- data/lib/a2a/types/invalid_request_error.rb +0 -15
- data/lib/a2a/types/json_parse_error.rb +0 -15
- data/lib/a2a/types/jsonrpc_error.rb +0 -15
- data/lib/a2a/types/jsonrpc_message.rb +0 -12
- data/lib/a2a/types/jsonrpc_request.rb +0 -15
- data/lib/a2a/types/jsonrpc_response.rb +0 -12
- data/lib/a2a/types/method_not_found_error.rb +0 -15
- data/lib/a2a/types/send_task_request.rb +0 -15
- data/lib/a2a/types/send_task_response.rb +0 -13
- data/lib/a2a/types/send_task_streaming_request.rb +0 -15
- data/lib/a2a/types/send_task_streaming_response.rb +0 -15
- data/lib/a2a/types/task_send_params.rb +0 -26
@@ -0,0 +1,99 @@
|
|
1
|
+
# Core Concepts and Components in A2A
|
2
|
+
|
3
|
+
A2A uses a set of core concepts that define how agents interact.
|
4
|
+
Understand these core building blocks to develop or integrate with A2A-compliant
|
5
|
+
systems.
|
6
|
+
|
7
|
+
{ width="70%" style="margin:20px auto;display:block;" }
|
8
|
+
|
9
|
+
## Core Actors in A2A Interactions
|
10
|
+
|
11
|
+
- **User**: The end user, which can be a human operator or an automated
|
12
|
+
service. The user initiates a request or defines a goal that requires
|
13
|
+
assistance from one or more AI agents.
|
14
|
+
- **A2A Client (Client Agent)**: An application, service, or another AI agent
|
15
|
+
that acts on behalf of the user. The client initiates communication using the
|
16
|
+
A2A protocol.
|
17
|
+
- **A2A Server (Remote Agent)**: An AI agent or an agentic system that exposes
|
18
|
+
an HTTP endpoint implementing the A2A protocol. It receives requests from
|
19
|
+
clients, processes tasks, and returns results or status updates. From the client's perspective,
|
20
|
+
the remote agent operates as an _opaque_ (black-box) system, meaning its internal workings, memory, or tools are not exposed.
|
21
|
+
|
22
|
+
## Fundamental Communication Elements
|
23
|
+
|
24
|
+
The following table describes the fundamental communication elements in A2A:
|
25
|
+
|
26
|
+
| Element | Description | Key Purpose |
|
27
|
+
| :------ | :---------- | :---------- |
|
28
|
+
| Agent Card | A JSON metadata document describing an agent's identity, capabilities, endpoint, skills, and authentication requirements. | Enables clients to discover agents and understand how to interact with them securely and effectively. |
|
29
|
+
| Task | A stateful unit of work initiated by an agent, with a unique ID and defined lifecycle. | Facilitates tracking of long-running operations and enables multi-turn interactions and collaboration. |
|
30
|
+
| Message | A single turn of communication between a client and an agent, containing content and a role ("user" or "agent"). | Conveys instructions, context, questions, answers, or status updates that are not necessarily formal artifacts. |
|
31
|
+
| Part | The fundamental content container (for example, TextPart, FilePart, DataPart) used within Messages and Artifacts. | Provides flexibility for agents to exchange various content types within messages and artifacts. |
|
32
|
+
| Artifact | A tangible output generated by an agent during a task (for example, a document, image, or structured data). | Delivers the concrete results of an agent's work, ensuring structured and retrievable outputs. |
|
33
|
+
|
34
|
+
## Interaction Mechanisms
|
35
|
+
|
36
|
+
The A2A Protocol supports various interaction patterns to accommodate different
|
37
|
+
needs for responsiveness and persistence. These mechanisms ensure that agents
|
38
|
+
can exchange information efficiently and reliably, regardless of the task's
|
39
|
+
complexity or duration:
|
40
|
+
|
41
|
+
- **Request/Response (Polling)**: Clients send a request and the server
|
42
|
+
responds. For long-running tasks, the client periodically polls the server
|
43
|
+
for updates.
|
44
|
+
- **Streaming with Server-Sent Events (SSE)**: Clients initiate a stream to
|
45
|
+
receive real-time, incremental results or status updates from the server
|
46
|
+
over an open HTTP connection.
|
47
|
+
- **Push Notifications**: For very long-running tasks or disconnected
|
48
|
+
scenarios, the server can actively send asynchronous notifications to a
|
49
|
+
client-provided webhook when significant task updates occur.
|
50
|
+
|
51
|
+
For a detailed exploration of streaming and push notifications, refer to the
|
52
|
+
[Streaming & Asynchronous Operations](./streaming-and-async.md) document.
|
53
|
+
|
54
|
+
## Agent Cards
|
55
|
+
|
56
|
+
The Agent Card is a JSON document that serves as a digital business card for
|
57
|
+
initial discovery and interaction setup. It provides essential metadata about an
|
58
|
+
agent. Clients parse this information to determine if an agent is suitable for a
|
59
|
+
given task, how to structure requests, and how to communicate securely. Key
|
60
|
+
information includes identity, service endpoint (URL), A2A capabilities,
|
61
|
+
authentication requirements, and a list of skills.
|
62
|
+
|
63
|
+
## Messages and Parts
|
64
|
+
|
65
|
+
A message represents a single turn of communication between a client and an
|
66
|
+
agent. It includes a role ("user" or "agent") and a unique `messageId`. It
|
67
|
+
contains one or more Part objects, which are granular containers for the actual
|
68
|
+
content. This design allows A2A to be modality independent.
|
69
|
+
|
70
|
+
The primary part kinds are:
|
71
|
+
|
72
|
+
- `TextPart`: Contains plain textual content.
|
73
|
+
- `FilePart`: Represents a file. It can be transmitted either inline (Base64
|
74
|
+
encoded) or through a URI. It includes metadata like "filename" and "mimeType".
|
75
|
+
- `DataPart`: Carries structured JSON data. This is useful for forms,
|
76
|
+
parameters, or any machine-readable information.
|
77
|
+
|
78
|
+
## Artifacts
|
79
|
+
|
80
|
+
An artifact represents a tangible output or a concrete result generated by a
|
81
|
+
remote agent during task processing. Unlike general messages, artifacts are the
|
82
|
+
actual deliverables. An artifact has a unique `artifactId`, a human-readable
|
83
|
+
name, and consists of one or more part objects. Artifacts are closely tied to the
|
84
|
+
task lifecycle and can be streamed incrementally to the client.
|
85
|
+
|
86
|
+
## Agent Response: Task or Message
|
87
|
+
|
88
|
+
The agent response can be a new `Task` (when the agent needs to perform a
|
89
|
+
long-running operation) or a `Message` (when the agent can respond immediately).
|
90
|
+
|
91
|
+
For more details, see [Life of a Task](./life-of-a-task.md).
|
92
|
+
|
93
|
+
## Other Important Concepts
|
94
|
+
|
95
|
+
- **Context (`contextId`):** A server-generated identifier that can be used to logically group multiple related `Task` objects, providing context across a series of interactions.
|
96
|
+
- **Transport and Format:** A2A communication occurs over HTTP(S). JSON-RPC 2.0 is used as the payload format for all requests and responses.
|
97
|
+
- **Authentication & Authorization:** A2A relies on standard web security practices. Authentication requirements are declared in the Agent Card, and credentials (e.g., OAuth tokens, API keys) are typically passed through HTTP headers, separate from the A2A protocol messages themselves. For more information, see [Enterprise-Ready Features](./enterprise-ready.md).
|
98
|
+
- **Agent Discovery:** The process by which clients find Agent Cards to learn about available A2A Servers and their capabilities. For more information, see [Agent Discovery](./agent-discovery.md).
|
99
|
+
- **Extensions:** A2A allows agents to declare custom protocol extensions as part of their AgentCard. For more information, see [Extensions](./extensions.md).
|
@@ -0,0 +1,255 @@
|
|
1
|
+
# Life of a Task
|
2
|
+
|
3
|
+
In the Agent2Agent (A2A) Protocol, interactions can range from simple, stateless
|
4
|
+
exchanges to complex, long-running processes. When an agent receives a message
|
5
|
+
from a client, it can respond in one of two fundamental ways:
|
6
|
+
|
7
|
+
- **Respond with a Stateless `Message`**: This type of response is
|
8
|
+
typically used for immediate, self-contained interactions that conclude
|
9
|
+
without requiring further state management.
|
10
|
+
- **Initiate a Stateful `Task`**: If the response is a `Task`, the agent will
|
11
|
+
process it through a defined lifecycle, communicating progress and requiring
|
12
|
+
input as needed, until it reaches an interrupted state (e.g.,
|
13
|
+
`input-required`, `auth-required`) or a terminal state (e.g., `completed`,
|
14
|
+
`canceled`, `rejected`, `failed`).
|
15
|
+
|
16
|
+
## Group Related Interactions
|
17
|
+
|
18
|
+
A `contextId` is a crucial identifier that logically groups multiple `Task`
|
19
|
+
objects and independent `Message` objects, providing continuity across a series of
|
20
|
+
interactions.
|
21
|
+
|
22
|
+
- When a client sends a message for the first time, the agent responds
|
23
|
+
with a new `contextId`. If a task is initiated, it will also have a `taskId`.
|
24
|
+
- Clients can send subsequent messages and include the same `contextId` to
|
25
|
+
indicate that they are continuing their previous interaction within the same
|
26
|
+
context.
|
27
|
+
- Clients optionally attach the `taskId` to a subsequent message to
|
28
|
+
indicate that it continues that specific task.
|
29
|
+
|
30
|
+
The `contextId` enables collaboration towards a common goal or a shared
|
31
|
+
contextual session across multiple, potentially concurrent tasks. Internally, an
|
32
|
+
A2A agent (especially one using an LLM) uses the `contextId` to manage its internal
|
33
|
+
conversational state or its LLM context.
|
34
|
+
|
35
|
+
## Agent Response: Message or Task
|
36
|
+
|
37
|
+
The choice between responding with a `Message` or a `Task` depends on the
|
38
|
+
nature of the interaction and the agent's capabilities:
|
39
|
+
|
40
|
+
- **Messages for Trivial Interactions**: `Message` objects are suitable for
|
41
|
+
transactional interactions that don't require long-running
|
42
|
+
processing or complex state management. An agent might use messages to
|
43
|
+
negotiate the acceptance or scope of a task before committing to a `Task`
|
44
|
+
object.
|
45
|
+
- **Tasks for Stateful Interactions**: Once an agent maps the intent of an
|
46
|
+
incoming message to a supported capability that requires substantial,
|
47
|
+
trackable work over an extended period, the agent responds with a `Task`
|
48
|
+
object.
|
49
|
+
|
50
|
+
Conceptually, agents operate at different levels of complexity:
|
51
|
+
|
52
|
+
- **Message-only Agents**: Always respond with `Message` objects. They
|
53
|
+
typically don't manage complex state or long-running executions, and use
|
54
|
+
`contextId` to tie messages together. These agents might directly wrap LLM
|
55
|
+
invocations and simple tools.
|
56
|
+
- **Task-generating Agents**: Always respond with `Task` objects, even for
|
57
|
+
responses, which are then modeled as completed tasks. Once a task is
|
58
|
+
created, the agent will only return `Task` objects in response to messages
|
59
|
+
sent, and once a task is complete, no more messages can be sent. This
|
60
|
+
approach avoids deciding between `Task` versus `Message`, but creates completed task objects
|
61
|
+
for even simple interactions.
|
62
|
+
- **Hybrid Agents**: Generate both `Message` and `Task` objects. These agents
|
63
|
+
use messages to negotiate agent capability and the scope of work for a task,
|
64
|
+
then send a `Task` object to track execution and manage states like
|
65
|
+
`input-required` or error handling. Once a task is created, the agent will
|
66
|
+
only return `Task` objects in response to messages sent, and once a task is
|
67
|
+
complete, no more messages can be sent. A hybrid agent uses messages to
|
68
|
+
negotiate the scope of a task, and then generate a task to track its
|
69
|
+
execution.
|
70
|
+
For more information about hybrid agents, see [A2A protocol: Demystifying Tasks vs Messages](https://discuss.google.dev/t/a2a-protocol-demystifying-tasks-vs-messages/255879).
|
71
|
+
|
72
|
+
## Task Refinements
|
73
|
+
|
74
|
+
Clients often need to send new requests based on task results or refine the
|
75
|
+
outputs of previous tasks. This is modeled by starting another interaction using
|
76
|
+
the same `contextId` as the original task. Clients further hint the agent by
|
77
|
+
providing references to the original task using `referenceTaskIds` in the
|
78
|
+
`Message` object. The agent then responds with either a new `Task` or a
|
79
|
+
`Message`.
|
80
|
+
|
81
|
+
## Task Immutability
|
82
|
+
|
83
|
+
Once a task reaches a terminal state (completed, canceled, rejected, or failed),
|
84
|
+
it cannot restart. Any subsequent interaction related to that task, such as a
|
85
|
+
refinement, must initiate a new task within the same `contextId`. This principle
|
86
|
+
offers several benefits:
|
87
|
+
|
88
|
+
- **Task Immutability.** Clients reliably reference tasks and their
|
89
|
+
associated state, artifacts, and messages, providing a clean mapping of
|
90
|
+
inputs to outputs. This is valuable for orchestration and traceability.
|
91
|
+
- **Clear Unit of Work.** Every new request, refinement, or follow-up becomes
|
92
|
+
a distinct task. This simplifies bookkeeping, allows for granular tracking
|
93
|
+
of an agent's work, and enables tracing each artifact to a specific unit of
|
94
|
+
work.
|
95
|
+
- **Easier Implementation.** This removes ambiguity for agent developers
|
96
|
+
regarding whether to create a new task or restart an existing one.
|
97
|
+
|
98
|
+
## Parallel Follow-ups
|
99
|
+
|
100
|
+
A2A supports parallel work by enabling agents to create distinct, parallel
|
101
|
+
tasks for each follow-up message sent within the same `contextId`. This allows
|
102
|
+
clients to track individual tasks and create new dependent tasks as soon as a
|
103
|
+
prerequisite task is complete.
|
104
|
+
|
105
|
+
For example:
|
106
|
+
|
107
|
+
- Task 1: Book a flight to Helsinki.
|
108
|
+
- Task 2: Based on Task 1, book a hotel.
|
109
|
+
- Task 3: Based on Task 1, book a snowmobile activity.
|
110
|
+
- Task 4: Based on Task 2, add a spa reservation to the hotel booking.
|
111
|
+
|
112
|
+
## Referencing Previous Artifacts
|
113
|
+
|
114
|
+
The serving agent infers the relevant artifact from a referenced task or from the
|
115
|
+
`contextId`. As the domain expert, the serving agent is best suited to resolve
|
116
|
+
ambiguity or identify missing information. If there is ambiguity, the agent asks
|
117
|
+
the client for clarification by returning an `input-required` state. The client
|
118
|
+
then specifies the artifact in its response, optionally populating artifact
|
119
|
+
references (`artifactId`, `taskId`) in `Part` metadata.
|
120
|
+
|
121
|
+
## Tracking Artifact Mutation
|
122
|
+
|
123
|
+
Follow-up or refinement tasks often lead to the creation of new artifacts based on older ones. Tracking these mutations is important to ensure that only the most recent version of an artifact is used in subsequent interactions. This could be conceptualized as a version history, where each new artifact is linked to its predecessor.
|
124
|
+
|
125
|
+
However, the client is in the best position to manage this artifact linkage. The client determines what constitutes an acceptable result and has the ability to accept or reject new versions. Therefore, the serving agent shouldn't be responsible for tracking artifact mutations, and this linkage is not part of the A2A protocol specification. Clients should maintain this version history on their end and present the latest acceptable version to the user.
|
126
|
+
|
127
|
+
To facilitate client-side tracking, serving agents should use a consistent `artifact-name` when generating a refined version of an existing artifact.
|
128
|
+
|
129
|
+
When initiating follow-up or refinement tasks, the client should explicitly reference the specific artifact they intend to refine, ideally the "latest" version from their perspective. If the artifact reference is not provided, the serving agent can:
|
130
|
+
|
131
|
+
- Attempt to infer the intended artifact based on the current `contextId`.
|
132
|
+
- If there is ambiguity or insufficient context, the agent should respond with an `input-required` task state to request clarification from the client.
|
133
|
+
|
134
|
+
## Example Follow-up Scenario
|
135
|
+
|
136
|
+
The following example illustrates a typical task flow with a follow-up:
|
137
|
+
|
138
|
+
1. Client sends a message to the agent:
|
139
|
+
|
140
|
+
```json
|
141
|
+
{
|
142
|
+
"jsonrpc": "2.0",
|
143
|
+
"id": "req-001",
|
144
|
+
"method": "message.send",
|
145
|
+
"params": {
|
146
|
+
"message": {
|
147
|
+
"role": "user",
|
148
|
+
"parts": [
|
149
|
+
{
|
150
|
+
"kind": "text",
|
151
|
+
"text": "Generate an image of a sailboat on the ocean."
|
152
|
+
}
|
153
|
+
]
|
154
|
+
"messageId": "msg-user-001"
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
```
|
159
|
+
|
160
|
+
2. Agent responds with a boat image (completed task):
|
161
|
+
|
162
|
+
```json
|
163
|
+
{
|
164
|
+
"jsonrpc": "2.0",
|
165
|
+
"id": "req-001",
|
166
|
+
"result": {
|
167
|
+
"id": "task-boat-gen-123",
|
168
|
+
"contextId": "ctx-conversation-abc",
|
169
|
+
"status": {
|
170
|
+
"state": "completed"
|
171
|
+
},
|
172
|
+
"artifacts": [
|
173
|
+
{
|
174
|
+
"artifactId": "artifact-boat-v1-xyz",
|
175
|
+
"name": "sailboat_image.png",
|
176
|
+
"description": "A generated image of a sailboat on the ocean.",
|
177
|
+
"parts": [
|
178
|
+
{
|
179
|
+
"kind": "file",
|
180
|
+
"file": {
|
181
|
+
"name": "sailboat_image.png",
|
182
|
+
"mimeType": "image/png",
|
183
|
+
"bytes": "base64_encoded_png_data_of_a_sailboat"
|
184
|
+
}
|
185
|
+
}
|
186
|
+
]
|
187
|
+
}
|
188
|
+
],
|
189
|
+
"kind": "task"
|
190
|
+
}
|
191
|
+
}
|
192
|
+
```
|
193
|
+
|
194
|
+
3. Client asks to color the boat red. This refinement request refers to the
|
195
|
+
previous `taskId` and uses the same `contextId`.
|
196
|
+
|
197
|
+
```json
|
198
|
+
{
|
199
|
+
"jsonrpc": "2.0",
|
200
|
+
"id": "req-002",
|
201
|
+
"method": "message.send",
|
202
|
+
"params": {
|
203
|
+
"message": {
|
204
|
+
"role": "user",
|
205
|
+
"messageId": "msg-user-002",
|
206
|
+
"contextId": "ctx-conversation-abc",
|
207
|
+
"referenceTaskIds": [
|
208
|
+
"task-boat-gen-123"
|
209
|
+
],
|
210
|
+
"parts": [
|
211
|
+
{
|
212
|
+
"kind": "text",
|
213
|
+
"text": "Please modify the sailboat to be red."
|
214
|
+
}
|
215
|
+
]
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
```
|
220
|
+
|
221
|
+
4. Agent responds with a new image artifact (new task, same context, updated
|
222
|
+
artifact name): The agent creates a new task within the same `contextId`. The
|
223
|
+
new boat image artifact retains the same name but has a new `artifactId`.
|
224
|
+
|
225
|
+
```json
|
226
|
+
{
|
227
|
+
"jsonrpc": "2.0",
|
228
|
+
"id": "req-002",
|
229
|
+
"result": {
|
230
|
+
"id": "task-boat-color-456",
|
231
|
+
"contextId": "ctx-conversation-abc",
|
232
|
+
"status": {
|
233
|
+
"state": "completed"
|
234
|
+
},
|
235
|
+
"artifacts": [
|
236
|
+
{
|
237
|
+
"artifactId": "artifact-boat-v2-red-pqr",
|
238
|
+
"name": "sailboat_image.png",
|
239
|
+
"description": "A generated image of a red sailboat on the ocean.",
|
240
|
+
"parts": [
|
241
|
+
{
|
242
|
+
"kind": "file",
|
243
|
+
"file": {
|
244
|
+
"name": "sailboat_image.png",
|
245
|
+
"mimeType": "image/png",
|
246
|
+
"bytes": "base64_encoded_png_data_of_a_RED_sailboat"
|
247
|
+
}
|
248
|
+
}
|
249
|
+
]
|
250
|
+
}
|
251
|
+
],
|
252
|
+
"kind": "task"
|
253
|
+
}
|
254
|
+
}
|
255
|
+
```
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# Streaming and Asynchronous Operations for Long-Running Tasks
|
2
|
+
|
3
|
+
The Agent2Agent (A2A) protocol is explicitly designed to handle tasks that might not complete immediately. Many AI-driven operations are often long-running, involve multiple steps, produce incremental results, or require human intervention. A2A provides mechanisms for managing such asynchronous interactions, ensuring that clients receive updates effectively, whether they remain continuously connected or operate in a more disconnected fashion.
|
4
|
+
|
5
|
+
## Streaming with Server-Sent Events (SSE)
|
6
|
+
|
7
|
+
For tasks that produce incremental results (like generating a long document or streaming media) or provide ongoing status updates, A2A supports real-time communication using Server-Sent Events (SSE). This approach is ideal when the client is able to maintain an active HTTP connection with the A2A Server.
|
8
|
+
|
9
|
+
The following key features detail how SSE streaming is implemented and managed within the A2A protocol:
|
10
|
+
|
11
|
+
- **Server Capability:** The A2A Server must indicate its support for streaming by setting `capabilities.streaming: true` in its Agent Card.
|
12
|
+
|
13
|
+
- **Initiating a Stream:** The client uses the `message/stream` RPC method to send an initial message (for example, a prompt or command) and simultaneously subscribe to updates for that task.
|
14
|
+
|
15
|
+
- **Server Response and Connection:** If the subscription is successful, the server responds with an HTTP 200 OK status and a `Content-Type: text/event-stream`. This HTTP connection remains open for the server to push events to the client.
|
16
|
+
|
17
|
+
- **Event Structure and Types:** The server sends events over this stream. Each event's `data` field contains a JSON-RPC 2.0 Response object, typically a `SendStreamingMessageResponse`. The `result` field of the `SendStreamingMessageResponse` contains:
|
18
|
+
|
19
|
+
- [`Task`](../specification.md#61-task-object): Represents the current state of the work.
|
20
|
+
- [`TaskStatusUpdateEvent`](../specification.md#722-taskstatusupdateevent-object): Communicates changes in the task's lifecycle state (for example, from `working` to `input-required` or `completed`). It also provides intermediate messages from the agent.
|
21
|
+
- [`TaskArtifactUpdateEvent`](../specification.md#723-taskartifactupdateevent-object): Delivers new or updated Artifacts generated by the task. This is used to stream large files or data structures in chunks, with fields like `append` and `lastChunk` to help reassemble.
|
22
|
+
|
23
|
+
- **Stream Termination:** The server signals the end of updates for a cycle by setting `final: true` in a `TaskStatusUpdateEvent`. This typically occurs when the task reaches a terminal state. After this, the server usually closes the SSE connection.
|
24
|
+
|
25
|
+
- **Resubscription:** If a client's SSE connection breaks prematurely while a task is still active, the client is able to attempt to reconnect to the stream using the `tasks/resubscribe` RPC method.
|
26
|
+
|
27
|
+
### When to Use Streaming
|
28
|
+
|
29
|
+
Streaming with SSE is best suited for:
|
30
|
+
|
31
|
+
- Real-time progress monitoring of long-running tasks.
|
32
|
+
- Receiving large results (artifacts) incrementally.
|
33
|
+
- Interactive, conversational exchanges where immediate feedback or partial responses are beneficial.
|
34
|
+
- Applications requiring low-latency updates from the agent.
|
35
|
+
|
36
|
+
### Protocol Specification References
|
37
|
+
|
38
|
+
Refer to the Protocol Specification for detailed structures:
|
39
|
+
|
40
|
+
- [`message/stream`](../specification.md#72-messagestream)
|
41
|
+
- [`tasks/resubscribe`](../specification.md#79-tasksresubscribe)
|
42
|
+
|
43
|
+
## Push Notifications for Disconnected Scenarios
|
44
|
+
|
45
|
+
For very long-running tasks (for example, lasting minutes, hours, or even days) or when clients are unable to or prefer not to maintain persistent connections (like mobile clients or serverless functions), A2A supports asynchronous updates using push notifications. This allows the A2A Server to actively notify a client-provided webhook when a significant task update occurs.
|
46
|
+
|
47
|
+
The following key features detail how push notifications are implemented and managed within the A2A protocol:
|
48
|
+
|
49
|
+
- **Server Capability:** The A2A Server must indicate its support for this feature by setting `capabilities.pushNotifications: true` in its Agent Card.
|
50
|
+
- **Configuration:** The client provides a [`PushNotificationConfig`](../specification.md#68-pushnotificationconfig-object) to the server. This configuration is supplied:
|
51
|
+
- Within the initial `message/send` or `message/stream` request, or
|
52
|
+
- Separately, using the `tasks/pushNotificationConfig/set` RPC method for an existing task.
|
53
|
+
The `PushNotificationConfig` includes a `url` (the HTTPS webhook URL), an optional `token` (for client-side validation), and optional `authentication` details (for the A2A Server to authenticate to the webhook).
|
54
|
+
- **Notification Trigger:** The A2A Server decides when to send a push notification, typically when a task reaches a significant state change (for example, terminal state, `input-required`, or `auth-required`).
|
55
|
+
- **Notification Payload:** The A2A protocol does not strictly define the HTTP body payload, but it SHOULD contain sufficient information for the client to identify the Task ID and understand the general nature of the update (for example, the new `TaskState`).
|
56
|
+
- **Client Action:** Upon receiving a push notification (and successfully verifying its authenticity), the client typically uses the `tasks/get` RPC method with the `taskId` from the notification to retrieve the complete, updated `Task` object, including any new artifacts.
|
57
|
+
|
58
|
+
### When to Use Push Notifications
|
59
|
+
|
60
|
+
Push notifications are ideal for:
|
61
|
+
|
62
|
+
- Very long-running tasks that can take minutes, hours, or days to complete.
|
63
|
+
- Clients that cannot or prefer not to maintain persistent connections, such as mobile applications or serverless functions.
|
64
|
+
- Scenarios where clients only need to be notified of significant state changes rather than continuous updates.
|
65
|
+
|
66
|
+
### Protocol Specification References
|
67
|
+
|
68
|
+
Refer to the Protocol Specification for detailed structures:
|
69
|
+
|
70
|
+
- [`tasks/pushNotificationConfig/set`](../specification.md#75-taskspushnotificationconfigset)
|
71
|
+
- [`tasks/get`](../specification.md#76-taskspushnotificationconfigget)
|
72
|
+
|
73
|
+
### Client-Side Push Notification Service
|
74
|
+
|
75
|
+
The `url` specified in `PushNotificationConfig.url` points to a client-side Push Notification Service. This service is responsible for receiving the HTTP POST notification from the A2A Server. Its responsibilities include authenticating the incoming notification, validating its relevance, and relaying the notification or its content to the appropriate client application logic or system.
|
76
|
+
|
77
|
+
### Security Considerations for Push Notifications
|
78
|
+
|
79
|
+
Security is paramount for push notifications due to their asynchronous and server-initiated outbound nature. Both the A2A Server (sending the notification) and the client's webhook receiver have critical responsibilities.
|
80
|
+
|
81
|
+
#### A2A Server Security (when sending notifications to client webhook)
|
82
|
+
|
83
|
+
- **Webhook URL Validation:** Servers SHOULD NOT blindly trust and send POST requests to any URL provided by a client. Malicious clients could provide URLs pointing to internal services or unrelated third-party systems, leading to Server-Side Request Forgery (SSRF) attacks or acting as Distributed Denial of Service (DDoS) amplifiers.
|
84
|
+
- **Mitigation strategies:** Allowlisting of trusted domains, ownership verification (for example, challenge-response mechanisms), and network controls (e.g., egress firewalls).
|
85
|
+
- **Authenticating to the Client's Webhook:** The A2A Server MUST authenticate itself to the client's webhook URL according to the scheme(s) specified in `PushNotificationConfig.authentication`. Common schemes include Bearer Tokens (OAuth 2.0), API keys, HMAC signatures, or mutual TLS (mTLS).
|
86
|
+
|
87
|
+
#### Client Webhook Receiver Security (when receiving notifications from A2A server)
|
88
|
+
|
89
|
+
- **Authenticating the A2A Server:** The webhook endpoint MUST rigorously verify the authenticity of incoming notification requests to ensure they originate from the legitimate A2A Server and not an imposter.
|
90
|
+
- **Verification methods:** Verify signatures/tokens (for example, JWT signatures against the A2A Server's trusted public keys, HMAC signatures, or API key validation). Also, validate the `PushNotificationConfig.token` if provided.
|
91
|
+
- **Preventing Replay Attacks:**
|
92
|
+
- **Timestamps:** Notifications SHOULD include a timestamp. The webhook SHOULD reject notifications that are too old.
|
93
|
+
- **Nonces/unique IDs:** For critical notifications, consider using unique, single-use identifiers (for example, JWT's `jti` claim or event IDs) to prevent processing duplicate notifications.
|
94
|
+
- **Secure Key Management and Rotation:** Implement secure key management practices, including regular key rotation, especially for cryptographic keys. Protocols like JWKS (JSON Web Key Set) facilitate key rotation for asymmetric keys.
|
95
|
+
|
96
|
+
#### Example Asymmetric Key Flow (JWT + JWKS)
|
97
|
+
|
98
|
+
1. Client sets `PushNotificationConfig` specifying `authentication.schemes: ["Bearer"]` and possibly an expected `issuer` or `audience` for the JWT.
|
99
|
+
2. A2A Server, when sending a notification:
|
100
|
+
- Generates a JWT, signing it with its private key. The JWT includes claims like `iss` (issuer), `aud` (audience), `iat` (issued at), `exp` (expires), `jti` (JWT ID), and `taskId`.
|
101
|
+
- The JWT header indicates the signing algorithm and key ID (`kid`).
|
102
|
+
- The A2A Server makes its public keys available through a JWKS endpoint.
|
103
|
+
3. Client Webhook, upon receiving the notification:
|
104
|
+
- Extracts the JWT from the Authorization header.
|
105
|
+
- Inspects the `kid` (key ID) in the JWT header.
|
106
|
+
- Fetches the corresponding public key from the A2A Server's JWKS endpoint (caching keys is recommended).
|
107
|
+
- Verifies the JWT signature using the public key.
|
108
|
+
- Validates claims (`iss`, `aud`, `iat`, `exp`, `jti`).
|
109
|
+
- Checks the `PushNotificationConfig.token` if provided.
|
110
|
+
|
111
|
+
This comprehensive, layered approach to security for push notifications helps ensure that messages are authentic, integral, and timely, protecting both the sending A2A Server and the receiving client webhook infrastructure.
|