Files
cleveragents-core/docs/adr/ADR-026-agent-client-protocol.md
T
freemo d5b122d4a3
CI / lint (push) Successful in 14s
CI / quality (push) Successful in 21s
CI / security (push) Successful in 36s
CI / build (push) Successful in 36s
CI / typecheck (push) Successful in 39s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m57s
CI / integration_tests (push) Successful in 3m23s
CI / docker (push) Successful in 53s
CI / coverage (push) Successful in 5m58s
CI / benchmark-publish (push) Successful in 19m27s
Docs: Updated to A2A and integrating rest standard
2026-03-11 13:19:55 -04:00

17 KiB

adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
adr_number title status_history tier authors superseded_by related_adrs acceptance
26 Agent-to-Agent Protocol (A2A)
2026-02-17
Proposed
Jeffrey Phillips Freeman
2026-02-17
Accepted
Jeffrey Phillips Freeman
4
Jeffrey Phillips Freeman
null
number title relationship
1 Layered Architecture A2A defines the fundamental boundary between the Presentation and Application layers in the four-layer architecture
number title relationship
6 Plan Lifecycle A2A extension methods expose the full plan lifecycle (use, execute, apply, cancel, correct, rollback) to all clients
number title relationship
20 Session Model A2A message operations (message/send, message/stream) map directly to SessionWorkflow operations
number title relationship
21 CLI and Output Rendering Every CLI command maps to an A2A method (standard or extension); the CLI is a thin rendering layer over A2A
number title relationship
23 Server Mode A2A is the sole client-server protocol; server mode uses A2A over HTTP, local mode uses A2A JSON-RPC over stdio
number title relationship
25 Observability and Logging A2A task update events deliver structured plan state changes and tool call events to subscribed clients
number title relationship
27 Language Server Protocol (LSP) Integration LSP servers are Infrastructure-layer components attached to actors; the IDE plugin (Presentation layer) communicates through A2A independently of LSP
number title relationship
47 A2A Standard Adoption ADR-047 defines the adoption of the external A2A standard that this ADR's protocol boundary implements
number title relationship
48 Server Application Architecture ADR-048 defines the server that implements the A2A endpoint; this ADR defines the protocol boundary role
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> A2A provides the standardized agent-to-agent communication layer needed for multi-actor orchestration

Context

CleverAgents is accessed through multiple presentation-layer clients — CLI, TUI, and an IDE plugin — and can operate in both local (single-process) and server (multi-user) modes. Without a shared, versioned contract between clients and the backend, each client would require bespoke integration code that drifts from the core domain model, making interoperability fragile and third-party client development impractical. The architecture needs a single protocol surface that all clients rely on regardless of deployment mode.

Decision Drivers

  • Multiple presentation-layer clients (CLI, TUI, IDE plugin) must share a single, versioned contract to avoid bespoke integration code that drifts from the core domain model
  • Local (in-process) and server (remote) deployment modes must expose identical operational semantics to all clients
  • Third-party client development must be practical without knowledge of internal domain or infrastructure services
  • Long-running operations (plan execution, tool invocations) require real-time streaming with causal ordering guarantees
  • The protocol must support backward-compatible evolution so existing clients are not broken by new features
  • Alignment with the emerging agent interoperability ecosystem is preferred over a bespoke protocol

Decision

CleverAgents adopts the Agent-to-Agent (A2A) Protocol — the open standard from a2a-protocol.org — as the sole communication protocol for all client-to-backend interaction. A2A is built on JSON-RPC 2.0 (with additional gRPC and REST bindings available) and provides standard operations for agent communication plus an extensibility mechanism for platform-specific operations. In local mode A2A flows over stdio via the JSON-RPC binding (agent as subprocess); in server mode over HTTP.

Design

Architectural Role

A2A defines the fundamental boundary between the Presentation and Application layers in the CleverAgents layered architecture (ADR-001). Every arrow from a Presentation-layer component (CLI, TUI, IDE plugin, A2A server endpoint) to the Application-layer Service Facade represents an A2A operation. No Presentation-layer module is permitted to bypass A2A and access Domain or Infrastructure services directly.

This boundary role makes A2A the single most architecturally significant protocol in the system — MCP and Agent Skills plug into the Infrastructure and Domain layers respectively, LSP provides actor-attached language intelligence in the Infrastructure layer (see ADR-027), but A2A is the protocol surface through which every client operation flows.

Agent Discovery: Agent Card

A2A introduces Agent Cards — JSON metadata documents served at /.well-known/agent.json — that describe an agent's identity, capabilities, skills, supported protocol bindings, authentication requirements, and extensions. The CleverAgents Agent Card declares:

  • Skills: Plan lifecycle, registry CRUD, context management, entity sync, namespace management, diagnostics
  • Extensions: _cleveragents/ platform-specific methods (declared via the A2A extension mechanism with URI urn:cleveragents:extensions:v1)
  • Supported interfaces: jsonrpc (primary), optionally rest
  • Security schemes: OAuth2, API key, or HTTP bearer — published in the Agent Card so clients can authenticate without protocol-level handshakes

In server mode, the Agent Card is served at the well-known URI. An authenticated extended Agent Card with additional detail is available via the getExtendedAgentCard operation. In local mode, the Agent Card is provided during initialization.

Protocol Scope

A2A communication is organized into two categories:

Standard A2A operations (defined by the external specification) handle the core agent interaction lifecycle:

Operation Category Operations Service(s)
Messaging message/send, message/stream SessionWorkflow, PlanService
Task lifecycle tasks/get, tasks/list, tasks/cancel TaskService
Task subscriptions tasks/subscribe TaskService, event delivery
Push notifications pushNotificationConfig/create, get, list, delete Notification service
Discovery getExtendedAgentCard Agent Card service

CleverAgents extension methods (_cleveragents/-prefixed per the A2A extensibility mechanism) handle platform operations:

Extension Group Methods Service(s)
Plan lifecycle _cleveragents/plan/use, execute, apply, cancel, status, tree, explain, correct, diff, artifacts, prompt, rollback, list PlanService, PlanLifecycle, CorrectionFlow
Registries _cleveragents/registry/{entity}/list, show, add, update, remove ActorService, ToolService, SkillService, ResourceService, ProjectService
Context _cleveragents/context/show, inspect, simulate, set ContextService
Sync _cleveragents/sync/pull, push, status SyncService
Namespace _cleveragents/namespace/list, show, members NamespaceService
Health _cleveragents/health/check, _cleveragents/diagnostics/run Health/diagnostic services

Every CLI command maps to an A2A operation. When a user runs agents plan status <ID>, the CLI sends a _cleveragents/plan/status JSON-RPC request through the active transport and renders the response.

Wire Format: JSON-RPC 2.0

The primary A2A protocol binding uses JSON-RPC 2.0 (A2A specification Section 9):

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "_cleveragents/plan/status",
  "params": { "plan_id": "01HXRCF1..." }
}

Successful response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": { "plan_id": "01HXRCF1...", "phase": "execute", "state": "running" }
}

Error response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": { "code": -32001, "message": "Plan not found", "data": { "plan_id": "01HXRCF1..." } }
}

Transport Modes

A2A is transport-agnostic at the specification level, defining abstract operations with multiple protocol bindings. CleverAgents uses the JSON-RPC binding (A2A Section 9) with two transports:

Local Mode — A2A JSON-RPC over stdio

CLI  ──stdio──→  Agent Subprocess  ──→  A2aLocalFacade  ──→  ServiceFacade.method()

The client spawns the agent as a subprocess. JSON-RPC messages flow over stdin/stdout. Extension methods are intercepted by A2aLocalFacade and routed to in-process Application-layer services. No network, no authentication.

Server Mode — A2A JSON-RPC over HTTP

CLI  ──HTTP──→  CleverAgents A2A Server  ──→  ServiceFacade.method()

The client connects to the CleverAgents server via the A2A SDK's HTTP transport. All operations (standard + extensions) flow through the single A2A JSON-RPC 2.0 endpoint. Authentication uses the security schemes declared in the Agent Card.

Architectural enforcement of transport parity:

  • The same A2A test suite runs over both transports (contract tests).
  • No Presentation-layer module imports from Infrastructure (import-linter CI checks).
  • The Service Facade is the sole Application-layer entry point from Presentation.

Streaming

A2A streaming uses Server-Sent Events (SSE) via the message/stream operation. The stream delivers typed events:

Event Type Emitted When
TaskStatusUpdateEvent Task state changes (submitted → working → completed, etc.)
TaskArtifactUpdateEvent Agent produces output artifacts (response chunks, plan entries, tool results)

In local mode, events flow as JSON-RPC notifications over stdout. In server mode, the A2A SDK manages the HTTP SSE connection. Both modes deliver the same event types with the same payload shapes.

Causal ordering guarantee: Events within a single task lifecycle are delivered in causal order.

Multi-Turn Interactions

A2A natively supports multi-turn interactions through the Task lifecycle. When a server-hosted agent requires client-side input or approval:

  1. The Task enters the input-required state (delivered via TaskStatusUpdateEvent)
  2. The client displays the request to the user (permission prompt, file access request, etc.)
  3. The client responds via message/send with the task's context ID, providing the requested input
  4. The Task resumes processing

This pattern replaces the need for protocol-level callbacks. Platform-specific client-side operations (file access, terminal commands) use _cleveragents/ extension methods that the client handles locally.

Error Taxonomy

A2A uses JSON-RPC 2.0 integer error codes (per the JSON-RPC binding, A2A Section 9.5):

Code Meaning Domain Exception(s)
-32700 Parse error
-32600 Invalid request
-32601 Method not found A2aOperationNotFoundError
-32602 Invalid params ValidationError
-32603 Internal error Any unhandled Exception
-32001 Entity not found ResourceNotFoundError
-32002 Authentication required AuthenticationError
-32003 Authorization forbidden AuthorizationError
-32004 Invalid state BusinessRuleViolation
-32005 Already exists DuplicateEntityError
-32006 Budget exceeded BudgetExceededError
-32007 Version mismatch A2aVersionMismatchError
-32008 Plan error PlanError

Versioning and Compatibility

  • The JSON-RPC protocol version is always "2.0" in the jsonrpc field
  • The A2A protocol version is communicated via the A2A-Version HTTP header in server mode
  • CleverAgents extension version is declared in the Agent Card's extensions field under urn:cleveragents:extensions:v1
  • Servers support the current extension version plus one prior minor version
  • Backward-compatible additions (new optional params, new extension methods) are permitted within a major version; breaking changes require a major version bump

Authentication and Authorization

  • Server mode: Standard HTTP authentication using security schemes declared in the Agent Card (OAuth2, API key, HTTP bearer). The Agent Card's securitySchemes field advertises which mechanisms are supported. Authorization is enforced per namespace.
  • Local mode: Authentication is bypassed — the agent subprocess runs with the user's local permissions.

Service Facade Mapping

Each A2A operation group maps to an Application-layer service. The complete method-to-service routing is documented in the specification's A2A Integration Architecture and Server and Client Architecture sections.

A2A Category Service
Standard message operations SessionWorkflow
Task lifecycle operations TaskService
Plan extension methods PlanService, PlanLifecycle, CorrectionFlow
Registry extension methods ActorService, ToolService, SkillService, ResourceService, ProjectService
Context extension methods ContextService
Sync extension methods SyncService
Namespace extension methods NamespaceService

Constraints

  • Clients must not bypass A2A to access storage, repositories, or internal domain services directly.
  • All A2A operations must be implementable over both stdio and HTTP transports with identical semantics.
  • All A2A operations in server mode must require valid authentication (via Agent Card-declared security schemes).
  • A2A responses must use the JSON-RPC 2.0 envelope; ad-hoc response shapes are prohibited.
  • Standard A2A operations must not be modified — use _cleveragents/ extension methods for platform-specific operations.
  • Streaming events must preserve causal ordering within a single task lifecycle.

Consequences

Positive

  • Clients are interchangeable — new clients (e.g., mobile, third-party dashboards) can be built against the A2A standard.
  • Local and server modes share the same protocol surface, eliminating behavioral drift.
  • Alignment with the A2A standard (Linux Foundation, Apache 2.0, multi-language SDKs) enables interoperability with the broader agent ecosystem.
  • Agent Card discovery allows third-party agents and clients to discover CleverAgents capabilities dynamically.
  • The A2A Python SDK provides production-quality transport implementations.
  • JSON-RPC 2.0 is a mature, widely-tooled standard; gRPC and REST bindings are available for future adoption.

Negative

  • The protocol adds upfront design and versioning overhead.
  • Some client-specific optimizations (e.g., batching, caching) are harder when constrained to a shared contract.

Risks

  • Protocol evolution could lag feature development if versioning discipline is not maintained.

Alternatives Considered

Per-client bespoke APIs — Faster initial development but leads to drift, duplicated logic, and higher long-term maintenance costs. Rejected.

Direct database access for local clients — Faster reads in local mode but breaks parity with server mode and tightly couples clients to storage schema. Rejected.

Bespoke REST API with custom JSON envelopes — Functional but isolated from the ecosystem. No interoperability with third-party agents or editors. Ongoing maintenance of custom envelope format. Rejected.

ACP (Agent Client Protocol) — The predecessor to A2A, also built on JSON-RPC 2.0. Lacked Agent Card discovery, had a smaller ecosystem, and is now deprecated in favor of A2A. A2A retains backward compatibility with ACP's JSON-RPC foundation. Rejected in favor of A2A's broader ecosystem, Linux Foundation governance, and multi-language SDK support.

gRPC — Strong typing and streaming but adds a code-generation dependency and is less accessible for browser-based clients than JSON-RPC over HTTP. A2A includes a gRPC binding (Section 10) that may be adopted for high-throughput server-to-server communication in the future.

Compliance

  • Protocol conformance tests: Validate all standard A2A operation signatures and response schemas against the A2A specification test suite.
  • Extension method tests: Validate all _cleveragents/ methods against documented parameter and response schemas.
  • Transport parity tests: Execute the same A2A test suite over stdio and HTTP transports, asserting identical results.
  • Authentication tests: Verify Agent Card-declared security schemes and namespace-scoped authorization in server mode.
  • Streaming tests: Ensure event ordering and schema compliance for TaskStatusUpdateEvent and TaskArtifactUpdateEvent payloads.
  • Agent Card tests: Validate the generated Agent Card conforms to the A2A specification schema.
  • Bypass detection: Architecture tests verify that no Presentation-layer module imports from the Infrastructure layer directly.