a2a-lite 0.1.0__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.
- a2a_lite-0.1.0/.gitignore +21 -0
- a2a_lite-0.1.0/PKG-INFO +383 -0
- a2a_lite-0.1.0/README.md +352 -0
- a2a_lite-0.1.0/examples/01_hello_world.py +21 -0
- a2a_lite-0.1.0/examples/02_calculator.py +48 -0
- a2a_lite-0.1.0/examples/03_async_agent.py +77 -0
- a2a_lite-0.1.0/examples/04_multi_agent/finance_agent.py +98 -0
- a2a_lite-0.1.0/examples/04_multi_agent/reporter_agent.py +71 -0
- a2a_lite-0.1.0/examples/04_multi_agent/run_demo.py +109 -0
- a2a_lite-0.1.0/examples/05_with_llm.py +128 -0
- a2a_lite-0.1.0/examples/06_pydantic_models.py +67 -0
- a2a_lite-0.1.0/examples/07_middleware.py +59 -0
- a2a_lite-0.1.0/examples/08_streaming.py +52 -0
- a2a_lite-0.1.0/examples/09_testing.py +83 -0
- a2a_lite-0.1.0/examples/10_webhooks.py +91 -0
- a2a_lite-0.1.0/examples/11_human_in_the_loop.py +78 -0
- a2a_lite-0.1.0/examples/12_file_handling.py +84 -0
- a2a_lite-0.1.0/examples/13_task_tracking.py +78 -0
- a2a_lite-0.1.0/examples/14_with_auth.py +53 -0
- a2a_lite-0.1.0/pyproject.toml +53 -0
- a2a_lite-0.1.0/src/a2a_lite/__init__.py +151 -0
- a2a_lite-0.1.0/src/a2a_lite/agent.py +453 -0
- a2a_lite-0.1.0/src/a2a_lite/auth.py +344 -0
- a2a_lite-0.1.0/src/a2a_lite/cli.py +336 -0
- a2a_lite-0.1.0/src/a2a_lite/decorators.py +32 -0
- a2a_lite-0.1.0/src/a2a_lite/discovery.py +148 -0
- a2a_lite-0.1.0/src/a2a_lite/executor.py +317 -0
- a2a_lite-0.1.0/src/a2a_lite/human_loop.py +284 -0
- a2a_lite-0.1.0/src/a2a_lite/middleware.py +193 -0
- a2a_lite-0.1.0/src/a2a_lite/parts.py +218 -0
- a2a_lite-0.1.0/src/a2a_lite/streaming.py +89 -0
- a2a_lite-0.1.0/src/a2a_lite/tasks.py +221 -0
- a2a_lite-0.1.0/src/a2a_lite/testing.py +268 -0
- a2a_lite-0.1.0/src/a2a_lite/utils.py +117 -0
- a2a_lite-0.1.0/src/a2a_lite/webhooks.py +232 -0
- a2a_lite-0.1.0/tests/__init__.py +1 -0
- a2a_lite-0.1.0/tests/test_agent.py +206 -0
- a2a_lite-0.1.0/tests/test_auth.py +177 -0
- a2a_lite-0.1.0/tests/test_decorators.py +68 -0
- a2a_lite-0.1.0/tests/test_discovery.py +55 -0
- a2a_lite-0.1.0/tests/test_human_loop.py +134 -0
- a2a_lite-0.1.0/tests/test_integration.py +218 -0
- a2a_lite-0.1.0/tests/test_middleware.py +124 -0
- a2a_lite-0.1.0/tests/test_parts.py +185 -0
- a2a_lite-0.1.0/tests/test_pydantic.py +89 -0
- a2a_lite-0.1.0/tests/test_tasks.py +180 -0
- a2a_lite-0.1.0/tests/test_testing.py +70 -0
- a2a_lite-0.1.0/tests/test_utils.py +134 -0
a2a_lite-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: a2a-lite
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Simplified wrapper for Google's A2A Protocol SDK
|
|
5
|
+
Author: A2A Lite Contributors
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: a2a,agents,ai,protocol,sdk
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: a2a-sdk[http-server]>=0.2.6
|
|
18
|
+
Requires-Dist: httpx>=0.25.0
|
|
19
|
+
Requires-Dist: pydantic>=2.0
|
|
20
|
+
Requires-Dist: rich>=13.0
|
|
21
|
+
Requires-Dist: starlette>=0.40.0
|
|
22
|
+
Requires-Dist: typer>=0.9.0
|
|
23
|
+
Requires-Dist: uvicorn>=0.30.0
|
|
24
|
+
Requires-Dist: watchfiles>=0.20.0
|
|
25
|
+
Requires-Dist: zeroconf>=0.80.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: httpx>=0.25; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# A2A Lite 🚀
|
|
33
|
+
|
|
34
|
+
**Build A2A agents in 8 lines. Add enterprise features when you need them.**
|
|
35
|
+
|
|
36
|
+
Wraps the official A2A SDKs ([Python](https://github.com/a2aproject/a2a-python), [TypeScript](https://github.com/a2aproject/a2a-js), [Java](https://github.com/a2aproject/a2a-java)) with a simple, intuitive API.
|
|
37
|
+
|
|
38
|
+
<table>
|
|
39
|
+
<tr>
|
|
40
|
+
<th>Python</th>
|
|
41
|
+
<th>TypeScript</th>
|
|
42
|
+
<th>Java</th>
|
|
43
|
+
</tr>
|
|
44
|
+
<tr>
|
|
45
|
+
<td>
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from a2a_lite import Agent
|
|
49
|
+
|
|
50
|
+
agent = Agent(
|
|
51
|
+
name="Bot",
|
|
52
|
+
description="My bot"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@agent.skill("greet")
|
|
56
|
+
async def greet(name: str):
|
|
57
|
+
return f"Hello, {name}!"
|
|
58
|
+
|
|
59
|
+
agent.run()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
</td>
|
|
63
|
+
<td>
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Agent } from 'a2a-lite';
|
|
67
|
+
|
|
68
|
+
const agent = new Agent({
|
|
69
|
+
name: 'Bot',
|
|
70
|
+
description: 'My bot'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
agent.skill('greet', async ({ name }) =>
|
|
74
|
+
`Hello, ${name}!`
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
agent.run();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
</td>
|
|
81
|
+
<td>
|
|
82
|
+
|
|
83
|
+
```java
|
|
84
|
+
var agent = Agent.builder()
|
|
85
|
+
.name("Bot")
|
|
86
|
+
.description("My bot")
|
|
87
|
+
.build();
|
|
88
|
+
|
|
89
|
+
agent.skill("greet", params ->
|
|
90
|
+
"Hello, " + params.get("name") + "!"
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
agent.run();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
</td>
|
|
97
|
+
</tr>
|
|
98
|
+
</table>
|
|
99
|
+
|
|
100
|
+
That's it. You have a running A2A agent.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Installation
|
|
105
|
+
|
|
106
|
+
### Python
|
|
107
|
+
```bash
|
|
108
|
+
pip install a2a-lite
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### TypeScript
|
|
112
|
+
```bash
|
|
113
|
+
npm install a2a-lite
|
|
114
|
+
# or
|
|
115
|
+
yarn add a2a-lite
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Java (Gradle)
|
|
119
|
+
```groovy
|
|
120
|
+
dependencies {
|
|
121
|
+
implementation 'com.a2alite:a2a-lite:0.1.0'
|
|
122
|
+
implementation 'io.javalin:javalin:5.6.3' // For standalone mode
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Java (Maven)
|
|
127
|
+
```xml
|
|
128
|
+
<dependency>
|
|
129
|
+
<groupId>com.a2alite</groupId>
|
|
130
|
+
<artifactId>a2a-lite</artifactId>
|
|
131
|
+
<version>0.1.0</version>
|
|
132
|
+
</dependency>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## The Philosophy
|
|
138
|
+
|
|
139
|
+
| Need | A2A Lite |
|
|
140
|
+
|------|----------|
|
|
141
|
+
| Hello World | 8 lines |
|
|
142
|
+
| Testing | 3 lines |
|
|
143
|
+
| Pydantic models | Just works |
|
|
144
|
+
| Auth | Add when needed |
|
|
145
|
+
| Files | Add when needed |
|
|
146
|
+
| Human-in-the-loop | Add when needed |
|
|
147
|
+
| Task tracking | Add when needed |
|
|
148
|
+
|
|
149
|
+
**Everything is optional except the basics.**
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Progressive Complexity
|
|
154
|
+
|
|
155
|
+
### Level 1: Just Works (No Setup)
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from a2a_lite import Agent
|
|
159
|
+
|
|
160
|
+
agent = Agent(name="Bot", description="A bot")
|
|
161
|
+
|
|
162
|
+
@agent.skill("greet")
|
|
163
|
+
async def greet(name: str) -> str:
|
|
164
|
+
return f"Hello, {name}!"
|
|
165
|
+
|
|
166
|
+
agent.run()
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Level 2: Use Pydantic (Just Works)
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from pydantic import BaseModel
|
|
173
|
+
|
|
174
|
+
class User(BaseModel):
|
|
175
|
+
name: str
|
|
176
|
+
email: str
|
|
177
|
+
|
|
178
|
+
@agent.skill("create_user")
|
|
179
|
+
async def create_user(user: User) -> dict:
|
|
180
|
+
# 'user' is already a User instance - auto-converted!
|
|
181
|
+
return {"id": 1, "name": user.name}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Level 3: Stream Responses (Just Yield)
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
@agent.skill("chat", streaming=True)
|
|
188
|
+
async def chat(message: str):
|
|
189
|
+
for word in message.split():
|
|
190
|
+
yield word + " "
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Level 4: Add Middleware (When Needed)
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
@agent.middleware
|
|
197
|
+
async def log_requests(ctx, next):
|
|
198
|
+
print(f"Calling: {ctx.skill}")
|
|
199
|
+
return await next()
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Level 5: Human-in-the-Loop (When Needed)
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from a2a_lite import InteractionContext
|
|
206
|
+
|
|
207
|
+
@agent.skill("wizard")
|
|
208
|
+
async def wizard(ctx: InteractionContext) -> dict:
|
|
209
|
+
name = await ctx.ask("What's your name?")
|
|
210
|
+
role = await ctx.ask("Role?", options=["Dev", "Manager"])
|
|
211
|
+
|
|
212
|
+
if await ctx.confirm(f"Create {name} as {role}?"):
|
|
213
|
+
return {"created": name}
|
|
214
|
+
return {"cancelled": True}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Level 6: Handle Files (When Needed)
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
from a2a_lite import FilePart
|
|
221
|
+
|
|
222
|
+
@agent.skill("summarize")
|
|
223
|
+
async def summarize(doc: FilePart) -> str:
|
|
224
|
+
content = await doc.read_text()
|
|
225
|
+
return f"Summary: {content[:100]}..."
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Level 7: Track Task Progress (When Needed)
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from a2a_lite import TaskContext
|
|
232
|
+
|
|
233
|
+
agent = Agent(name="Bot", task_store="memory")
|
|
234
|
+
|
|
235
|
+
@agent.skill("process")
|
|
236
|
+
async def process(data: str, task: TaskContext) -> str:
|
|
237
|
+
await task.update("working", "Starting...", progress=0.0)
|
|
238
|
+
|
|
239
|
+
for i in range(10):
|
|
240
|
+
await task.update("working", f"Step {i}/10", progress=i/10)
|
|
241
|
+
|
|
242
|
+
return "Done!"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Level 8: Add Authentication (When Needed)
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from a2a_lite import Agent, APIKeyAuth
|
|
249
|
+
|
|
250
|
+
agent = Agent(
|
|
251
|
+
name="SecureBot",
|
|
252
|
+
auth=APIKeyAuth(keys=["secret-key"]),
|
|
253
|
+
)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Testing (3 Lines)
|
|
259
|
+
|
|
260
|
+
<table>
|
|
261
|
+
<tr>
|
|
262
|
+
<th>Python</th>
|
|
263
|
+
<th>TypeScript</th>
|
|
264
|
+
<th>Java</th>
|
|
265
|
+
</tr>
|
|
266
|
+
<tr>
|
|
267
|
+
<td>
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from a2a_lite import TestClient
|
|
271
|
+
|
|
272
|
+
client = TestClient(agent)
|
|
273
|
+
assert client.call("greet", name="World") == "Hello, World!"
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
</td>
|
|
277
|
+
<td>
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import { TestClient } from 'a2a-lite';
|
|
281
|
+
|
|
282
|
+
const client = new TestClient(agent);
|
|
283
|
+
expect(await client.call('greet', { name: 'World' })).toBe('Hello, World!');
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
</td>
|
|
287
|
+
<td>
|
|
288
|
+
|
|
289
|
+
```java
|
|
290
|
+
var client = new TestClient(agent);
|
|
291
|
+
assertThat(client.call("greet", Map.of("name", "World")))
|
|
292
|
+
.isEqualTo("Hello, World!");
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
</td>
|
|
296
|
+
</tr>
|
|
297
|
+
</table>
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## CLI
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
a2a-lite init my-agent # Create new project
|
|
305
|
+
a2a-lite inspect http://... # View agent capabilities
|
|
306
|
+
a2a-lite test http://... skill # Test a skill
|
|
307
|
+
a2a-lite discover # Find local agents
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Full Feature List
|
|
313
|
+
|
|
314
|
+
| Feature | Import | Complexity |
|
|
315
|
+
|---------|--------|------------|
|
|
316
|
+
| Basic skills | `Agent` | Just works |
|
|
317
|
+
| Pydantic models | `BaseModel` | Just works |
|
|
318
|
+
| Streaming | `streaming=True` | Just works |
|
|
319
|
+
| Testing | `TestClient` | Just works |
|
|
320
|
+
| Middleware | `@agent.middleware` | Add when needed |
|
|
321
|
+
| Webhooks | `@agent.on_complete` | Add when needed |
|
|
322
|
+
| Human-in-the-loop | `InteractionContext` | Add when needed |
|
|
323
|
+
| Conversation memory | `ConversationMemory` | Add when needed |
|
|
324
|
+
| File handling | `FilePart` | Add when needed |
|
|
325
|
+
| Structured data | `DataPart` | Add when needed |
|
|
326
|
+
| Rich outputs | `Artifact` | Add when needed |
|
|
327
|
+
| Task tracking | `TaskContext` | Add when needed |
|
|
328
|
+
| API Key auth | `APIKeyAuth` | Add when needed |
|
|
329
|
+
| Bearer/JWT auth | `BearerAuth` | Add when needed |
|
|
330
|
+
| Multiple auth | `CompositeAuth` | Add when needed |
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Examples
|
|
335
|
+
|
|
336
|
+
| Example | What it shows |
|
|
337
|
+
|---------|---------------|
|
|
338
|
+
| [01_hello_world.py](examples/01_hello_world.py) | Simplest agent (8 lines) |
|
|
339
|
+
| [02_calculator.py](examples/02_calculator.py) | Multiple skills |
|
|
340
|
+
| [06_pydantic_models.py](examples/06_pydantic_models.py) | Auto Pydantic conversion |
|
|
341
|
+
| [08_streaming.py](examples/08_streaming.py) | Streaming responses |
|
|
342
|
+
| [09_testing.py](examples/09_testing.py) | Testing your agents |
|
|
343
|
+
| [11_human_in_the_loop.py](examples/11_human_in_the_loop.py) | Ask user questions |
|
|
344
|
+
| [12_file_handling.py](examples/12_file_handling.py) | Handle files |
|
|
345
|
+
| [13_task_tracking.py](examples/13_task_tracking.py) | Progress updates |
|
|
346
|
+
| [14_with_auth.py](examples/14_with_auth.py) | Authentication |
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## For AI Coding Assistants
|
|
351
|
+
|
|
352
|
+
See [AGENT.md](AGENT.md) for a quick reference guide optimized for AI coding assistants implementing A2A agents.
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## 100% A2A Protocol Compatible
|
|
357
|
+
|
|
358
|
+
A2A Lite wraps the official A2A SDKs. Every feature maps to real A2A protocol concepts:
|
|
359
|
+
|
|
360
|
+
| A2A Lite | A2A Protocol |
|
|
361
|
+
|----------|--------------|
|
|
362
|
+
| `@agent.skill()` / `agent.skill()` | Agent Skills |
|
|
363
|
+
| `streaming=True` / `SkillConfig.withStreaming()` | SSE Streaming |
|
|
364
|
+
| `InteractionContext.ask()` | `input-required` state |
|
|
365
|
+
| `TaskContext.update()` | Task lifecycle states |
|
|
366
|
+
| `FilePart` | A2A File parts |
|
|
367
|
+
| `APIKeyAuth` / `BearerAuth` | Security schemes |
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Language-Specific Documentation
|
|
372
|
+
|
|
373
|
+
| Language | Package | Documentation |
|
|
374
|
+
|----------|---------|---------------|
|
|
375
|
+
| Python | [`a2a-lite`](https://pypi.org/project/a2a-lite/) | [packages/python/README.md](packages/python/README.md) |
|
|
376
|
+
| TypeScript | [`a2a-lite`](https://www.npmjs.com/package/a2a-lite) | [packages/typescript/README.md](packages/typescript/README.md) |
|
|
377
|
+
| Java | `com.a2alite:a2a-lite` | [packages/java/README.md](packages/java/README.md) |
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## License
|
|
382
|
+
|
|
383
|
+
Apache 2.0
|