Files
cleveragents-core/docs/adr/ADR-047-acp-standard-adoption.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

18 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
47 A2A Standard Adoption
2026-03-11
Draft
Jeffrey Phillips Freeman
2026-03-11
Proposed
Jeffrey Phillips Freeman
2026-03-11
Accepted
Jeffrey Phillips Freeman
4
Jeffrey Phillips Freeman
number title relationship
1 Layered Architecture A2A remains the Presentation-Application boundary; adopting the external standard provides the wire format while preserving the layer role
number title relationship
23 Server Mode Server mode transport uses A2A JSON-RPC over HTTP; shared Domain/Application layers are unaffected
number title relationship
26 Agent-to-Agent Protocol (A2A) Supersedes the bespoke envelope and REST transport originally defined in ADR-026; the A2A boundary role and operation groups remain, now implemented via the external standard
number title relationship
22 LangChain/LangGraph Integration LangGraph Platform serves as the remote actor execution backend; A2A handles the client-server protocol layer above it
number title relationship
48 Server Application Architecture ADR-048 defines the server that implements the A2A standard endpoint; this ADR defines the protocol it speaks
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> Adopting the external A2A standard eliminates our bespoke protocol, aligns with the emerging agent ecosystem, and gives us production-quality transports and Agent Card discovery via the SDK

Context

ADR-026 established the agent communication protocol as the sole Presentation-Application boundary for all CleverAgents clients. That initial design used a bespoke JSON envelope format transported over a RESTful API (FastAPI/uvicorn, URL-path routing, HTTP verbs, SSE streaming). Since then, the Agent-to-Agent (A2A) Protocol has emerged as an open standard (a2a-protocol.org) under the Linux Foundation (Apache 2.0 license), with official SDKs in Python, Go, JavaScript, Java, and .NET. The external standard provides:

  • A protocol-binding-agnostic operation model with JSON-RPC 2.0, gRPC, and REST bindings
  • Agent Cards (/.well-known/agent.json) for dynamic capability discovery
  • Standard operations for messaging (message/send, message/stream), task lifecycle (tasks/get, tasks/list, tasks/cancel), push notifications, and agent discovery
  • A rich Task lifecycle model with states: submitted, working, input-required, completed, failed, canceled, rejected
  • An extensibility mechanism for platform-specific operations (custom methods declared in Agent Card)
  • SSE streaming for real-time task status and artifact updates
  • Multi-language SDK support with production-quality transport implementations

Adopting this external standard eliminates our bespoke protocol, provides SDK-quality transport implementations, Agent Card-based discovery, and positions CleverAgents within the broader agent interoperability ecosystem.

Decision Drivers

  • The existing bespoke protocol (custom envelope, REST routing, SSE streaming) requires ongoing maintenance and has no ecosystem adoption outside CleverAgents
  • The A2A standard covers the core agent interaction lifecycle (messaging, task management, streaming, discovery) which maps directly to CleverAgents SessionWorkflow and plan execution
  • Platform operations (plan lifecycle, registry CRUD, entity sync, namespace management) are cleanly handled by A2A's extensibility mechanism
  • The A2A Python SDK provides production-quality JSON-RPC and HTTP transports, eliminating the need for our stub transport and custom serialization code
  • Agent Card discovery enables third-party agents and clients to dynamically discover CleverAgents capabilities
  • IDE plugins, CLI, TUI, and external clients all benefit from speaking a standardized protocol that third parties can implement against
  • A2A's Linux Foundation governance and broad industry adoption (22k+ GitHub stars, 140+ contributors) provide long-term ecosystem stability

Decision

CleverAgents adopts the external Agent-to-Agent (A2A) Protocol standard (a2a-protocol.org) as the sole communication protocol for all client-server interaction. This replaces the bespoke REST+JSON envelope protocol defined in the original ADR-026. The protocol role of A2A — as the Presentation-Application boundary — is unchanged; only the wire format, transport, and method vocabulary change.

No REST API. All communication uses A2A via the JSON-RPC 2.0 protocol binding. Standard A2A operations handle agent interactions. A2A extension methods (_cleveragents/-prefixed) handle all platform operations.

Design

Protocol Architecture

A2A is the only protocol between any client and the CleverAgents backend. There are two categories of operations:

Standard A2A operations (defined by the external specification):

Operation Direction Purpose
message/send Client → Server Send a message to the agent, receive a Task or direct response
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
tasks/cancel Client → Server Cancel a running task
tasks/subscribe Client → Server Subscribe to task updates via SSE
pushNotificationConfig/* Client → Server Manage push notification webhooks
getExtendedAgentCard Client → Server Fetch authenticated Agent Card with full detail

Standard A2A streaming events (server → client via SSE):

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

Multi-turn interactions (replacing protocol-level callbacks):

Pattern Purpose
Task enters input-required state Human-in-the-loop approval (maps to automation profile gates)
Client responds via message/send Provides requested input, file content, or approval
_cleveragents/fs/* extensions Agent accesses files on client machine (handled locally by client)
_cleveragents/terminal/* extensions Agent runs commands in sandbox on client machine

CleverAgents extension methods (declared in Agent Card via A2A extension mechanism):

All platform operations use the _cleveragents/ namespace. See the specification's Server and Client Architecture section for the complete method catalog with parameters and response schemas.

Mapping to CleverAgents Concepts

A2A Standard Concept CleverAgents Concept
message/send SessionWorkflow.tell() — user talks to orchestrator actor
TaskStatusUpdateEvent (plan updates) Plan with entries (content, priority, status) — direct mapping
TaskArtifactUpdateEvent (tool output) Tool invocations during plan execution
Task input-required state Automation profile human-in-the-loop approval gates
_cleveragents/fs/* extensions Agent accesses client-local project resources
_cleveragents/terminal/* extensions Agent runs commands in sandbox on client machine
Agent Card skills Advertised plan lifecycle, registry, context, sync capabilities
Agent Card security schemes Authentication methods (OAuth2, API key, bearer token)

Agent Discovery: Agent Card

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

  • Skills: Plan lifecycle management, registry CRUD, context assembly, entity sync, namespace management, diagnostics
  • Extensions: _cleveragents/ methods with URI urn:cleveragents:extensions:v1
  • Supported interfaces: jsonrpc (primary)
  • Security schemes: OAuth2, API key, or HTTP bearer

An authenticated extended Agent Card with additional detail is available via the getExtendedAgentCard operation.

Transport Modes

The system supports three transport configurations:

Local mode — A2A JSON-RPC over stdio:

Client Process  ──stdio──→  Agent Subprocess (A2A server)
                              │
                              ├── A2aLocalFacade (platform ops resolved in-process)
                              └── Actor Graph (LangGraph, local execution)

The client spawns the agent as a subprocess. A2A JSON-RPC messages flow over stdin/stdout. Platform operations (registry, plan lifecycle, etc.) are handled by A2aLocalFacade which routes to in-process Application-layer services. No network, no serialization beyond JSON-RPC framing.

Server mode — A2A JSON-RPC over HTTP (CleverAgents server):

Client  ──HTTP──→  CleverAgents A2A Server
                     │
                     ├── Standard A2A operations → SessionWorkflow, Actor Graphs (via LangGraph Platform RemoteGraph)
                     └── Extension methods → PlanService, RegistryServices, SyncService, NamespaceService

The client connects to the CleverAgents server via the A2A SDK's HTTP transport. All communication — both agent interactions and platform operations — flows through the single A2A endpoint. The server delegates actor execution to LangGraph Platform via RemoteGraph.

Server mode — External A2A agent + CleverAgents server:

Client  ──HTTP──→  External A2A Server (agent interactions)
        ──HTTP──→  CleverAgents A2A Server (extension methods only)

When an agent is hosted on an external A2A-compatible server, the client sends standard A2A operations to that server and _cleveragents/ extension methods to the CleverAgents server. This enables interoperability with any A2A-compliant agent.

Wire Format: JSON-RPC 2.0

All A2A messages use JSON-RPC 2.0 framing (A2A specification Section 9):

Request (message/send):

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [{ "text": "Refactor the auth module to use dependency injection" }]
    }
  }
}

Response (Task created):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "task_01HXRCF1...",
    "status": { "state": "working" }
  }
}

SSE streaming event:

{
  "jsonrpc": "2.0",
  "method": "message/stream",
  "params": {
    "id": "task_01HXRCF1...",
    "status": { "state": "working" },
    "artifacts": [{ "parts": [{ "text": "I'll start by extracting the authentication..." }] }]
  }
}

Error response:

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

Extension method request:

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

Error Code Mapping

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

Code Meaning Domain Exception(s)
-32700 Parse error (malformed JSON)
-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

Application-specific error codes use the range -32001 to -32099 per JSON-RPC 2.0 convention.

Authentication

Authentication uses standard HTTP security schemes declared in the Agent Card:

  1. Client discovers the Agent Card at /.well-known/agent.json
  2. Agent Card's securitySchemes field declares supported auth mechanisms (OAuth2, API key, HTTP bearer)
  3. Client authenticates using the declared mechanism (e.g., Authorization: Bearer <token> header)
  4. All subsequent requests include the authentication credentials

For HTTP transport, the A2A-Version header communicates the protocol version.

Local mode (stdio transport) bypasses authentication entirely — the agent subprocess runs with the user's local permissions.

Versioning

  • The JSON-RPC protocol version is always "2.0" in the jsonrpc field
  • A2A protocol version is communicated via the A2A-Version HTTP header
  • CleverAgents extension version is declared in the Agent Card's extensions field under urn:cleveragents:extensions:v1
  • Backward compatibility: servers support current extension version plus one prior minor version
  • Breaking changes to extension methods require a major version bump of the _cleveragents extension namespace

Client-Side Architecture

The client uses an A2aClient wrapping the A2A Python SDK:

Component Role Notes
A2aLocalFacade Extension method dispatch Routes _cleveragents/ methods to in-process Application-layer services in local mode
A2A SDK HTTP transport Server mode transport Production HTTP transport with SSE streaming
A2A SDK JSON-RPC types Wire format types SendMessageRequest, Task, Message, Part, TaskStatusUpdateEvent, etc.
A2aEventQueue Local mode event delivery In-process delivery of task update events
Agent Card Discovery Describes capabilities, skills, extensions, and security schemes

Constraints

  • All client-server communication must use A2A. No REST endpoints, no ad-hoc HTTP calls, no separate API surfaces.
  • Standard A2A operations must not be modified or extended — use _cleveragents/ extension methods for platform-specific operations.
  • Extension method names must follow the _cleveragents/{domain}/{operation} naming convention.
  • Clients must gracefully handle servers that do not advertise _cleveragents capabilities (indicating a non-CleverAgents A2A server).

Consequences

Positive

  • Eliminates the bespoke REST protocol, reducing maintenance burden and protocol-specific code
  • Aligns with the A2A interoperability ecosystem — any A2A-compatible client or agent can interact with CleverAgents
  • Agent Card discovery enables dynamic capability advertisement and third-party integration
  • The A2A Python SDK provides production-quality transports with proper connection lifecycle management
  • JSON-RPC 2.0 is a mature, well-tooled standard with broad language support; gRPC and REST bindings are available for future adoption
  • IDE plugins benefit from a standard protocol that editor developers may already support
  • The extensibility mechanism cleanly separates standard agent operations from platform-specific operations
  • Linux Foundation governance and multi-language SDK support provide long-term ecosystem stability

Negative

  • Adopting the standard requires updating all existing protocol source code and tests
  • JSON-RPC 2.0's error code scheme (integers) is less self-documenting than string-based codes (e.g., NOT_FOUND vs -32001)

Risks

  • The extension method namespace (_cleveragents/) could collide with other implementations. Mitigation: the _cleveragents prefix is unique and registered.

Alternatives Considered

Keep the bespoke REST protocol — Functional but isolated. No ecosystem interoperability, ongoing maintenance of custom envelope format, and no path to IDE-native agent protocol support. Rejected.

Adopt standard for agent conversations only, keep REST for platform operations — Simpler initial approach but creates two protocol surfaces, complicating client implementation and authentication. The A2A extensibility mechanism makes this unnecessary. Rejected.

ACP (Agent Client Protocol) — The predecessor to A2A. Also built on JSON-RPC 2.0, but lacked Agent Card discovery, had a smaller single-language SDK ecosystem, and is now deprecated. The ecosystem (including ACP's originating platform) has converged on A2A. Rejected in favor of A2A.

gRPC for platform operations — Strong typing and streaming but adds code generation dependency, a second protocol surface, and is harder to debug. A2A includes a gRPC binding (Section 10) that can be adopted later if needed. Rejected as the primary binding.

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 test suite over stdio transport (local mode) and HTTP transport (server mode), asserting identical results.
  • SDK integration tests: Verify A2A Python SDK transport works correctly for both transport modes.
  • Agent Card tests: Validate the generated Agent Card conforms to the A2A specification schema.
  • Discovery tests: Verify /.well-known/agent.json is served correctly and getExtendedAgentCard returns authenticated detail.
  • Bypass detection: Architecture tests verify no Presentation-layer module bypasses A2A to access Domain or Infrastructure services.