a2a-lite 0.2.0__py3-none-any.whl → 0.2.2__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.
- a2a_lite/__init__.py +1 -1
- a2a_lite/agent.py +34 -10
- a2a_lite/auth.py +17 -6
- a2a_lite/cli.py +1 -1
- a2a_lite/decorators.py +2 -0
- a2a_lite/executor.py +45 -10
- a2a_lite/middleware.py +6 -1
- a2a_lite/tasks.py +5 -5
- a2a_lite/testing.py +10 -1
- a2a_lite/utils.py +5 -1
- a2a_lite/webhooks.py +2 -6
- {a2a_lite-0.2.0.dist-info → a2a_lite-0.2.2.dist-info}/METADATA +3 -1
- a2a_lite-0.2.2.dist-info/RECORD +19 -0
- a2a_lite-0.2.0.dist-info/RECORD +0 -19
- {a2a_lite-0.2.0.dist-info → a2a_lite-0.2.2.dist-info}/WHEEL +0 -0
- {a2a_lite-0.2.0.dist-info → a2a_lite-0.2.2.dist-info}/entry_points.txt +0 -0
a2a_lite/__init__.py
CHANGED
a2a_lite/agent.py
CHANGED
|
@@ -170,11 +170,14 @@ class Agent:
|
|
|
170
170
|
import typing
|
|
171
171
|
from .tasks import TaskContext as _TaskContext
|
|
172
172
|
from .human_loop import InteractionContext as _InteractionContext
|
|
173
|
+
from .auth import AuthResult as _AuthResult
|
|
173
174
|
|
|
174
175
|
needs_task_context = False
|
|
175
176
|
needs_interaction = False
|
|
177
|
+
needs_auth = False
|
|
176
178
|
task_context_param: str | None = None
|
|
177
179
|
interaction_param: str | None = None
|
|
180
|
+
auth_param: str | None = None
|
|
178
181
|
|
|
179
182
|
try:
|
|
180
183
|
resolved_hints = typing.get_type_hints(func)
|
|
@@ -190,6 +193,14 @@ class Agent:
|
|
|
190
193
|
elif _is_or_subclass(hint, _InteractionContext):
|
|
191
194
|
needs_interaction = True
|
|
192
195
|
interaction_param = param_name
|
|
196
|
+
elif _is_or_subclass(hint, _AuthResult):
|
|
197
|
+
needs_auth = True
|
|
198
|
+
auth_param = param_name
|
|
199
|
+
|
|
200
|
+
# Also detect require_auth decorator
|
|
201
|
+
if getattr(func, '__requires_auth__', False) and not needs_auth:
|
|
202
|
+
needs_auth = True
|
|
203
|
+
auth_param = auth_param or "auth"
|
|
193
204
|
|
|
194
205
|
# Extract schemas
|
|
195
206
|
input_schema, output_schema = extract_function_schemas(func)
|
|
@@ -205,8 +216,10 @@ class Agent:
|
|
|
205
216
|
is_streaming=is_streaming,
|
|
206
217
|
needs_task_context=needs_task_context,
|
|
207
218
|
needs_interaction=needs_interaction,
|
|
219
|
+
needs_auth=needs_auth,
|
|
208
220
|
task_context_param=task_context_param,
|
|
209
221
|
interaction_param=interaction_param,
|
|
222
|
+
auth_param=auth_param,
|
|
210
223
|
)
|
|
211
224
|
|
|
212
225
|
self._skills[skill_name] = skill_def
|
|
@@ -332,6 +345,10 @@ class Agent:
|
|
|
332
345
|
task_store=self._task_store,
|
|
333
346
|
)
|
|
334
347
|
|
|
348
|
+
# The SDK's InMemoryTaskStore handles protocol-level task lifecycle
|
|
349
|
+
# (task creation, state transitions per the A2A spec). This is separate
|
|
350
|
+
# from self._task_store which provides application-level tracking
|
|
351
|
+
# (progress updates, custom status) exposed via TaskContext to skills.
|
|
335
352
|
request_handler = DefaultRequestHandler(
|
|
336
353
|
agent_executor=executor,
|
|
337
354
|
task_store=InMemoryTaskStore(),
|
|
@@ -379,11 +396,14 @@ class Agent:
|
|
|
379
396
|
))
|
|
380
397
|
|
|
381
398
|
# Run startup hooks
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
asyncio.
|
|
385
|
-
|
|
386
|
-
|
|
399
|
+
async def _run_startup():
|
|
400
|
+
for hook in self._on_startup:
|
|
401
|
+
if asyncio.iscoroutinefunction(hook):
|
|
402
|
+
await hook()
|
|
403
|
+
else:
|
|
404
|
+
hook()
|
|
405
|
+
if self._on_startup:
|
|
406
|
+
asyncio.run(_run_startup())
|
|
387
407
|
|
|
388
408
|
# Enable discovery if requested
|
|
389
409
|
if enable_discovery:
|
|
@@ -430,11 +450,14 @@ class Agent:
|
|
|
430
450
|
)
|
|
431
451
|
finally:
|
|
432
452
|
# Run shutdown hooks
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
asyncio.
|
|
436
|
-
|
|
437
|
-
|
|
453
|
+
async def _run_shutdown():
|
|
454
|
+
for hook in self._on_shutdown:
|
|
455
|
+
if asyncio.iscoroutinefunction(hook):
|
|
456
|
+
await hook()
|
|
457
|
+
else:
|
|
458
|
+
hook()
|
|
459
|
+
if self._on_shutdown:
|
|
460
|
+
asyncio.run(_run_shutdown())
|
|
438
461
|
|
|
439
462
|
# Unregister discovery
|
|
440
463
|
if self._discovery:
|
|
@@ -485,6 +508,7 @@ class Agent:
|
|
|
485
508
|
task_store=self._task_store,
|
|
486
509
|
)
|
|
487
510
|
|
|
511
|
+
# SDK task store for protocol-level lifecycle (separate from app-level self._task_store)
|
|
488
512
|
request_handler = DefaultRequestHandler(
|
|
489
513
|
agent_executor=executor,
|
|
490
514
|
task_store=InMemoryTaskStore(),
|
a2a_lite/auth.py
CHANGED
|
@@ -60,6 +60,17 @@ class AuthRequest:
|
|
|
60
60
|
method: str = "POST"
|
|
61
61
|
path: str = "/"
|
|
62
62
|
|
|
63
|
+
def get_header(self, name: str) -> Optional[str]:
|
|
64
|
+
"""Get a header value (case-insensitive)."""
|
|
65
|
+
# Try exact match first, then case-insensitive
|
|
66
|
+
if name in self.headers:
|
|
67
|
+
return self.headers[name]
|
|
68
|
+
lower = name.lower()
|
|
69
|
+
for k, v in self.headers.items():
|
|
70
|
+
if k.lower() == lower:
|
|
71
|
+
return v
|
|
72
|
+
return None
|
|
73
|
+
|
|
63
74
|
|
|
64
75
|
@dataclass
|
|
65
76
|
class AuthResult:
|
|
@@ -128,8 +139,8 @@ class APIKeyAuth(AuthProvider):
|
|
|
128
139
|
return hashlib.sha256(key.encode()).hexdigest()
|
|
129
140
|
|
|
130
141
|
async def authenticate(self, request: AuthRequest) -> AuthResult:
|
|
131
|
-
# Check header
|
|
132
|
-
key = request.
|
|
142
|
+
# Check header (case-insensitive)
|
|
143
|
+
key = request.get_header(self.header)
|
|
133
144
|
|
|
134
145
|
# Check query param
|
|
135
146
|
if not key and self.query_param:
|
|
@@ -179,7 +190,7 @@ class BearerAuth(AuthProvider):
|
|
|
179
190
|
self.header = header
|
|
180
191
|
|
|
181
192
|
async def authenticate(self, request: AuthRequest) -> AuthResult:
|
|
182
|
-
auth_header = request.
|
|
193
|
+
auth_header = request.get_header(self.header) or ""
|
|
183
194
|
|
|
184
195
|
if not auth_header.startswith("Bearer "):
|
|
185
196
|
return AuthResult.failure("Bearer token required")
|
|
@@ -211,7 +222,7 @@ class OAuth2Auth(AuthProvider):
|
|
|
211
222
|
audience="my-agent",
|
|
212
223
|
)
|
|
213
224
|
|
|
214
|
-
Requires: pip install
|
|
225
|
+
Requires: pip install a2a-lite[oauth]
|
|
215
226
|
"""
|
|
216
227
|
|
|
217
228
|
def __init__(
|
|
@@ -228,7 +239,7 @@ class OAuth2Auth(AuthProvider):
|
|
|
228
239
|
self._jwks_client = None
|
|
229
240
|
|
|
230
241
|
async def authenticate(self, request: AuthRequest) -> AuthResult:
|
|
231
|
-
auth_header = request.
|
|
242
|
+
auth_header = request.get_header("Authorization") or ""
|
|
232
243
|
|
|
233
244
|
if not auth_header.startswith("Bearer "):
|
|
234
245
|
return AuthResult.failure("Bearer token required")
|
|
@@ -266,7 +277,7 @@ class OAuth2Auth(AuthProvider):
|
|
|
266
277
|
|
|
267
278
|
except ImportError:
|
|
268
279
|
return AuthResult.failure(
|
|
269
|
-
"OAuth2 requires pyjwt: pip install
|
|
280
|
+
"OAuth2 requires pyjwt: pip install a2a-lite[oauth]"
|
|
270
281
|
)
|
|
271
282
|
except Exception as e:
|
|
272
283
|
return AuthResult.failure(f"Token validation failed: {str(e)}")
|
a2a_lite/cli.py
CHANGED
a2a_lite/decorators.py
CHANGED
|
@@ -18,8 +18,10 @@ class SkillDefinition:
|
|
|
18
18
|
is_streaming: bool = False
|
|
19
19
|
needs_task_context: bool = False
|
|
20
20
|
needs_interaction: bool = False
|
|
21
|
+
needs_auth: bool = False
|
|
21
22
|
task_context_param: Optional[str] = None
|
|
22
23
|
interaction_param: Optional[str] = None
|
|
24
|
+
auth_param: Optional[str] = None
|
|
23
25
|
|
|
24
26
|
def to_dict(self) -> Dict[str, Any]:
|
|
25
27
|
"""Convert to dictionary for serialization."""
|
a2a_lite/executor.py
CHANGED
|
@@ -59,6 +59,23 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
59
59
|
from a2a.utils import new_agent_text_message
|
|
60
60
|
|
|
61
61
|
try:
|
|
62
|
+
# Authenticate the request (always run to produce auth_result for injection)
|
|
63
|
+
auth_result = None
|
|
64
|
+
if self.auth_provider:
|
|
65
|
+
from .auth import AuthRequest, NoAuth
|
|
66
|
+
headers = {}
|
|
67
|
+
if context.call_context and context.call_context.state:
|
|
68
|
+
headers = context.call_context.state.get('headers', {})
|
|
69
|
+
auth_request = AuthRequest(headers=headers)
|
|
70
|
+
auth_result = await self.auth_provider.authenticate(auth_request)
|
|
71
|
+
# Reject unauthenticated requests (unless NoAuth)
|
|
72
|
+
if not isinstance(self.auth_provider, NoAuth) and not auth_result.authenticated:
|
|
73
|
+
error_msg = json.dumps({
|
|
74
|
+
"error": auth_result.error or "Authentication failed",
|
|
75
|
+
})
|
|
76
|
+
await event_queue.enqueue_event(new_agent_text_message(error_msg))
|
|
77
|
+
return
|
|
78
|
+
|
|
62
79
|
# Extract message and parts
|
|
63
80
|
message, parts = self._extract_message_and_parts(context)
|
|
64
81
|
|
|
@@ -72,9 +89,10 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
72
89
|
message=message,
|
|
73
90
|
)
|
|
74
91
|
|
|
75
|
-
# Store parts in metadata for skill access
|
|
92
|
+
# Store parts and auth result in metadata for skill access
|
|
76
93
|
ctx.metadata["parts"] = parts
|
|
77
94
|
ctx.metadata["event_queue"] = event_queue
|
|
95
|
+
ctx.metadata["auth_result"] = auth_result
|
|
78
96
|
|
|
79
97
|
# Define final handler
|
|
80
98
|
async def final_handler(ctx: MiddlewareContext) -> Any:
|
|
@@ -120,7 +138,14 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
120
138
|
if skill_name is None:
|
|
121
139
|
if not self.skills:
|
|
122
140
|
return {"error": "No skills registered"}
|
|
123
|
-
|
|
141
|
+
# Only auto-select if there's exactly one skill
|
|
142
|
+
if len(self.skills) == 1:
|
|
143
|
+
skill_name = list(self.skills.keys())[0]
|
|
144
|
+
else:
|
|
145
|
+
return {
|
|
146
|
+
"error": "No skill specified. Use {\"skill\": \"name\", \"params\": {...}} format.",
|
|
147
|
+
"available_skills": list(self.skills.keys()),
|
|
148
|
+
}
|
|
124
149
|
|
|
125
150
|
if skill_name not in self.skills:
|
|
126
151
|
return {
|
|
@@ -150,6 +175,10 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
150
175
|
param_name = skill_def.interaction_param or "ctx"
|
|
151
176
|
params[param_name] = interaction_ctx
|
|
152
177
|
|
|
178
|
+
if skill_def.needs_auth:
|
|
179
|
+
param_name = skill_def.auth_param or "auth"
|
|
180
|
+
params[param_name] = metadata.get("auth_result")
|
|
181
|
+
|
|
153
182
|
# Call the handler
|
|
154
183
|
handler = skill_def.handler
|
|
155
184
|
|
|
@@ -167,11 +196,19 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
167
196
|
metadata: Dict[str, Any],
|
|
168
197
|
) -> Dict[str, Any]:
|
|
169
198
|
"""Convert parameters to Pydantic models and file parts if needed."""
|
|
199
|
+
import typing
|
|
170
200
|
handler = skill_def.handler
|
|
171
|
-
|
|
201
|
+
try:
|
|
202
|
+
hints = typing.get_type_hints(handler)
|
|
203
|
+
except Exception:
|
|
204
|
+
hints = getattr(handler, '__annotations__', {})
|
|
205
|
+
|
|
206
|
+
from .parts import FilePart, DataPart
|
|
172
207
|
|
|
173
208
|
converted = {}
|
|
174
209
|
for param_name, value in params.items():
|
|
210
|
+
if param_name == 'return':
|
|
211
|
+
continue
|
|
175
212
|
param_type = hints.get(param_name)
|
|
176
213
|
|
|
177
214
|
if param_type is None:
|
|
@@ -181,13 +218,12 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
181
218
|
# Skip special context types
|
|
182
219
|
from .tasks import TaskContext as _TaskContext
|
|
183
220
|
from .human_loop import InteractionContext as _InteractionContext
|
|
184
|
-
|
|
221
|
+
from .auth import AuthResult as _AuthResult
|
|
222
|
+
if _is_or_subclass(param_type, _TaskContext) or _is_or_subclass(param_type, _InteractionContext) or _is_or_subclass(param_type, _AuthResult):
|
|
185
223
|
continue
|
|
186
224
|
|
|
187
225
|
# Convert FilePart
|
|
188
|
-
|
|
189
|
-
if "FilePart" in type_name:
|
|
190
|
-
from .parts import FilePart
|
|
226
|
+
if _is_or_subclass(param_type, FilePart):
|
|
191
227
|
if isinstance(value, dict):
|
|
192
228
|
# Handle both A2A format and simple dict format
|
|
193
229
|
if "file" in value:
|
|
@@ -208,8 +244,7 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
208
244
|
continue
|
|
209
245
|
|
|
210
246
|
# Convert DataPart
|
|
211
|
-
if
|
|
212
|
-
from .parts import DataPart
|
|
247
|
+
if _is_or_subclass(param_type, DataPart):
|
|
213
248
|
if isinstance(value, dict):
|
|
214
249
|
# Handle both A2A format and simple dict format
|
|
215
250
|
if "type" in value and value.get("type") == "data":
|
|
@@ -317,7 +352,7 @@ class LiteAgentExecutor(AgentExecutor):
|
|
|
317
352
|
if asyncio.iscoroutinefunction(handler):
|
|
318
353
|
return await handler(*args, **kwargs)
|
|
319
354
|
else:
|
|
320
|
-
loop = asyncio.
|
|
355
|
+
loop = asyncio.get_running_loop()
|
|
321
356
|
return await loop.run_in_executor(
|
|
322
357
|
None,
|
|
323
358
|
lambda: handler(*args, **kwargs)
|
a2a_lite/middleware.py
CHANGED
|
@@ -159,7 +159,12 @@ def retry_middleware(max_retries: int = 3, delay: float = 1.0):
|
|
|
159
159
|
|
|
160
160
|
def rate_limit_middleware(requests_per_minute: int = 60):
|
|
161
161
|
"""
|
|
162
|
-
Create a simple rate limiting middleware.
|
|
162
|
+
Create a simple in-process rate limiting middleware.
|
|
163
|
+
|
|
164
|
+
Note: This rate limiter is per-process. Under multi-worker uvicorn
|
|
165
|
+
(e.g., ``--workers 4``), each worker tracks limits independently.
|
|
166
|
+
For shared rate limiting across workers, use an external store
|
|
167
|
+
(Redis, etc.) and a custom middleware.
|
|
163
168
|
|
|
164
169
|
Example:
|
|
165
170
|
agent.add_middleware(rate_limit_middleware(requests_per_minute=100))
|
a2a_lite/tasks.py
CHANGED
|
@@ -30,7 +30,7 @@ from __future__ import annotations
|
|
|
30
30
|
import asyncio
|
|
31
31
|
import logging
|
|
32
32
|
from dataclasses import dataclass, field
|
|
33
|
-
from datetime import datetime
|
|
33
|
+
from datetime import datetime, timezone
|
|
34
34
|
from enum import Enum
|
|
35
35
|
from typing import Any, Callable, Dict, List, Optional
|
|
36
36
|
from uuid import uuid4
|
|
@@ -55,7 +55,7 @@ class TaskStatus:
|
|
|
55
55
|
state: TaskState
|
|
56
56
|
message: Optional[str] = None
|
|
57
57
|
progress: Optional[float] = None # 0.0 to 1.0
|
|
58
|
-
timestamp: datetime = field(default_factory=datetime.
|
|
58
|
+
timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
59
59
|
|
|
60
60
|
def to_dict(self) -> Dict[str, Any]:
|
|
61
61
|
return {
|
|
@@ -77,8 +77,8 @@ class Task:
|
|
|
77
77
|
error: Optional[str] = None
|
|
78
78
|
artifacts: List[Any] = field(default_factory=list)
|
|
79
79
|
history: List[TaskStatus] = field(default_factory=list)
|
|
80
|
-
created_at: datetime = field(default_factory=datetime.
|
|
81
|
-
updated_at: datetime = field(default_factory=datetime.
|
|
80
|
+
created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
81
|
+
updated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
82
82
|
|
|
83
83
|
def update_status(
|
|
84
84
|
self,
|
|
@@ -89,7 +89,7 @@ class Task:
|
|
|
89
89
|
"""Update task status."""
|
|
90
90
|
self.history.append(self.status)
|
|
91
91
|
self.status = TaskStatus(state=state, message=message, progress=progress)
|
|
92
|
-
self.updated_at = datetime.
|
|
92
|
+
self.updated_at = datetime.now(timezone.utc)
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
class TaskContext:
|
a2a_lite/testing.py
CHANGED
|
@@ -214,7 +214,16 @@ class AgentTestClient:
|
|
|
214
214
|
result = await gen
|
|
215
215
|
results.append(result)
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
# Handle both sync and async calling contexts
|
|
218
|
+
try:
|
|
219
|
+
asyncio.get_running_loop()
|
|
220
|
+
# Already in an async context — run in a separate thread
|
|
221
|
+
import concurrent.futures
|
|
222
|
+
with concurrent.futures.ThreadPoolExecutor(1) as pool:
|
|
223
|
+
pool.submit(asyncio.run, run_handler()).result()
|
|
224
|
+
except RuntimeError:
|
|
225
|
+
# No running loop — safe to use asyncio.run()
|
|
226
|
+
asyncio.run(run_handler())
|
|
218
227
|
return results
|
|
219
228
|
|
|
220
229
|
|
a2a_lite/utils.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Helper functions for A2A Lite.
|
|
3
3
|
"""
|
|
4
|
+
import typing
|
|
4
5
|
from typing import Any, Dict, Type, get_origin, get_args, Union
|
|
5
6
|
import inspect
|
|
6
7
|
|
|
@@ -103,7 +104,10 @@ def extract_function_schemas(func) -> tuple[Dict[str, Any], Dict[str, Any]]:
|
|
|
103
104
|
Tuple of (input_schema, output_schema)
|
|
104
105
|
"""
|
|
105
106
|
sig = inspect.signature(func)
|
|
106
|
-
|
|
107
|
+
try:
|
|
108
|
+
hints = typing.get_type_hints(func)
|
|
109
|
+
except Exception:
|
|
110
|
+
hints = getattr(func, '__annotations__', {})
|
|
107
111
|
|
|
108
112
|
# Build input schema from parameters
|
|
109
113
|
properties = {}
|
a2a_lite/webhooks.py
CHANGED
|
@@ -9,7 +9,7 @@ Simplifies sending notifications when tasks complete:
|
|
|
9
9
|
"""
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
-
from dataclasses import dataclass
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
13
|
from typing import Any, Callable, Dict, List, Optional
|
|
14
14
|
import asyncio
|
|
15
15
|
import json
|
|
@@ -19,15 +19,11 @@ import json
|
|
|
19
19
|
class WebhookConfig:
|
|
20
20
|
"""Configuration for a webhook endpoint."""
|
|
21
21
|
url: str
|
|
22
|
-
headers: Dict[str, str] =
|
|
22
|
+
headers: Dict[str, str] = field(default_factory=dict)
|
|
23
23
|
retry_count: int = 3
|
|
24
24
|
retry_delay: float = 1.0
|
|
25
25
|
timeout: float = 30.0
|
|
26
26
|
|
|
27
|
-
def __post_init__(self):
|
|
28
|
-
if self.headers is None:
|
|
29
|
-
self.headers = {}
|
|
30
|
-
|
|
31
27
|
|
|
32
28
|
class WebhookClient:
|
|
33
29
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: a2a-lite
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Simplified wrapper for Google's A2A Protocol SDK
|
|
5
5
|
Author: A2A Lite Contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -27,6 +27,8 @@ Provides-Extra: dev
|
|
|
27
27
|
Requires-Dist: httpx>=0.25; extra == 'dev'
|
|
28
28
|
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
29
29
|
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
30
|
+
Provides-Extra: oauth
|
|
31
|
+
Requires-Dist: pyjwt[crypto]>=2.0; extra == 'oauth'
|
|
30
32
|
Description-Content-Type: text/markdown
|
|
31
33
|
|
|
32
34
|
# A2A Lite - Python
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
a2a_lite/__init__.py,sha256=-uZfl-CoWKt4xFSmda3TEBmPB7pRA71u9C4HkK8Pavs,3520
|
|
2
|
+
a2a_lite/agent.py,sha256=OrIzIaJLv7O55G1jrSl81pNem9S7kD47QDOzxISAmw0,17793
|
|
3
|
+
a2a_lite/auth.py,sha256=A1AMncM0cuWEAcysjumAhjd0lI_jMLmJpeYWuAPj30A,10181
|
|
4
|
+
a2a_lite/cli.py,sha256=chLmUrWPxXmXU75LO8yhN5HP0rct3yN8W_i_txTvoJA,9043
|
|
5
|
+
a2a_lite/decorators.py,sha256=RDekZdDJQR8124zX0lvTinaU7iJdNjNHaNPop17_gmg,1116
|
|
6
|
+
a2a_lite/discovery.py,sha256=BxpiJAUDxIyI2gvsLhjmHte5c9ax5Qf1hbBQnyAmxLQ,4508
|
|
7
|
+
a2a_lite/executor.py,sha256=gC_9mzoGalUJMZUio-SQeXcoZvOU4LR69eK9ikncJwQ,13628
|
|
8
|
+
a2a_lite/human_loop.py,sha256=XAqxp-k8I7TNyuLqqNmLEqABHqcAUiKYCL8n3W5StaY,8685
|
|
9
|
+
a2a_lite/middleware.py,sha256=c6jb9aFfyTf-JY6KjqaSgFJmpzqbHLC6Q1h9NNteqzo,5545
|
|
10
|
+
a2a_lite/parts.py,sha256=qVRiD-H9_NlMPk-R0gTUiGVQ77E2poiuBWAUyAyAoTI,6177
|
|
11
|
+
a2a_lite/streaming.py,sha256=RFv9EJYnhwkT0h1Wovkj4EXwFzCgHdaA-h7WpPaaONo,2329
|
|
12
|
+
a2a_lite/tasks.py,sha256=UpmDP-VGIQ1LodBNq4zx2pJElQ31gOJOAduHFBVyxOA,7039
|
|
13
|
+
a2a_lite/testing.py,sha256=M9IbLA6oUz1DokJ9Sc_r0gK43NNkU78IVkiBRuDFFCU,9393
|
|
14
|
+
a2a_lite/utils.py,sha256=AFLYQ4J-F7H_HeYWAeg8H3p9EOdDv4dOpju_ebrU5PI,3934
|
|
15
|
+
a2a_lite/webhooks.py,sha256=TNhDlG84rrP_gC2pQ-op5xo01p5Z9sm_ZgQIrJRI7OY,6095
|
|
16
|
+
a2a_lite-0.2.2.dist-info/METADATA,sha256=o74kDuPcSpG1A82qVROqwqMMTTvR95vigXwtx64OeCU,12657
|
|
17
|
+
a2a_lite-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
18
|
+
a2a_lite-0.2.2.dist-info/entry_points.txt,sha256=BONfFqZbCntNal2iwlTJAE09gCUvurfvqslMYVYh4is,46
|
|
19
|
+
a2a_lite-0.2.2.dist-info/RECORD,,
|
a2a_lite-0.2.0.dist-info/RECORD
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
a2a_lite/__init__.py,sha256=HfTauky7g1ugDu1OQO65qcCi8bzbHeSaAK_k6ENrB8k,3520
|
|
2
|
-
a2a_lite/agent.py,sha256=ZdRGi1w1VYDUd7DxlGneZ_1Y5JSAIyur_zU6RZIrmp0,16647
|
|
3
|
-
a2a_lite/auth.py,sha256=vRAYOj-4VOiaXQ_-hKk8YFkideyU5b8JFj2lEp-rW8s,9772
|
|
4
|
-
a2a_lite/cli.py,sha256=beffnCU-FJR7kVCCJBwHYazUQzwi4g7HiSD20lgrpAM,9043
|
|
5
|
-
a2a_lite/decorators.py,sha256=VdinkddmF61IS8TkjdSfHGdn3nDKwepcIjWZPZBKg3w,1050
|
|
6
|
-
a2a_lite/discovery.py,sha256=BxpiJAUDxIyI2gvsLhjmHte5c9ax5Qf1hbBQnyAmxLQ,4508
|
|
7
|
-
a2a_lite/executor.py,sha256=tNtrIbwAImadMyJFtrat1iaXkqrACckrqjt3x39IPOc,11891
|
|
8
|
-
a2a_lite/human_loop.py,sha256=XAqxp-k8I7TNyuLqqNmLEqABHqcAUiKYCL8n3W5StaY,8685
|
|
9
|
-
a2a_lite/middleware.py,sha256=ciR2z5y85uYIc4YFGNTR2litjRehuU7jsohYMJDGHkI,5282
|
|
10
|
-
a2a_lite/parts.py,sha256=qVRiD-H9_NlMPk-R0gTUiGVQ77E2poiuBWAUyAyAoTI,6177
|
|
11
|
-
a2a_lite/streaming.py,sha256=RFv9EJYnhwkT0h1Wovkj4EXwFzCgHdaA-h7WpPaaONo,2329
|
|
12
|
-
a2a_lite/tasks.py,sha256=VWHhRwi4ajrr4vMNSJVpFjSUqMOdAPM-PnVUeCnYbww,6963
|
|
13
|
-
a2a_lite/testing.py,sha256=kmQGkFucUAv2zPkrko0ZWn7S1q3bkz0v7FXpO6J47mU,8985
|
|
14
|
-
a2a_lite/utils.py,sha256=CnkO6HH9oKEXymbJG2ohdt1ESxldQ3fkmcYVO-o9R_k,3841
|
|
15
|
-
a2a_lite/webhooks.py,sha256=t6ebT3jVBEKFpjhBnPI-nuQWIUKQUbJm24phXOBnNKA,6158
|
|
16
|
-
a2a_lite-0.2.0.dist-info/METADATA,sha256=CR6_O8Uu-M8whAcFH9bGetWql2ZzmSRZwFCncjIg2tU,12583
|
|
17
|
-
a2a_lite-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
18
|
-
a2a_lite-0.2.0.dist-info/entry_points.txt,sha256=BONfFqZbCntNal2iwlTJAE09gCUvurfvqslMYVYh4is,46
|
|
19
|
-
a2a_lite-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|