a2a-lite 0.2.4__py3-none-any.whl → 0.2.5__py3-none-any.whl
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: a2a-lite
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Simplified wrapper for Google's A2A Protocol SDK
|
|
5
5
|
Author: A2A Lite Contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -29,11 +29,14 @@ Provides-Extra: oauth
|
|
|
29
29
|
Requires-Dist: pyjwt[crypto]>=2.0; extra == 'oauth'
|
|
30
30
|
Description-Content-Type: text/markdown
|
|
31
31
|
|
|
32
|
-
# A2A Lite
|
|
32
|
+
# A2A Lite — Python
|
|
33
|
+
|
|
34
|
+
[](https://pypi.org/project/a2a-lite/)
|
|
35
|
+
[](https://github.com/xvierd/a2a-lite)
|
|
33
36
|
|
|
34
37
|
**Build A2A agents in 8 lines. Add features when you need them.**
|
|
35
38
|
|
|
36
|
-
Wraps the official [A2A Python SDK](https://github.com/a2aproject/a2a-python) with a simple,
|
|
39
|
+
Wraps the official [A2A Python SDK](https://github.com/a2aproject/a2a-python) with a simple, decorator-based API. 100% protocol-compatible.
|
|
37
40
|
|
|
38
41
|
```python
|
|
39
42
|
from a2a_lite import Agent
|
|
@@ -81,7 +84,7 @@ async def multiply(a: int, b: int) -> int:
|
|
|
81
84
|
agent.run(port=8787)
|
|
82
85
|
```
|
|
83
86
|
|
|
84
|
-
### 2. Test it
|
|
87
|
+
### 2. Test it (no HTTP needed)
|
|
85
88
|
|
|
86
89
|
```python
|
|
87
90
|
from a2a_lite import Agent, AgentTestClient
|
|
@@ -97,7 +100,7 @@ result = client.call("add", a=2, b=3)
|
|
|
97
100
|
assert result == 5
|
|
98
101
|
```
|
|
99
102
|
|
|
100
|
-
### 3. Call it
|
|
103
|
+
### 3. Call it over the network
|
|
101
104
|
|
|
102
105
|
```bash
|
|
103
106
|
curl -X POST http://localhost:8787/ \
|
|
@@ -120,7 +123,7 @@ curl -X POST http://localhost:8787/ \
|
|
|
120
123
|
|
|
121
124
|
## Progressive Complexity
|
|
122
125
|
|
|
123
|
-
### Level 1
|
|
126
|
+
### Level 1 — Basic Skills
|
|
124
127
|
|
|
125
128
|
```python
|
|
126
129
|
from a2a_lite import Agent
|
|
@@ -134,7 +137,7 @@ async def greet(name: str) -> str:
|
|
|
134
137
|
agent.run()
|
|
135
138
|
```
|
|
136
139
|
|
|
137
|
-
### Level 2
|
|
140
|
+
### Level 2 — Pydantic Models
|
|
138
141
|
|
|
139
142
|
Pass dicts from callers — they're auto-converted to Pydantic models:
|
|
140
143
|
|
|
@@ -160,7 +163,9 @@ async def count_users(users: List[User]) -> int:
|
|
|
160
163
|
return len(users)
|
|
161
164
|
```
|
|
162
165
|
|
|
163
|
-
### Level 3
|
|
166
|
+
### Level 3 — Streaming
|
|
167
|
+
|
|
168
|
+
Just `yield` instead of `return`:
|
|
164
169
|
|
|
165
170
|
```python
|
|
166
171
|
@agent.skill("chat", streaming=True)
|
|
@@ -169,7 +174,9 @@ async def chat(message: str):
|
|
|
169
174
|
yield word + " "
|
|
170
175
|
```
|
|
171
176
|
|
|
172
|
-
### Level 4
|
|
177
|
+
### Level 4 — Middleware
|
|
178
|
+
|
|
179
|
+
Cross-cutting concerns without touching skill code:
|
|
173
180
|
|
|
174
181
|
```python
|
|
175
182
|
@agent.middleware
|
|
@@ -191,7 +198,9 @@ agent.add_middleware(rate_limit_middleware(max_per_minute=60))
|
|
|
191
198
|
agent.add_middleware(retry_middleware(max_retries=3))
|
|
192
199
|
```
|
|
193
200
|
|
|
194
|
-
### Level 5
|
|
201
|
+
### Level 5 — File Handling
|
|
202
|
+
|
|
203
|
+
Accept and return files through the A2A protocol:
|
|
195
204
|
|
|
196
205
|
```python
|
|
197
206
|
from a2a_lite import FilePart
|
|
@@ -202,7 +211,9 @@ async def summarize(doc: FilePart) -> str:
|
|
|
202
211
|
return f"Summary: {content[:100]}..."
|
|
203
212
|
```
|
|
204
213
|
|
|
205
|
-
### Level 6
|
|
214
|
+
### Level 6 — Task Tracking
|
|
215
|
+
|
|
216
|
+
Long-running operations with progress updates:
|
|
206
217
|
|
|
207
218
|
```python
|
|
208
219
|
from a2a_lite import TaskContext
|
|
@@ -212,14 +223,14 @@ agent = Agent(name="Bot", description="A bot", task_store="memory")
|
|
|
212
223
|
@agent.skill("process")
|
|
213
224
|
async def process(data: str, task: TaskContext) -> str:
|
|
214
225
|
await task.update("working", "Starting...", progress=0.0)
|
|
215
|
-
|
|
216
226
|
for i in range(10):
|
|
217
227
|
await task.update("working", f"Step {i}/10", progress=i/10)
|
|
218
|
-
|
|
219
228
|
return "Done!"
|
|
220
229
|
```
|
|
221
230
|
|
|
222
|
-
### Level 7
|
|
231
|
+
### Level 7 — Authentication
|
|
232
|
+
|
|
233
|
+
API keys are hashed in memory using SHA-256 — plaintext keys are never stored.
|
|
223
234
|
|
|
224
235
|
```python
|
|
225
236
|
from a2a_lite import Agent, APIKeyAuth
|
|
@@ -231,8 +242,6 @@ agent = Agent(
|
|
|
231
242
|
)
|
|
232
243
|
```
|
|
233
244
|
|
|
234
|
-
API keys are hashed in memory using SHA-256 — plaintext keys are never stored.
|
|
235
|
-
|
|
236
245
|
Other auth providers:
|
|
237
246
|
|
|
238
247
|
```python
|
|
@@ -261,7 +270,7 @@ async def whoami(auth: AuthResult) -> dict:
|
|
|
261
270
|
return {"user": auth.identity, "scheme": auth.scheme}
|
|
262
271
|
```
|
|
263
272
|
|
|
264
|
-
### Level 8
|
|
273
|
+
### Level 8 — CORS & Production Mode
|
|
265
274
|
|
|
266
275
|
```python
|
|
267
276
|
agent = Agent(
|
|
@@ -272,12 +281,24 @@ agent = Agent(
|
|
|
272
281
|
)
|
|
273
282
|
```
|
|
274
283
|
|
|
275
|
-
### Level 9
|
|
284
|
+
### Level 9 — Lifecycle Hooks
|
|
276
285
|
|
|
277
286
|
```python
|
|
287
|
+
@agent.on_startup
|
|
288
|
+
async def startup():
|
|
289
|
+
print("Agent starting...")
|
|
290
|
+
|
|
291
|
+
@agent.on_shutdown
|
|
292
|
+
async def shutdown():
|
|
293
|
+
print("Agent stopping...")
|
|
294
|
+
|
|
278
295
|
@agent.on_complete
|
|
279
296
|
async def notify(skill_name, result, ctx):
|
|
280
297
|
print(f"Skill {skill_name} completed with: {result}")
|
|
298
|
+
|
|
299
|
+
@agent.on_error
|
|
300
|
+
async def handle_error(error: Exception):
|
|
301
|
+
return {"error": str(error), "type": type(error).__name__}
|
|
281
302
|
```
|
|
282
303
|
|
|
283
304
|
---
|
|
@@ -286,7 +307,7 @@ async def notify(skill_name, result, ctx):
|
|
|
286
307
|
|
|
287
308
|
### AgentTestClient
|
|
288
309
|
|
|
289
|
-
|
|
310
|
+
Synchronous test client for pytest:
|
|
290
311
|
|
|
291
312
|
```python
|
|
292
313
|
from a2a_lite import Agent, AgentTestClient
|
|
@@ -324,7 +345,7 @@ def test_list_skills():
|
|
|
324
345
|
|
|
325
346
|
### TestResult
|
|
326
347
|
|
|
327
|
-
Every `client.call()` returns a `TestResult
|
|
348
|
+
Every `client.call()` returns a `TestResult`:
|
|
328
349
|
|
|
329
350
|
| Property | Description |
|
|
330
351
|
|----------|-------------|
|
|
@@ -333,7 +354,7 @@ Every `client.call()` returns a `TestResult` with:
|
|
|
333
354
|
| `.json()` | Parse text as JSON (raises on invalid JSON) |
|
|
334
355
|
| `.raw_response` | Full A2A response dict |
|
|
335
356
|
|
|
336
|
-
`TestResult` supports direct equality
|
|
357
|
+
`TestResult` supports direct equality for simple values (`result == 5`), but use `.data` for subscripting (`result.data["key"]`).
|
|
337
358
|
|
|
338
359
|
### AsyncAgentTestClient
|
|
339
360
|
|
|
@@ -365,10 +386,11 @@ def test_streaming():
|
|
|
365
386
|
## CLI
|
|
366
387
|
|
|
367
388
|
```bash
|
|
368
|
-
a2a-lite init my-agent #
|
|
369
|
-
a2a-lite serve agent.py # Run agent from file
|
|
370
|
-
a2a-lite inspect http://... # View agent
|
|
371
|
-
a2a-lite test http://... skill #
|
|
389
|
+
a2a-lite init my-agent # Scaffold a new project
|
|
390
|
+
a2a-lite serve agent.py # Run an agent from file
|
|
391
|
+
a2a-lite inspect http://... # View agent card & skills
|
|
392
|
+
a2a-lite test http://... skill # Smoke-test a skill
|
|
393
|
+
a2a-lite discover # Find agents on the local network (mDNS)
|
|
372
394
|
a2a-lite version # Show version
|
|
373
395
|
```
|
|
374
396
|
|
|
@@ -427,7 +449,7 @@ Agent(
|
|
|
427
449
|
|
|
428
450
|
### Special Parameter Types
|
|
429
451
|
|
|
430
|
-
|
|
452
|
+
Auto-injected when detected in skill function signatures:
|
|
431
453
|
|
|
432
454
|
| Type | Description |
|
|
433
455
|
|------|-------------|
|
|
@@ -444,18 +466,22 @@ These are auto-injected when detected in skill function signatures:
|
|
|
444
466
|
|---------|---------------|
|
|
445
467
|
| [01_hello_world.py](examples/01_hello_world.py) | Simplest agent (8 lines) |
|
|
446
468
|
| [02_calculator.py](examples/02_calculator.py) | Multiple skills |
|
|
469
|
+
| [03_async_agent.py](examples/03_async_agent.py) | Async operations & lifecycle hooks |
|
|
470
|
+
| [04_multi_agent/](examples/04_multi_agent) | Two agents communicating |
|
|
471
|
+
| [05_with_llm.py](examples/05_with_llm.py) | OpenAI / Anthropic integration |
|
|
447
472
|
| [06_pydantic_models.py](examples/06_pydantic_models.py) | Auto Pydantic conversion |
|
|
473
|
+
| [07_middleware.py](examples/07_middleware.py) | Middleware pipeline |
|
|
448
474
|
| [08_streaming.py](examples/08_streaming.py) | Streaming responses |
|
|
449
|
-
| [09_testing.py](examples/09_testing.py) |
|
|
450
|
-
| [10_file_handling.py](examples/10_file_handling.py) |
|
|
475
|
+
| [09_testing.py](examples/09_testing.py) | Built-in TestClient |
|
|
476
|
+
| [10_file_handling.py](examples/10_file_handling.py) | File upload & processing |
|
|
451
477
|
| [11_task_tracking.py](examples/11_task_tracking.py) | Progress updates |
|
|
452
478
|
| [12_with_auth.py](examples/12_with_auth.py) | Authentication |
|
|
453
479
|
|
|
454
480
|
---
|
|
455
481
|
|
|
456
|
-
##
|
|
482
|
+
## A2A Protocol Mapping
|
|
457
483
|
|
|
458
|
-
|
|
484
|
+
Everything maps directly to the underlying protocol — no magic, no lock-in.
|
|
459
485
|
|
|
460
486
|
| A2A Lite | A2A Protocol |
|
|
461
487
|
|----------|--------------|
|
|
@@ -464,6 +490,7 @@ A2A Lite wraps the official A2A Python SDK. Every feature maps to real A2A proto
|
|
|
464
490
|
| `TaskContext.update()` | Task lifecycle states |
|
|
465
491
|
| `FilePart` | A2A File parts |
|
|
466
492
|
| `DataPart` | A2A Data parts |
|
|
493
|
+
| `Artifact` | A2A Artifacts |
|
|
467
494
|
| `APIKeyAuth` / `BearerAuth` | Security schemes |
|
|
468
495
|
|
|
469
496
|
---
|
|
@@ -10,7 +10,7 @@ a2a_lite/streaming.py,sha256=6qLMUlbk61HBhtotxhSz5Yh4wL9OHeGt24o_J--RJvI,1626
|
|
|
10
10
|
a2a_lite/tasks.py,sha256=UpmDP-VGIQ1LodBNq4zx2pJElQ31gOJOAduHFBVyxOA,7039
|
|
11
11
|
a2a_lite/testing.py,sha256=M9IbLA6oUz1DokJ9Sc_r0gK43NNkU78IVkiBRuDFFCU,9393
|
|
12
12
|
a2a_lite/utils.py,sha256=AFLYQ4J-F7H_HeYWAeg8H3p9EOdDv4dOpju_ebrU5PI,3934
|
|
13
|
-
a2a_lite-0.2.
|
|
14
|
-
a2a_lite-0.2.
|
|
15
|
-
a2a_lite-0.2.
|
|
16
|
-
a2a_lite-0.2.
|
|
13
|
+
a2a_lite-0.2.5.dist-info/METADATA,sha256=q8-8uOzX_pzzHKJGJ7iYbqQ8onJDias33mzbjwsduH8,12501
|
|
14
|
+
a2a_lite-0.2.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
+
a2a_lite-0.2.5.dist-info/entry_points.txt,sha256=BONfFqZbCntNal2iwlTJAE09gCUvurfvqslMYVYh4is,46
|
|
16
|
+
a2a_lite-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|