You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/migrations/v1_0/README.md
+76-51Lines changed: 76 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,11 @@ Beyond protocol support, `v1.0` enhances the developer experience by introducing
6
6
7
7
This documentation details the technical upgrades and architectural modifications introduced in A2A Python SDK v1.0. For developers using the database persistence layer, please refer to the [Database Migration Guide](database/) for specific update instructions.
8
8
9
+
> ### **Why Upgrade to v1.0?**
10
+
> ***Protocol v1.0 Compliance**: Full alignment with the latest A2A industry standard for cross-agent interoperability.
11
+
> ***Reduced Boilerplate**: Unified helper utilities that simplify common tasks like message and task creation.
12
+
> ***Architectural Flexibility**: Direct Starlette/FastAPI integration allows you to mount A2A routes into existing applications with full control over middleware.
13
+
9
14
---
10
15
11
16
## Table of Contents
@@ -55,9 +60,9 @@ pip install --upgrade a2a-sdk
55
60
Types have migrated from Pydantic models to Protobuf-based classes.
All the enum values are now standardized from snake_case to **SCREAMING_SNAKE_CASE** format.
65
+
All the enum values are now [standardised](https://a2a-protocol.org/v1.0.0/specification/#55-json-field-naming-convention)to use `SCREAMING_SNAKE_CASE` format.
61
66
62
67
This affects every enum in the SDK: `TaskState`, `Role`.
63
68
@@ -131,14 +136,14 @@ message = Message(
131
136
132
137
### AgentCard Structure
133
138
134
-
The new `AgentCard` can supports multiple transport bindings using `AgentInterface` class.
135
-
136
-
Key differences:
137
-
-`url` is gone; use `supported_interfaces` with one or more `AgentInterface` entries
138
-
-`AgentCapabilities.input_modes` and `AgentCapabilities.output_modes` are removed; use `AgentCard.default_input_modes` / `AgentCard.default_output_modes` for card-level defaults, or `AgentSkill.input_modes` / `AgentSkill.output_modes` for per-skill overrides
139
-
-`supports_authenticated_extended_card` is no longer a top-level `AgentCard` field; it has moved into `AgentCapabilities` and is renamed to `extended_agent_card`
-`examples`field was removed; set it per `AgentSkill` instead
139
+
Key changes:
140
+
- Added `AgentInterface` class to support multiple transport bindings via the `supported_interfaces` field in AgentCard.
141
+
- The `url` parameter in `AgentCapabilities` is removed and is now part of `AgentInterface`.
142
+
-Accepted values for `AgentInterface.protocol_binding`: `'JSONRPC'`, `'HTTP+JSON'`, `'GRPC'`
143
+
-The `AgentCard.capabilities` field is renamed to `AgentCard.agent_capabilities`.
144
+
-The `AgentCard.supports_authenticated_extended_card` fieldis renamed to `AgentCapabilities.extended_agent_card`.
145
+
-The `AgentCapabilities.input_modes` and `AgentCapabilities.output_modes` fields are removed; use `AgentCard.default_input_modes` / `AgentCard.default_output_modes` for card-level defaults, or `AgentSkill.input_modes` / `AgentSkill.output_modes` for per-skill overrides.
146
+
-The `examples`parameter in `AgentCard` is removed and is now part of `AgentSkill`.
142
147
143
148
**Before (v0.3):**
144
149
```python
@@ -164,7 +169,7 @@ agent_card = AgentCard(
164
169
165
170
**After (v1.0):**
166
171
```python
167
-
from a2a.types import AgentCard, AgentCapabilities, AgentInterface, AgentSkill,
172
+
from a2a.types import AgentCard, AgentCapabilities, AgentInterface, AgentSkill
168
173
169
174
agent_card = AgentCard(
170
175
name='My Agent',
@@ -232,10 +237,13 @@ The wrapper classes (`A2AStarletteApplication`, `A2AFastApiApplication` and `A2A
232
237
from a2a.server.apps import A2AStarletteApplication
233
238
import uvicorn
234
239
240
+
# Create application using A2AStarletteApplication wrapper class
235
241
server = A2AStarletteApplication(
236
242
agent_card=agent_card,
237
243
http_handler=request_handler,
238
244
)
245
+
246
+
# Start the server
239
247
uvicorn.run(server.build(), host=host, port=port)
240
248
```
241
249
@@ -245,26 +253,19 @@ from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
The `BaseClient.send_message()` return type is standardised from `AsyncIterator[ClientEvent | Message]` to `AsyncIterator[StreamResponse]`.
335
+
The `BaseClient.send_message()` return type is standardised from `AsyncIterator[ClientEvent | Message]` to `AsyncIterator[StreamResponse]`.
336
336
337
-
Each `StreamResponse` yields exactly one of: `task`, `message`, `status_update`, or `artifact_update`. Use `HasField()` to check which field is set.
337
+
Each `StreamResponse` yields exactly one of: (`task`, `message`, `status_update`, or `artifact_update`). Use `HasField()` to check which field is set.
338
338
339
339
340
340
**Before (v0.3):**
@@ -368,6 +368,7 @@ async for chunk in client.send_message(request):
368
368
369
369
`ClientConfig.push_notification_config` is now **singular** (a single `TaskPushNotificationConfig` or `None`), not a list.
370
370
371
+
371
372
**Before (v0.3):**
372
373
```python
373
374
config = ClientConfig(
@@ -386,31 +387,55 @@ config = ClientConfig(
386
387
387
388
## 9. Helper Utilities
388
389
389
-
A new `a2a.helpers` module consolidates helper functions into a single import. Most were previously available under `a2a.utils.*`; a few are new in v1.0.
390
+
To improve the developer experience, we have consolidated helper functions into a single import. In v0.3, these helper functions were scattered across different modules; In v1.0, they are all available under `a2a.helpers`.
391
+
392
+
| Helper Function | Description |
393
+
|---|---|
394
+
|`display_agent_card`| Prints a human-readable summary of an `AgentCard` to stdout. |
395
+
|`get_artifact_text`| Joins all text parts of an `Artifact` into a single string (using `\n` as delimiter). |
396
+
|`get_message_text`| Joins all text parts of a `Message` into a single string (using `\n` as delimiter). |
397
+
|`get_stream_response_text`| Extracts text from a `StreamResponse` protobuf message. |
398
+
|`get_text_parts`| Returns a list of raw text strings from a sequence of `Part` objects, skipping non-text parts. |
399
+
|`new_artifact`| Creates an `Artifact` from a list of `Part` objects, a name, and an optional description and ID. |
400
+
|`new_message`| Creates a `Message` from a list of `Part` objects with a role (defaults to `ROLE_AGENT`), and optional task/context IDs. |
401
+
|`new_task`| Creates a `Task` with an explicit task ID, context ID, and state. |
402
+
|`new_task_from_user_message`| Creates a `TASK_STATE_SUBMITTED``Task` from a user `Message`. Raises an error if the role is not `ROLE_USER` or if parts are empty. |
403
+
|`new_text_artifact`| Creates an `Artifact` with a single text `Part`, a name, and an optional description and ID. |
404
+
|`new_text_artifact_update_event`| Creates a `TaskArtifactUpdateEvent` with a text artifact. |
405
+
|`new_text_message`| Creates a `Message` with a single text `Part`; role defaults to `ROLE_AGENT`. |
406
+
|`new_text_status_update_event`| Creates a `TaskStatusUpdateEvent` with a text message. |
407
+
408
+
Example Usage:
409
+
410
+
**1. Create a user message**
390
411
391
412
```python
392
-
from a2a.helpers import (
393
-
display_agent_card, # print a human-readable summary of an AgentCard to stdout
394
-
get_artifact_text, # join all text parts of an Artifact into a single string (delimiter='\n')
395
-
get_message_text, # join all text parts of a Message into a single string (delimiter='\n')
396
-
get_stream_response_text, # extract text from a StreamResponse proto message
397
-
get_text_parts, # return a list of raw text strings from a sequence of Parts (skips non-text parts)
398
-
new_artifact, # create an Artifact from a list of Parts, name, optional description and artifact_id
399
-
new_message, # create a Message from a list of Parts with role (default ROLE_AGENT), optional task_id/context_id
400
-
new_task, # create a Task with explicit task_id, context_id, and state
401
-
new_task_from_user_message, # create a TASK_STATE_SUBMITTED Task from a user Message; raises if role != ROLE_USER or parts are empty
402
-
new_text_artifact, # create an Artifact with a single text Part, name, optional description and artifact_id
403
-
new_text_artifact_update_event, # create a TaskArtifactUpdateEvent with a text artifact
404
-
new_text_message, # create a Message with a single text Part; role defaults to ROLE_AGENT
405
-
new_text_status_update_event, # create a TaskStatusUpdateEvent with a text message
406
-
)
413
+
from a2a.helpers import new_text_message
414
+
from a2a.types import Role
415
+
416
+
# Create a user message
417
+
user_message = new_text_message("What's the weather?", role=Role.ROLE_USER)
418
+
419
+
# Create an agent response message
420
+
response_message = new_text_message("It is sunny today!")
421
+
```
422
+
423
+
**2. Extract the text out of a message**
424
+
425
+
```python
426
+
from a2a.helpers import get_message_text
427
+
428
+
# Get text from a message
429
+
text = get_message_text(response_message)
430
+
print(text)
407
431
```
408
432
409
433
---
410
434
411
435
## 10. Summary of Key Changes in v1.0
412
436
413
-
-**Standardisation to `SCREAMING_SNAKE_CASE`** — All enum values have been renamed from `kebab-case` strings to `SCREAMING_SNAKE_CASE` for compliance with the ProtoJSON specification.
437
+
-**Migration to Protobuf** — Core types have migrated from Pydantic models to Protobuf-based classes. Protobuf objects do not support arbitrary attribute assignment. Use `MessageToDict` from `google.protobuf.json_format` to convert objects to dictionaries, and `HasField('field_name')` to check for optional fields.
438
+
-**Standardisation to `SCREAMING_SNAKE_CASE`** — All enum values have been renamed from `snake_case` strings to `SCREAMING_SNAKE_CASE` for compliance with the ProtoJSON specification.
414
439
-**`AgentCard`** — Significantly restructured to support multiple transport interfaces.
415
440
-**`AgentInterface`** — The top-level `url` field is replaced by `supported_interfaces`, a list of `AgentInterface` objects. Each entry describes a single transport endpoint carrying `protocol_binding`, `protocol_version`, and `url`.
416
441
-**Input and output modes** — `AgentCapabilities.input_modes` and `AgentCapabilities.output_modes` are removed and now live directly on `AgentCard` as `default_input_modes` and `default_output_modes`. Individual skills can override these with their own `input_modes` and `output_modes`.
0 commit comments