Skip to content

Commit 2a0ea56

Browse files
committed
update Part construction
1 parent 93f8269 commit 2a0ea56

1 file changed

Lines changed: 71 additions & 18 deletions

File tree

docs/migrations/v1_0/README.md

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,51 +86,104 @@ This affects every enum in the SDK: `TaskState`, `Role`.
8686
8787
### Message and Part construction
8888

89-
Constructing messages is simplified in v1.0. The old API required wrapping content in an intermediate type (`TextPart`, `FilePart`, `DataPart`) before placing it inside a `Part`. In v1.0, the wrapper types are removed and content types are set directly on the `Part`.
89+
Constructing messages is simplified in v1.0. The old API required wrapping content in an intermediate type (`TextPart`, `FilePart`, `DataPart`) before placing it inside a `Part`. In v1.0, the wrapper types are removed and all content fields are set directly on the unified `Part` message.
9090

91-
Key changes:
92-
- `Part(TextPart(text=...))``Part(text=...)` (flat union field)
93-
- `Role.user``Role.ROLE_USER`, `Role.agent``Role.ROLE_AGENT`
91+
| Part type | v0.3 | v1.0 |
92+
|---|---|---|
93+
| Text | `Part(TextPart(text=..., ...))` | `Part(text=..., ...)` |
94+
| File (bytes) | `Part(FilePart(file=FileWithBytes(bytes=..., ...)))` | `Part(raw=..., ...)` |
95+
| File (URI) | `Part(FilePart(file=FileWithUri(uri=..., ...)))` | `Part(url=..., ...)` |
96+
| Structured data | `Part(DataPart(data=..., ...))` | `Part(data=..., ...))` |
97+
98+
> **Note on file bytes**: In v0.3 `FileWithBytes.bytes` was a **base64-encoded string**. In v1.0 `Part.raw` is raw **`bytes`** — no base64 encoding needed.
99+
100+
> **Note on structured data**: In v0.3 `DataPart.data` was a plain `dict`. In v1.0 `Part.data` is a `google.protobuf.Value`, so use `ParseDict` to convert from a Python dict.
94101
95102
**Before (v0.3):**
96103
```python
97-
from a2a.types import Message, Part, Role, TextPart
104+
import base64
98105
from uuid import uuid4
106+
from a2a.types import Message, Part, Role, TextPart, FilePart, DataPart, FileWithBytes, FileWithUri
107+
108+
# Text part
109+
text_part = Part(TextPart(text="What's the weather in Warsaw?"))
110+
111+
# File part — base64-encoded bytes (e.g. an image)
112+
with open("photo.png", "rb") as f:
113+
image_b64 = base64.b64encode(f.read()).decode()
114+
file_bytes_part = Part(FilePart(file=FileWithBytes(
115+
bytes=image_b64,
116+
mime_type="image/png",
117+
name="photo.png",
118+
)))
119+
120+
# File part — URI pointing to a remote file
121+
file_uri_part = Part(FilePart(file=FileWithUri(
122+
uri="https://example.com/report.pdf",
123+
mime_type="application/pdf",
124+
name="report.pdf",
125+
)))
126+
127+
# Data part — structured JSON payload
128+
data_part = Part(DataPart(data={"city": "Warsaw", "temperature_c": 18}))
99129

100130
message = Message(
101131
role=Role.user,
102-
parts=[Part(TextPart(text="Hello"))],
132+
parts=[text_part, file_bytes_part, file_uri_part, data_part],
103133
message_id=uuid4().hex,
104134
task_id=uuid4().hex,
105135
)
106136
```
107137

108138
**After (v1.0):**
109139

110-
Using [A2A helper utilities](#9-helper-utilities)
111-
112140
```python
113-
from a2a.helpers import new_text_message
114-
from a2a.types import Role
141+
from uuid import uuid4
142+
from google.protobuf.json_format import ParseDict
143+
from google.protobuf.struct_pb2 import Value
144+
from a2a.types import Message, Part, Role
115145

116-
# Use the helper function to create `Hello` message
117-
message = new_text_message(text="Hello", role=Role.ROLE_USER)
118-
```
146+
# Text part
147+
text_part = Part(text="What's the weather in Warsaw?")
119148

120-
Without helper utils, you can still construct directly
149+
# File part — raw bytes (e.g. an image); no base64 encoding required
150+
with open("photo.png", "rb") as f:
151+
image_bytes = f.read()
152+
file_bytes_part = Part(
153+
raw=image_bytes,
154+
media_type="image/png",
155+
filename="photo.png",
156+
)
121157

122-
```python
123-
from a2a.types import Message, Part, Role
124-
from uuid import uuid4
158+
# File part — URI pointing to a remote file
159+
file_uri_part = Part(
160+
url="https://example.com/report.pdf",
161+
media_type="application/pdf",
162+
filename="report.pdf",
163+
)
164+
165+
# Data part — use ParseDict to convert a Python dict to a protobuf Value
166+
data_part = Part(
167+
data=.ParseDict({"city": "Warsaw", "temperature_c": 18}, Value()),
168+
)
125169

126170
message = Message(
127171
role=Role.ROLE_USER,
128-
parts=[Part(text="Hello")],
172+
parts=[text_part, file_bytes_part, file_uri_part, data_part],
129173
message_id=uuid4().hex,
130174
task_id=uuid4().hex,
131175
)
132176
```
133177

178+
For text-only messages, use the [A2A helper utilities](#9-helper-utilities) to reduce boilerplate:
179+
180+
```python
181+
from a2a.helpers import new_text_message
182+
from a2a.types import Role
183+
184+
message = new_text_message(text="What's the weather in Warsaw?", role=Role.ROLE_USER)
185+
```
186+
134187
> **Example**: [`helloworld/test_client.py` in PR #474](https://github.com/a2aproject/a2a-samples/pull/474/files#diff-f62c07d3b00364a3100b7effb3e2a1cca0624277d3e40da1bdb07bb46b6a8cef)
135188
136189
### AgentCard Structure

0 commit comments

Comments
 (0)