Files
cleveragents-core/docs/reference/a2a.md
T
HAL9000 980fcabc48
CI / push-validation (pull_request) Successful in 28s
CI / lint (pull_request) Successful in 32s
CI / helm (pull_request) Successful in 36s
CI / build (pull_request) Successful in 43s
CI / quality (pull_request) Successful in 55s
CI / typecheck (pull_request) Successful in 1m18s
CI / security (pull_request) Successful in 1m19s
CI / unit_tests (pull_request) Successful in 6m51s
CI / integration_tests (pull_request) Successful in 10m33s
CI / docker (pull_request) Failing after 12m6s
CI / coverage (pull_request) Failing after 12m22s
CI / status-check (pull_request) Failing after 3s
docs: document ACP to A2A module rename and symbol standardization [AUTO-DOCS-8]
2026-06-03 22:51:33 -04:00

444 lines
18 KiB
Markdown

# A2A (Agent-to-Agent Protocol) Reference
## Overview
CleverAgents adopts the external **Agent-to-Agent (A2A) Protocol** standard
([a2a-protocol.org](https://a2a-protocol.org)) as the sole communication
protocol for all client-server interaction. A2A provides the boundary layer
between the Presentation and Application layers.
**Module:** `cleveragents.a2a`
**Protocol:** JSON-RPC 2.0 binding (A2A specification Section 9)
**SDK:** `a2a-sdk` package ([a2aproject/a2a-python](https://github.com/a2aproject/a2a-python))
## Table of Contents
- [A2A (Agent-to-Agent Protocol) Reference](#a2a-agent-to-agent-protocol-reference)
- [Overview](#overview)
- [Table of Contents](#table-of-contents)
- [Agent Card](#agent-card)
- [Transport Modes](#transport-modes)
- [Standard A2A Operations](#standard-a2a-operations)
- [Extension Methods](#extension-methods)
- [Plan Operations](#plan-operations)
- [Registry Operations](#registry-operations)
- [Context Operations](#context-operations)
- [Sync Operations](#sync-operations)
- [Namespace Operations](#namespace-operations)
- [Health and Diagnostics](#health-and-diagnostics)
- [Streaming Events](#streaming-events)
- [Task Lifecycle States](#task-lifecycle-states)
- [Example Streaming Event](#example-streaming-event)
- [Multi-Turn Interactions](#multi-turn-interactions)
- [Local Facade](#local-facade)
- [Constructor](#constructor)
- [Methods](#methods)
- [Service Wiring](#service-wiring)
- [Service Keys](#service-keys)
- [Error Code Taxonomy](#error-code-taxonomy)
- [Example Error Response](#example-error-response)
- [Authentication](#authentication)
- [Client Architecture](#client-architecture)
- [Components](#components)
- [Error Hierarchy](#error-hierarchy)
---
## Agent Card
A2A uses **Agent Cards** for capability discovery. The CleverAgents Agent Card
is served at `/.well-known/agent.json` in server mode:
```json
{
"name": "CleverAgents",
"description": "AI agent orchestration platform",
"url": "https://server.example.com",
"version": "1.0",
"capabilities": {
"streaming": true,
"pushNotifications": true
},
"skills": [
{ "id": "plan-lifecycle", "name": "Plan Lifecycle Management" },
{ "id": "registry-crud", "name": "Entity Registry Operations" },
{ "id": "context-mgmt", "name": "Context Assembly" },
{ "id": "entity-sync", "name": "Entity Synchronization" },
{ "id": "namespace-mgmt", "name": "Namespace Management" }
],
"extensions": [
{
"uri": "urn:cleveragents:extensions:v1",
"description": "CleverAgents platform operations"
}
],
"securitySchemes": [
{ "type": "http", "scheme": "bearer" }
],
"interfaces": [
{ "protocol": "jsonrpc", "url": "https://server.example.com/a2a" }
]
}
```
An authenticated extended Agent Card with additional detail is available
via the `getExtendedAgentCard` operation.
---
## Transport Modes
| Mode | Transport | Class / SDK Component | Behaviour |
|--------|------------------------|------------------------------------|--------------------------------------------------------|
| Local | A2A JSON-RPC over stdio | `A2aLocalFacade` + JSON-RPC stdio | Agent as subprocess; extensions resolved in-process |
| Server | A2A JSON-RPC over HTTP | A2A SDK HTTP transport | JSON-RPC 2.0 to CleverAgents server |
In local mode the agent runs as a subprocess. JSON-RPC messages flow over
stdin/stdout. Extension methods (`_cleveragents/*`) are intercepted by
`A2aLocalFacade` and routed to in-process Application-layer services.
No network, no authentication.
In server mode the client connects via the A2A SDK's HTTP transport.
All operations — standard A2A and extensions — flow through the single
A2A JSON-RPC 2.0 endpoint on the server.
---
## Standard A2A Operations
These operations are defined by the external A2A specification and handle
the core agent interaction lifecycle:
| Operation | Direction | Purpose |
|-----------|-----------|---------|
| `message/send` | Client -> Server | Send a message to the agent; returns a Task or direct Message |
| `message/stream` | Client -> Server | Send a message with SSE streaming of task updates |
| `tasks/get` | Client -> Server | Retrieve current state of a task |
| `tasks/list` | Client -> Server | List tasks with optional filtering and pagination |
| `tasks/cancel` | Client -> Server | Cancel a running task |
| `tasks/subscribe` | Client -> Server | Subscribe to task updates via SSE |
| `pushNotificationConfig/create` | Client -> Server | Create push notification webhook |
| `pushNotificationConfig/get` | Client -> Server | Get push notification config |
| `pushNotificationConfig/list` | Client -> Server | List push notification configs |
| `pushNotificationConfig/delete` | Client -> Server | Delete push notification config |
| `getExtendedAgentCard` | Client -> Server | Fetch authenticated Agent Card |
---
## Extension Methods
Platform operations use `_cleveragents/`-prefixed extension methods
(declared in the Agent Card via the A2A extension mechanism):
### Plan Operations
| Method | Service Method | Required Params |
|--------|----------------|-----------------|
| `_cleveragents/plan/use` | `PlanService.create_plan()` | `action_name`, `project_names` |
| `_cleveragents/plan/execute` | `PlanLifecycle.execute()` | `plan_id` |
| `_cleveragents/plan/apply` | `PlanLifecycle.apply()` | `plan_id` |
| `_cleveragents/plan/cancel` | `PlanService.cancel()` | `plan_id` |
| `_cleveragents/plan/status` | `PlanService.get_status()` | `plan_id` |
| `_cleveragents/plan/tree` | `PlanService.get_tree()` | `plan_id` |
| `_cleveragents/plan/explain` | `PlanService.explain_decision()` | `plan_id`, `decision_id` |
| `_cleveragents/plan/correct` | `CorrectionFlow.correct()` | `plan_id`, `decision_id`, `correction` |
| `_cleveragents/plan/diff` | `PlanService.get_diff()` | `plan_id` |
| `_cleveragents/plan/artifacts` | `PlanService.get_artifacts()` | `plan_id` |
| `_cleveragents/plan/prompt` | `PlanService.inject_guidance()` | `plan_id`, `message` |
| `_cleveragents/plan/rollback` | `PlanLifecycle.rollback()` | `plan_id` |
| `_cleveragents/plan/list` | `PlanService.list()` | *(optional filters)* |
### Registry Operations
Pattern applies to all entity types (`actor`, `skill`, `tool`, `validation`,
`resource`, `resource_type`, `project`, `action`, `automation_profile`,
`invariant`, `lsp`):
| Method Pattern | Service Method Pattern | Required Params |
|----------------|------------------------|-----------------|
| `_cleveragents/registry/{entity}/list` | `{Entity}Service.list()` | `namespace` (optional) |
| `_cleveragents/registry/{entity}/show` | `{Entity}Service.show()` | `name` |
| `_cleveragents/registry/{entity}/add` | `{Entity}Service.add()` | Entity-specific fields |
| `_cleveragents/registry/{entity}/update` | `{Entity}Service.update()` | `name`, updated fields |
| `_cleveragents/registry/{entity}/remove` | `{Entity}Service.remove()` | `name` |
### Context Operations
| Method | Service Method | Required Params |
|--------|---------------|-----------------|
| `_cleveragents/context/show` | `ContextService.show()` | `project_name` |
| `_cleveragents/context/inspect` | `ContextService.inspect()` | `project_name` |
| `_cleveragents/context/simulate` | `ContextService.simulate()` | `project_name`, simulation params |
| `_cleveragents/context/set` | `ContextService.set()` | `project_name`, context data |
### Sync Operations
| Method | Service Method | Required Params |
|--------|---------------|-----------------|
| `_cleveragents/sync/pull` | `SyncService.pull()` | `namespace` |
| `_cleveragents/sync/push` | `SyncService.push()` | `namespace`, `entities` |
| `_cleveragents/sync/status` | `SyncService.status()` | `namespace` (optional) |
### Namespace Operations
| Method | Service Method | Required Params |
|--------|---------------|-----------------|
| `_cleveragents/namespace/list` | `NamespaceService.list()` | -- |
| `_cleveragents/namespace/show` | `NamespaceService.show()` | `namespace` |
| `_cleveragents/namespace/members` | `NamespaceService.members()` | `namespace` |
### Health and Diagnostics
| Method | Purpose |
|--------|---------|
| `_cleveragents/health/check` | Server health check |
| `_cleveragents/diagnostics/run` | Run diagnostic suite |
---
## Streaming Events
A2A streaming uses SSE via the `message/stream` operation, delivering typed
events as the task progresses:
| Event Type | Emitted When |
|-----------|-------------|
| `TaskStatusUpdateEvent` | Task state changes (submitted -> working -> completed, etc.) |
| `TaskArtifactUpdateEvent` | Agent produces output (response chunks, plan entries, tool results) |
### Task Lifecycle States
| State | Meaning |
|-------|---------|
| `submitted` | Task created, awaiting processing |
| `working` | Agent is actively processing |
| `input-required` | Agent needs client input (human-in-the-loop) |
| `completed` | Task finished successfully |
| `failed` | Task failed with error |
| `canceled` | Task was canceled by client |
| `rejected` | Task was rejected by agent |
### Example Streaming Event
```json
{
"jsonrpc": "2.0",
"method": "message/stream",
"params": {
"id": "task_01HXR...",
"status": { "state": "working" },
"artifacts": [{
"parts": [{ "text": "I'll start by extracting..." }]
}]
}
}
```
---
## Multi-Turn Interactions
A2A replaces protocol-level callbacks with multi-turn interactions via the
Task lifecycle:
| Interaction | How It Works |
|-------------|--------------|
| Human-in-the-loop approval | Task enters `input-required` state; client displays prompt; client responds via `message/send` |
| File access (read/write) | `_cleveragents/fs/*` extension methods handled locally by client |
| Terminal access | `_cleveragents/terminal/*` extension methods handled locally by client |
When a server-hosted agent needs client-side resources, the Task enters
`input-required` state. The client handles the request and responds,
resuming the task.
---
## Local Facade
`A2aLocalFacade` handles extension method dispatch in local mode:
```python
from cleveragents.a2a import A2aLocalFacade
from cleveragents.a2a.models import A2aRequest
facade = A2aLocalFacade(services={
"session_service": my_session_service,
"plan_lifecycle_service": my_plan_lifecycle_service,
"tool_registry": my_tool_registry,
"resource_registry_service": my_resource_registry_service,
})
# Extension methods are dispatched to in-process services (synchronous)
response = facade.dispatch(A2aRequest(
method="_cleveragents/plan/status",
params={"plan_id": "01J..."}
))
```
### Constructor
| Parameter | Type | Default | Description |
|------------|----------------------------|---------|-------------------------------|
| `services` | `dict[str, Any] \| None` | `None` | Named services for routing |
### Methods
| Method | Returns | Description |
|---------------------------------|-------------------|--------------------------------------|
| `dispatch(request: A2aRequest)` | `A2aResponse` | Route extension method to handler |
| `register_service` | `None` | Register a named service |
| `list_operations()` | `list[str]` | All supported extension method names |
---
## Service Wiring
Each A2A extension method is wired to a concrete application service.
Services are injected via the `services` dict at construction time or
registered later with `register_service()`.
### Service Keys
| Key | Type | Wired Methods |
|------------------------------|-----------------------------|-------------------------------------|
| `session_service` | `SessionWorkflow` | Standard message operations |
| `plan_lifecycle_service` | `PlanLifecycleService` | `_cleveragents/plan/*` |
| `tool_registry` | `ToolRegistry` | `_cleveragents/registry/tool/*` |
| `resource_registry_service` | `ResourceRegistryService` | `_cleveragents/registry/resource/*` |
| `sync_service` | `SyncService` | `_cleveragents/sync/*` |
| `namespace_service` | `NamespaceService` | `_cleveragents/namespace/*` |
| `context_service` | `ContextService` | `_cleveragents/context/*` |
---
## Error Code Taxonomy
Domain exceptions are mapped to JSON-RPC 2.0 error codes:
| JSON-RPC Code | Domain Exception(s) | Meaning |
|-------------------|----------------------------------------|----------------------------------|
| `-32700` | -- | Parse error (malformed JSON) |
| `-32600` | -- | Invalid request |
| `-32601` | `A2aOperationNotFoundError` | Method not found |
| `-32602` | `ValidationError` | Invalid params |
| `-32603` | Any unhandled `Exception` | Internal error |
| `-32001` | `ResourceNotFoundError` | Entity not found |
| `-32002` | `AuthenticationError` | Authentication required |
| `-32003` | `AuthorizationError` | Authorization forbidden |
| `-32004` | `BusinessRuleViolation` | Invalid state |
| `-32005` | `DuplicateEntityError` | Already exists |
| `-32006` | `BudgetExceededError` | Budget exceeded |
| `-32007` | `A2aVersionMismatchError` | Version mismatch |
| `-32008` | `PlanError` | Plan lifecycle error |
| `-32009` | `ConfigurationError` | Configuration error |
### Example Error Response
```json
{
"jsonrpc": "2.0",
"id": 42,
"error": {
"code": -32001,
"message": "Plan not found",
"data": { "plan_id": "01HXRCF1..." }
}
}
```
---
## Authentication
Authentication uses standard HTTP security schemes declared in the Agent Card:
1. Client discovers Agent Card at `/.well-known/agent.json`
2. Agent Card's `securitySchemes` declares supported auth mechanisms
3. Client authenticates using the declared scheme (e.g., `Authorization: Bearer <token>`)
4. All subsequent requests include authentication credentials
Local mode (stdio) bypasses authentication -- the agent subprocess runs
with the user's local permissions.
---
## Client Architecture
The client uses an `A2aClient` wrapping the A2A Python SDK:
```python
from cleveragents.a2a import A2aClient, TransportSelector
# TransportSelector picks stdio or HTTP based on configuration
transport = TransportSelector().get_transport()
client = A2aClient(transport)
# Standard A2A operation
await client.send_message(message="Add pagination", context_id="ctx_01HXR...")
# Extension method
result = await client.plan_status(plan_id="01HXRCF1...")
```
### Components
| Component | Role | Notes |
|-----------|------|-------|
| `A2aLocalFacade` | Extension dispatch in local mode | Routes `_cleveragents/` methods to in-process services |
| A2A SDK HTTP transport | Server mode transport | Production HTTP transport with SSE streaming |
| A2A SDK JSON-RPC types | Wire format | `SendMessageRequest`, `Task`, `Message`, `Part`, etc. |
| `A2aEventQueue` | Local mode event delivery | In-process task update event delivery |
| Agent Card | Discovery | Capability advertisement and auth scheme declaration |
---
## Error Hierarchy
```
CleverAgentsError
└── A2aError
├── A2aNotAvailableError
├── A2aVersionMismatchError
└── A2aOperationNotFoundError
```
| Exception | When Raised |
|-----------------------------|----------------------------------------------------|
| `A2aNotAvailableError` | Server-mode operation attempted without connection |
| `A2aVersionMismatchError` | Unsupported A2A version |
| `A2aOperationNotFoundError` | Unknown method dispatched |
---
## ACP to A2A Migration
> **v3.6.0 breaking change.** The `cleveragents.acp` module was renamed to
> `cleveragents.a2a` and all `Acp*` symbols were renamed to `A2a*`. The
> request/response wire format was updated to comply with JSON-RPC 2.0.
For a complete migration guide including symbol rename tables, field name
changes, operation name mapping, and YAML configuration updates, see
[`docs/development/acp-to-a2a-migration.md`](../development/acp-to-a2a-migration.md).
### Quick Reference: Deprecated Legacy Operations
The following ACP operation names are accepted by `A2aLocalFacade.dispatch()`
in `cleveragents.a2a.facade.A2aLocalFacade` (commit `449c33b7`) for backward
compatibility but are **deprecated**:
| Deprecated (ACP) | Replacement (A2A) |
|---|---|
| `session.create` | `_cleveragents/session/create` |
| `session.close` | `_cleveragents/session/close` |
| `plan.create` | `_cleveragents/plan/use` |
| `plan.execute` | `_cleveragents/plan/execute` |
| `plan.status` | `_cleveragents/plan/status` |
| `plan.diff` | `_cleveragents/plan/diff` |
| `plan.apply` | `_cleveragents/plan/apply` |
| `registry.list_tools` | `_cleveragents/registry/tool/list` |
| `registry.list_resources` | `_cleveragents/registry/resource/list` |
| `context.get` | `_cleveragents/context/show` |
See [ADR-047](../adr/ADR-047-acp-standard-adoption.md) for the architectural
rationale behind this change.