a2a-lite 0.2.2__tar.gz → 0.2.4__tar.gz

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.
Files changed (49) hide show
  1. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/PKG-INFO +40 -95
  2. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/README.md +37 -90
  3. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/06_pydantic_models.py +1 -1
  4. a2a_lite-0.2.2/examples/12_file_handling.py → a2a_lite-0.2.4/examples/10_file_handling.py +1 -1
  5. a2a_lite-0.2.2/examples/13_task_tracking.py → a2a_lite-0.2.4/examples/11_task_tracking.py +1 -1
  6. a2a_lite-0.2.2/examples/14_with_auth.py → a2a_lite-0.2.4/examples/12_with_auth.py +1 -1
  7. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/pyproject.toml +3 -5
  8. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/__init__.py +7 -36
  9. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/agent.py +2 -64
  10. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/cli.py +2 -43
  11. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/decorators.py +0 -3
  12. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/executor.py +1 -9
  13. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/streaming.py +0 -29
  14. a2a_lite-0.2.2/examples/10_webhooks.py +0 -91
  15. a2a_lite-0.2.2/examples/11_human_in_the_loop.py +0 -78
  16. a2a_lite-0.2.2/src/a2a_lite/discovery.py +0 -152
  17. a2a_lite-0.2.2/src/a2a_lite/human_loop.py +0 -284
  18. a2a_lite-0.2.2/src/a2a_lite/webhooks.py +0 -228
  19. a2a_lite-0.2.2/tests/test_discovery.py +0 -55
  20. a2a_lite-0.2.2/tests/test_human_loop.py +0 -134
  21. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/.claude/settings.local.json +0 -0
  22. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/.gitignore +0 -0
  23. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/01_hello_world.py +0 -0
  24. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/02_calculator.py +0 -0
  25. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/03_async_agent.py +0 -0
  26. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/04_multi_agent/finance_agent.py +0 -0
  27. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/04_multi_agent/reporter_agent.py +0 -0
  28. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/04_multi_agent/run_demo.py +0 -0
  29. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/05_with_llm.py +0 -0
  30. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/07_middleware.py +0 -0
  31. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/08_streaming.py +0 -0
  32. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/examples/09_testing.py +0 -0
  33. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/auth.py +0 -0
  34. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/middleware.py +0 -0
  35. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/parts.py +0 -0
  36. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/tasks.py +0 -0
  37. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/testing.py +0 -0
  38. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/src/a2a_lite/utils.py +0 -0
  39. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/__init__.py +0 -0
  40. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_agent.py +0 -0
  41. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_auth.py +0 -0
  42. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_decorators.py +0 -0
  43. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_integration.py +0 -0
  44. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_middleware.py +0 -0
  45. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_parts.py +0 -0
  46. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_pydantic.py +0 -0
  47. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_tasks.py +0 -0
  48. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_testing.py +0 -0
  49. {a2a_lite-0.2.2 → a2a_lite-0.2.4}/tests/test_utils.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: a2a-lite
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Simplified wrapper for Google's A2A Protocol SDK
5
5
  Author: A2A Lite Contributors
6
- License-Expression: Apache-2.0
6
+ License-Expression: MIT
7
7
  Keywords: a2a,agents,ai,protocol,sdk
8
8
  Classifier: Development Status :: 3 - Alpha
9
9
  Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
@@ -21,8 +21,6 @@ Requires-Dist: rich>=13.0
21
21
  Requires-Dist: starlette>=0.40.0
22
22
  Requires-Dist: typer>=0.9.0
23
23
  Requires-Dist: uvicorn>=0.30.0
24
- Requires-Dist: watchfiles>=0.20.0
25
- Requires-Dist: zeroconf>=0.80.0
26
24
  Provides-Extra: dev
27
25
  Requires-Dist: httpx>=0.25; extra == 'dev'
28
26
  Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
@@ -33,7 +31,7 @@ Description-Content-Type: text/markdown
33
31
 
34
32
  # A2A Lite - Python
35
33
 
36
- **Build A2A agents in 8 lines. Add enterprise features when you need them.**
34
+ **Build A2A agents in 8 lines. Add features when you need them.**
37
35
 
38
36
  Wraps the official [A2A Python SDK](https://github.com/a2aproject/a2a-python) with a simple, intuitive API.
39
37
 
@@ -149,7 +147,6 @@ class User(BaseModel):
149
147
 
150
148
  @agent.skill("create_user")
151
149
  async def create_user(user: User) -> dict:
152
- # 'user' is already a User instance — auto-converted from dict!
153
150
  return {"id": 1, "name": user.name}
154
151
  ```
155
152
 
@@ -188,28 +185,13 @@ Built-in middleware:
188
185
  ```python
189
186
  from a2a_lite import logging_middleware, timing_middleware, retry_middleware, rate_limit_middleware
190
187
 
191
- agent.use(logging_middleware)
192
- agent.use(timing_middleware)
193
- agent.use(rate_limit_middleware(max_per_minute=60))
194
- agent.use(retry_middleware(max_retries=3))
188
+ agent.add_middleware(logging_middleware)
189
+ agent.add_middleware(timing_middleware)
190
+ agent.add_middleware(rate_limit_middleware(max_per_minute=60))
191
+ agent.add_middleware(retry_middleware(max_retries=3))
195
192
  ```
196
193
 
197
- ### Level 5: Human-in-the-Loop
198
-
199
- ```python
200
- from a2a_lite import InteractionContext
201
-
202
- @agent.skill("wizard")
203
- async def wizard(ctx: InteractionContext) -> dict:
204
- name = await ctx.ask("What's your name?")
205
- role = await ctx.ask("Role?", options=["Dev", "Manager"])
206
-
207
- if await ctx.confirm(f"Create {name} as {role}?"):
208
- return {"created": name}
209
- return {"cancelled": True}
210
- ```
211
-
212
- ### Level 6: File Handling
194
+ ### Level 5: File Handling
213
195
 
214
196
  ```python
215
197
  from a2a_lite import FilePart
@@ -220,7 +202,7 @@ async def summarize(doc: FilePart) -> str:
220
202
  return f"Summary: {content[:100]}..."
221
203
  ```
222
204
 
223
- ### Level 7: Task Tracking
205
+ ### Level 6: Task Tracking
224
206
 
225
207
  ```python
226
208
  from a2a_lite import TaskContext
@@ -237,7 +219,7 @@ async def process(data: str, task: TaskContext) -> str:
237
219
  return "Done!"
238
220
  ```
239
221
 
240
- ### Level 8: Authentication
222
+ ### Level 7: Authentication
241
223
 
242
224
  ```python
243
225
  from a2a_lite import Agent, APIKeyAuth
@@ -262,14 +244,24 @@ agent = Agent(
262
244
  auth=BearerAuth(secret="your-jwt-secret"),
263
245
  )
264
246
 
265
- # OAuth2
247
+ # OAuth2 (requires: pip install a2a-lite[oauth])
266
248
  agent = Agent(
267
249
  name="Bot", description="A bot",
268
250
  auth=OAuth2Auth(issuer="https://auth.example.com", audience="my-api"),
269
251
  )
270
252
  ```
271
253
 
272
- ### Level 9: CORS and Production Mode
254
+ Skills can receive auth results by type-hinting a parameter as `AuthResult`:
255
+
256
+ ```python
257
+ from a2a_lite.auth import AuthResult
258
+
259
+ @agent.skill("whoami")
260
+ async def whoami(auth: AuthResult) -> dict:
261
+ return {"user": auth.identity, "scheme": auth.scheme}
262
+ ```
263
+
264
+ ### Level 8: CORS and Production Mode
273
265
 
274
266
  ```python
275
267
  agent = Agent(
@@ -280,11 +272,11 @@ agent = Agent(
280
272
  )
281
273
  ```
282
274
 
283
- ### Level 10: Webhooks
275
+ ### Level 9: Completion Hooks
284
276
 
285
277
  ```python
286
278
  @agent.on_complete
287
- async def notify(skill_name, result):
279
+ async def notify(skill_name, result, ctx):
288
280
  print(f"Skill {skill_name} completed with: {result}")
289
281
  ```
290
282
 
@@ -313,25 +305,16 @@ async def info(name: str, age: int) -> dict:
313
305
  def test_simple_result():
314
306
  client = AgentTestClient(agent)
315
307
  result = client.call("greet", name="World")
316
- # Simple values support direct equality
317
308
  assert result == "Hello, World!"
318
309
 
319
310
 
320
311
  def test_dict_result():
321
312
  client = AgentTestClient(agent)
322
313
  result = client.call("info", name="Alice", age=30)
323
- # Access dict results via .data
324
314
  assert result.data["name"] == "Alice"
325
315
  assert result.data["age"] == 30
326
316
 
327
317
 
328
- def test_text_access():
329
- client = AgentTestClient(agent)
330
- result = client.call("greet", name="World")
331
- # .text gives the raw string
332
- assert result.text == '"Hello, World!"'
333
-
334
-
335
318
  def test_list_skills():
336
319
  client = AgentTestClient(agent)
337
320
  skills = client.list_skills()
@@ -379,59 +362,19 @@ def test_streaming():
379
362
 
380
363
  ---
381
364
 
382
- ## Task Store
383
-
384
- The `TaskStore` provides async-safe task lifecycle management:
385
-
386
- ```python
387
- from a2a_lite.tasks import TaskStore, TaskStatus
388
-
389
- store = TaskStore()
390
-
391
- # All operations are async and thread-safe
392
- task = await store.create(task_id="task-1", skill="process")
393
- task = await store.get("task-1")
394
- await store.update("task-1", status=TaskStatus.WORKING, progress=0.5)
395
- tasks = await store.list()
396
- await store.delete("task-1")
397
- ```
398
-
399
- ---
400
-
401
- ## Agent Discovery
402
-
403
- Find agents on your local network via mDNS:
404
-
405
- ```python
406
- from a2a_lite import AgentDiscovery
407
-
408
- # Advertise your agent
409
- agent.run(port=8787, enable_discovery=True)
410
-
411
- # Discover other agents
412
- discovery = AgentDiscovery()
413
- agents = await discovery.discover(timeout=5.0)
414
- for a in agents:
415
- print(f"{a.name} at {a.url}")
416
- ```
417
-
418
- ---
419
-
420
365
  ## CLI
421
366
 
422
367
  ```bash
423
368
  a2a-lite init my-agent # Create new project
424
369
  a2a-lite serve agent.py # Run agent from file
425
- a2a-lite serve agent.py -r # Run with hot reload
426
370
  a2a-lite inspect http://... # View agent capabilities
427
371
  a2a-lite test http://... skill # Test a skill
428
- a2a-lite discover # Find local agents
429
372
  a2a-lite version # Show version
430
373
  ```
431
374
 
432
375
  ---
433
376
 
434
- ## Full API Reference
377
+ ## API Reference
435
378
 
436
379
  ### Agent
437
380
 
@@ -445,7 +388,6 @@ Agent(
445
388
  task_store: str | TaskStore = None, # "memory" or custom TaskStore
446
389
  cors_origins: List[str] = None, # CORS allowed origins
447
390
  production: bool = False, # Enable production warnings
448
- enable_discovery: bool = False, # mDNS discovery
449
391
  )
450
392
  ```
451
393
 
@@ -455,8 +397,11 @@ Agent(
455
397
  |--------|-------------|
456
398
  | `@agent.skill(name, **config)` | Register a skill via decorator |
457
399
  | `@agent.middleware` | Register middleware via decorator |
458
- | `agent.use(middleware)` | Register middleware function |
400
+ | `agent.add_middleware(fn)` | Register middleware function |
459
401
  | `@agent.on_complete` | Register completion hook |
402
+ | `@agent.on_startup` | Register startup hook |
403
+ | `@agent.on_shutdown` | Register shutdown hook |
404
+ | `@agent.on_error` | Register error handler |
460
405
  | `agent.run(port=8787)` | Start the server |
461
406
  | `agent.get_app()` | Get the ASGI app (for custom deployment) |
462
407
 
@@ -464,7 +409,7 @@ Agent(
464
409
 
465
410
  ```python
466
411
  @agent.skill(
467
- name: str, # Skill name (required)
412
+ name: str = None, # Skill name (defaults to function name)
468
413
  description: str = None, # Human-readable description
469
414
  tags: List[str] = None, # Categorization tags
470
415
  streaming: bool = False, # Enable streaming
@@ -477,18 +422,19 @@ Agent(
477
422
  |----------|-------|
478
423
  | `APIKeyAuth(keys=[...])` | API key auth (keys hashed with SHA-256) |
479
424
  | `BearerAuth(secret=...)` | JWT/Bearer token auth |
480
- | `OAuth2Auth(issuer=..., audience=...)` | OAuth2 auth |
425
+ | `OAuth2Auth(issuer=..., audience=...)` | OAuth2 auth (requires `a2a-lite[oauth]`) |
481
426
  | `NoAuth()` | No auth (default) |
482
427
 
483
428
  ### Special Parameter Types
484
429
 
485
- These are auto-injected when detected in skill signatures:
430
+ These are auto-injected when detected in skill function signatures:
486
431
 
487
432
  | Type | Description |
488
433
  |------|-------------|
489
434
  | `TaskContext` | Task lifecycle management (requires `task_store`) |
490
- | `InteractionContext` | Human-in-the-loop interactions |
435
+ | `AuthResult` | Authentication result injection |
491
436
  | `FilePart` | File upload handling |
437
+ | `DataPart` | Structured data handling |
492
438
 
493
439
  ---
494
440
 
@@ -501,10 +447,9 @@ These are auto-injected when detected in skill signatures:
501
447
  | [06_pydantic_models.py](examples/06_pydantic_models.py) | Auto Pydantic conversion |
502
448
  | [08_streaming.py](examples/08_streaming.py) | Streaming responses |
503
449
  | [09_testing.py](examples/09_testing.py) | Testing your agents |
504
- | [11_human_in_the_loop.py](examples/11_human_in_the_loop.py) | Ask user questions |
505
- | [12_file_handling.py](examples/12_file_handling.py) | Handle files |
506
- | [13_task_tracking.py](examples/13_task_tracking.py) | Progress updates |
507
- | [14_with_auth.py](examples/14_with_auth.py) | Authentication |
450
+ | [10_file_handling.py](examples/10_file_handling.py) | Handle files |
451
+ | [11_task_tracking.py](examples/11_task_tracking.py) | Progress updates |
452
+ | [12_with_auth.py](examples/12_with_auth.py) | Authentication |
508
453
 
509
454
  ---
510
455
 
@@ -516,13 +461,13 @@ A2A Lite wraps the official A2A Python SDK. Every feature maps to real A2A proto
516
461
  |----------|--------------|
517
462
  | `@agent.skill()` | Agent Skills |
518
463
  | `streaming=True` | SSE Streaming |
519
- | `InteractionContext.ask()` | `input-required` state |
520
464
  | `TaskContext.update()` | Task lifecycle states |
521
465
  | `FilePart` | A2A File parts |
466
+ | `DataPart` | A2A Data parts |
522
467
  | `APIKeyAuth` / `BearerAuth` | Security schemes |
523
468
 
524
469
  ---
525
470
 
526
471
  ## License
527
472
 
528
- Apache 2.0
473
+ MIT
@@ -1,6 +1,6 @@
1
1
  # A2A Lite - Python
2
2
 
3
- **Build A2A agents in 8 lines. Add enterprise features when you need them.**
3
+ **Build A2A agents in 8 lines. Add features when you need them.**
4
4
 
5
5
  Wraps the official [A2A Python SDK](https://github.com/a2aproject/a2a-python) with a simple, intuitive API.
6
6
 
@@ -116,7 +116,6 @@ class User(BaseModel):
116
116
 
117
117
  @agent.skill("create_user")
118
118
  async def create_user(user: User) -> dict:
119
- # 'user' is already a User instance — auto-converted from dict!
120
119
  return {"id": 1, "name": user.name}
121
120
  ```
122
121
 
@@ -155,28 +154,13 @@ Built-in middleware:
155
154
  ```python
156
155
  from a2a_lite import logging_middleware, timing_middleware, retry_middleware, rate_limit_middleware
157
156
 
158
- agent.use(logging_middleware)
159
- agent.use(timing_middleware)
160
- agent.use(rate_limit_middleware(max_per_minute=60))
161
- agent.use(retry_middleware(max_retries=3))
157
+ agent.add_middleware(logging_middleware)
158
+ agent.add_middleware(timing_middleware)
159
+ agent.add_middleware(rate_limit_middleware(max_per_minute=60))
160
+ agent.add_middleware(retry_middleware(max_retries=3))
162
161
  ```
163
162
 
164
- ### Level 5: Human-in-the-Loop
165
-
166
- ```python
167
- from a2a_lite import InteractionContext
168
-
169
- @agent.skill("wizard")
170
- async def wizard(ctx: InteractionContext) -> dict:
171
- name = await ctx.ask("What's your name?")
172
- role = await ctx.ask("Role?", options=["Dev", "Manager"])
173
-
174
- if await ctx.confirm(f"Create {name} as {role}?"):
175
- return {"created": name}
176
- return {"cancelled": True}
177
- ```
178
-
179
- ### Level 6: File Handling
163
+ ### Level 5: File Handling
180
164
 
181
165
  ```python
182
166
  from a2a_lite import FilePart
@@ -187,7 +171,7 @@ async def summarize(doc: FilePart) -> str:
187
171
  return f"Summary: {content[:100]}..."
188
172
  ```
189
173
 
190
- ### Level 7: Task Tracking
174
+ ### Level 6: Task Tracking
191
175
 
192
176
  ```python
193
177
  from a2a_lite import TaskContext
@@ -204,7 +188,7 @@ async def process(data: str, task: TaskContext) -> str:
204
188
  return "Done!"
205
189
  ```
206
190
 
207
- ### Level 8: Authentication
191
+ ### Level 7: Authentication
208
192
 
209
193
  ```python
210
194
  from a2a_lite import Agent, APIKeyAuth
@@ -229,14 +213,24 @@ agent = Agent(
229
213
  auth=BearerAuth(secret="your-jwt-secret"),
230
214
  )
231
215
 
232
- # OAuth2
216
+ # OAuth2 (requires: pip install a2a-lite[oauth])
233
217
  agent = Agent(
234
218
  name="Bot", description="A bot",
235
219
  auth=OAuth2Auth(issuer="https://auth.example.com", audience="my-api"),
236
220
  )
237
221
  ```
238
222
 
239
- ### Level 9: CORS and Production Mode
223
+ Skills can receive auth results by type-hinting a parameter as `AuthResult`:
224
+
225
+ ```python
226
+ from a2a_lite.auth import AuthResult
227
+
228
+ @agent.skill("whoami")
229
+ async def whoami(auth: AuthResult) -> dict:
230
+ return {"user": auth.identity, "scheme": auth.scheme}
231
+ ```
232
+
233
+ ### Level 8: CORS and Production Mode
240
234
 
241
235
  ```python
242
236
  agent = Agent(
@@ -247,11 +241,11 @@ agent = Agent(
247
241
  )
248
242
  ```
249
243
 
250
- ### Level 10: Webhooks
244
+ ### Level 9: Completion Hooks
251
245
 
252
246
  ```python
253
247
  @agent.on_complete
254
- async def notify(skill_name, result):
248
+ async def notify(skill_name, result, ctx):
255
249
  print(f"Skill {skill_name} completed with: {result}")
256
250
  ```
257
251
 
@@ -280,25 +274,16 @@ async def info(name: str, age: int) -> dict:
280
274
  def test_simple_result():
281
275
  client = AgentTestClient(agent)
282
276
  result = client.call("greet", name="World")
283
- # Simple values support direct equality
284
277
  assert result == "Hello, World!"
285
278
 
286
279
 
287
280
  def test_dict_result():
288
281
  client = AgentTestClient(agent)
289
282
  result = client.call("info", name="Alice", age=30)
290
- # Access dict results via .data
291
283
  assert result.data["name"] == "Alice"
292
284
  assert result.data["age"] == 30
293
285
 
294
286
 
295
- def test_text_access():
296
- client = AgentTestClient(agent)
297
- result = client.call("greet", name="World")
298
- # .text gives the raw string
299
- assert result.text == '"Hello, World!"'
300
-
301
-
302
287
  def test_list_skills():
303
288
  client = AgentTestClient(agent)
304
289
  skills = client.list_skills()
@@ -346,59 +331,19 @@ def test_streaming():
346
331
 
347
332
  ---
348
333
 
349
- ## Task Store
350
-
351
- The `TaskStore` provides async-safe task lifecycle management:
352
-
353
- ```python
354
- from a2a_lite.tasks import TaskStore, TaskStatus
355
-
356
- store = TaskStore()
357
-
358
- # All operations are async and thread-safe
359
- task = await store.create(task_id="task-1", skill="process")
360
- task = await store.get("task-1")
361
- await store.update("task-1", status=TaskStatus.WORKING, progress=0.5)
362
- tasks = await store.list()
363
- await store.delete("task-1")
364
- ```
365
-
366
- ---
367
-
368
- ## Agent Discovery
369
-
370
- Find agents on your local network via mDNS:
371
-
372
- ```python
373
- from a2a_lite import AgentDiscovery
374
-
375
- # Advertise your agent
376
- agent.run(port=8787, enable_discovery=True)
377
-
378
- # Discover other agents
379
- discovery = AgentDiscovery()
380
- agents = await discovery.discover(timeout=5.0)
381
- for a in agents:
382
- print(f"{a.name} at {a.url}")
383
- ```
384
-
385
- ---
386
-
387
334
  ## CLI
388
335
 
389
336
  ```bash
390
337
  a2a-lite init my-agent # Create new project
391
338
  a2a-lite serve agent.py # Run agent from file
392
- a2a-lite serve agent.py -r # Run with hot reload
393
339
  a2a-lite inspect http://... # View agent capabilities
394
340
  a2a-lite test http://... skill # Test a skill
395
- a2a-lite discover # Find local agents
396
341
  a2a-lite version # Show version
397
342
  ```
398
343
 
399
344
  ---
400
345
 
401
- ## Full API Reference
346
+ ## API Reference
402
347
 
403
348
  ### Agent
404
349
 
@@ -412,7 +357,6 @@ Agent(
412
357
  task_store: str | TaskStore = None, # "memory" or custom TaskStore
413
358
  cors_origins: List[str] = None, # CORS allowed origins
414
359
  production: bool = False, # Enable production warnings
415
- enable_discovery: bool = False, # mDNS discovery
416
360
  )
417
361
  ```
418
362
 
@@ -422,8 +366,11 @@ Agent(
422
366
  |--------|-------------|
423
367
  | `@agent.skill(name, **config)` | Register a skill via decorator |
424
368
  | `@agent.middleware` | Register middleware via decorator |
425
- | `agent.use(middleware)` | Register middleware function |
369
+ | `agent.add_middleware(fn)` | Register middleware function |
426
370
  | `@agent.on_complete` | Register completion hook |
371
+ | `@agent.on_startup` | Register startup hook |
372
+ | `@agent.on_shutdown` | Register shutdown hook |
373
+ | `@agent.on_error` | Register error handler |
427
374
  | `agent.run(port=8787)` | Start the server |
428
375
  | `agent.get_app()` | Get the ASGI app (for custom deployment) |
429
376
 
@@ -431,7 +378,7 @@ Agent(
431
378
 
432
379
  ```python
433
380
  @agent.skill(
434
- name: str, # Skill name (required)
381
+ name: str = None, # Skill name (defaults to function name)
435
382
  description: str = None, # Human-readable description
436
383
  tags: List[str] = None, # Categorization tags
437
384
  streaming: bool = False, # Enable streaming
@@ -444,18 +391,19 @@ Agent(
444
391
  |----------|-------|
445
392
  | `APIKeyAuth(keys=[...])` | API key auth (keys hashed with SHA-256) |
446
393
  | `BearerAuth(secret=...)` | JWT/Bearer token auth |
447
- | `OAuth2Auth(issuer=..., audience=...)` | OAuth2 auth |
394
+ | `OAuth2Auth(issuer=..., audience=...)` | OAuth2 auth (requires `a2a-lite[oauth]`) |
448
395
  | `NoAuth()` | No auth (default) |
449
396
 
450
397
  ### Special Parameter Types
451
398
 
452
- These are auto-injected when detected in skill signatures:
399
+ These are auto-injected when detected in skill function signatures:
453
400
 
454
401
  | Type | Description |
455
402
  |------|-------------|
456
403
  | `TaskContext` | Task lifecycle management (requires `task_store`) |
457
- | `InteractionContext` | Human-in-the-loop interactions |
404
+ | `AuthResult` | Authentication result injection |
458
405
  | `FilePart` | File upload handling |
406
+ | `DataPart` | Structured data handling |
459
407
 
460
408
  ---
461
409
 
@@ -468,10 +416,9 @@ These are auto-injected when detected in skill signatures:
468
416
  | [06_pydantic_models.py](examples/06_pydantic_models.py) | Auto Pydantic conversion |
469
417
  | [08_streaming.py](examples/08_streaming.py) | Streaming responses |
470
418
  | [09_testing.py](examples/09_testing.py) | Testing your agents |
471
- | [11_human_in_the_loop.py](examples/11_human_in_the_loop.py) | Ask user questions |
472
- | [12_file_handling.py](examples/12_file_handling.py) | Handle files |
473
- | [13_task_tracking.py](examples/13_task_tracking.py) | Progress updates |
474
- | [14_with_auth.py](examples/14_with_auth.py) | Authentication |
419
+ | [10_file_handling.py](examples/10_file_handling.py) | Handle files |
420
+ | [11_task_tracking.py](examples/11_task_tracking.py) | Progress updates |
421
+ | [12_with_auth.py](examples/12_with_auth.py) | Authentication |
475
422
 
476
423
  ---
477
424
 
@@ -483,13 +430,13 @@ A2A Lite wraps the official A2A Python SDK. Every feature maps to real A2A proto
483
430
  |----------|--------------|
484
431
  | `@agent.skill()` | Agent Skills |
485
432
  | `streaming=True` | SSE Streaming |
486
- | `InteractionContext.ask()` | `input-required` state |
487
433
  | `TaskContext.update()` | Task lifecycle states |
488
434
  | `FilePart` | A2A File parts |
435
+ | `DataPart` | A2A Data parts |
489
436
  | `APIKeyAuth` / `BearerAuth` | Security schemes |
490
437
 
491
438
  ---
492
439
 
493
440
  ## License
494
441
 
495
- Apache 2.0
442
+ MIT
@@ -6,7 +6,7 @@ This is the SIMPLEST way to handle complex data - just use Pydantic!
6
6
  Run: python examples/06_pydantic_models.py
7
7
  Test: a2a-lite test http://localhost:8787 create_user -p '{"user": {"name": "Alice", "email": "alice@example.com", "age": 30}}'
8
8
  """
9
- from pydantic import BaseModel, EmailStr
9
+ from pydantic import BaseModel
10
10
  from typing import List, Optional
11
11
  from a2a_lite import Agent
12
12
 
@@ -3,7 +3,7 @@ Example: Multi-modal file handling.
3
3
 
4
4
  Handle files, images, documents - not just text!
5
5
 
6
- Run: python examples/12_file_handling.py
6
+ Run: python examples/10_file_handling.py
7
7
  """
8
8
  from a2a_lite import Agent, FilePart, DataPart, Artifact
9
9
 
@@ -3,7 +3,7 @@ Example: Task lifecycle and progress tracking.
3
3
 
4
4
  Show users real-time progress for long-running tasks.
5
5
 
6
- Run: python examples/13_task_tracking.py
6
+ Run: python examples/11_task_tracking.py
7
7
  """
8
8
  import asyncio
9
9
  from a2a_lite import Agent, TaskContext
@@ -3,7 +3,7 @@ Example: Authentication (optional).
3
3
 
4
4
  Add auth when you need it - skip it when you don't.
5
5
 
6
- Run: python examples/14_with_auth.py
6
+ Run: python examples/12_with_auth.py
7
7
  Test: curl -H "X-API-Key: secret-key" http://localhost:8787/...
8
8
  """
9
9
  from a2a_lite import Agent, APIKeyAuth
@@ -1,9 +1,9 @@
1
1
  [project]
2
2
  name = "a2a-lite"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Simplified wrapper for Google's A2A Protocol SDK"
5
5
  readme = "README.md"
6
- license = "Apache-2.0"
6
+ license = "MIT"
7
7
  requires-python = ">=3.10"
8
8
  authors = [
9
9
  { name = "A2A Lite Contributors" }
@@ -12,7 +12,7 @@ keywords = ["a2a", "agents", "protocol", "sdk", "ai"]
12
12
  classifiers = [
13
13
  "Development Status :: 3 - Alpha",
14
14
  "Intended Audience :: Developers",
15
- "License :: OSI Approved :: Apache Software License",
15
+ "License :: OSI Approved :: MIT License",
16
16
  "Programming Language :: Python :: 3",
17
17
  "Programming Language :: Python :: 3.10",
18
18
  "Programming Language :: Python :: 3.11",
@@ -24,8 +24,6 @@ dependencies = [
24
24
  "pydantic>=2.0",
25
25
  "typer>=0.9.0",
26
26
  "rich>=13.0",
27
- "watchfiles>=0.20.0",
28
- "zeroconf>=0.80.0",
29
27
  "uvicorn>=0.30.0",
30
28
  "httpx>=0.25.0",
31
29
  "starlette>=0.40.0",