4.8 KiB
cleveragents.a2a — Agent-to-Agent Protocol
The a2a package implements the Agent-to-Agent (A2A) protocol boundary.
In local mode the A2aLocalFacade maps A2A operation names to direct
Python method calls on application services — no serialization, no network.
In server mode stub transports raise A2aNotAvailableError until the
concrete HTTP transport is wired in.
See ADR-026 and ADR-047 for design rationale.
Core Classes
A2aLocalFacade
class A2aLocalFacade:
async def dispatch(self, request: A2aRequest) -> A2aResponse: ...
Routes A2A requests to live application services. Supported operations:
| Operation | Description |
|---|---|
session.create |
Create a new conversation session |
session.close |
Close an existing session |
plan.create |
Create a new plan |
plan.execute |
Execute a plan |
plan.status |
Query plan status |
plan.diff |
Retrieve plan diff |
plan.apply |
Apply a plan |
registry.list_tools |
List available tools |
registry.list_resources |
List available resources |
event.subscribe |
Subscribe to event stream |
from cleveragents.a2a import A2aLocalFacade, A2aRequest
facade = A2aLocalFacade(container)
response = await facade.dispatch(
A2aRequest(method="session.create", params={"actor": "openai/gpt-4o"})
)
A2aRequest / A2aResponse
Breaking change (v3.7.0+): Fields were renamed to comply with the JSON-RPC 2.0 wire format. See the CHANGELOG for the migration table.
class A2aRequest(BaseModel):
jsonrpc: Literal["2.0"] = "2.0" # was: a2a_version
id: str | None = None # was: request_id
method: str # was: operation
params: dict[str, Any] = {}
class A2aResponse(BaseModel):
jsonrpc: Literal["2.0"] = "2.0" # was: a2a_version
id: str | None = None # was: request_id
result: Any | None = None # was: data (success path)
error: A2aErrorDetail | None = None
# result and error are mutually exclusive (enforced by validator)
Usage example (updated for JSON-RPC 2.0 field names):
from cleveragents.a2a import A2aLocalFacade, A2aRequest
facade = A2aLocalFacade(container)
response = await facade.dispatch(
A2aRequest(method="session.create", params={"actor": "openai/gpt-4o"})
)
if response.result is not None:
session_id = response.result["session_id"]
elif response.error is not None:
raise RuntimeError(response.error.message)
A2aEventQueue
Async event queue for subscribing to plan and session events.
queue = A2aEventQueue()
async for event in queue.subscribe("plan-42"):
print(event.type, event.payload)
Call queue.close() on shutdown to release resources.
A2aVersionNegotiator
Negotiates the A2A protocol version between client and server.
Error Types
| Exception | Description |
|---|---|
A2aError |
Base A2A exception |
A2aNotAvailableError |
Operation not available in current mode |
A2aOperationNotFoundError |
Unknown operation name |
A2aVersionMismatchError |
Incompatible protocol versions |
Server Client Stubs
ServerClient, RemoteExecutionClient, and AuthClient are protocol
interfaces for server-mode operation. StubServerClient,
StubRemoteExecutionClient, and StubAuthClient raise
A2aNotAvailableError for all methods until server mode is fully
implemented.
Server Connection
from cleveragents.a2a import ServerConnectionConfig
config = ServerConnectionConfig(url="https://my-server.example.com", token="...")
Validates URL format and token presence.
ACP to A2A Rename (v3.6.0)
Breaking change in v3.6.0. The
cleveragents.acpmodule was renamed tocleveragents.a2a. AllAcp*class names were renamed toA2a*. TheAcpRequestandAcpResponsefield names were updated to comply with the JSON-RPC 2.0 specification.
For the complete migration guide, see
docs/development/acp-to-a2a-migration.md.
Symbol rename summary:
| Old (ACP) | New (A2A) |
|---|---|
AcpRequest |
A2aRequest |
AcpResponse |
A2aResponse |
AcpLocalFacade |
A2aLocalFacade |
AcpError |
A2aError |
AcpEventQueue |
A2aEventQueue |
Field rename summary (A2aRequest / A2aResponse):
| Old Field | New Field |
|---|---|
a2a_version |
jsonrpc |
request_id |
id |
operation |
method |
payload |
params |
data |
result |
error_detail |
error |
See ADR-047 for architectural rationale.