feat(a2a): implement A2A HTTP transport for server mode #720

Closed
freemo wants to merge 4 commits from feature/m9-a2a-http into master
Owner

Summary

Implements the A2A HTTP transport for server mode per the specification (§Architecture > Transport Modes), enabling client-server communication via a single JSON-RPC 2.0 HTTP endpoint with SSE streaming support.

Closes #692

Changes

New modules in src/cleveragents/a2a/

  • http_transport.pyA2aRemoteTransport class implementing:
    • HTTP POST to single JSON-RPC endpoint using A2A SDK A2AClient
    • SSE streaming for long-running operations via TaskStatusUpdateEvent and TaskArtifactUpdateEvent
    • Authentication integration (OAuth2, API key, bearer token via HTTP headers)
    • Automatic retry with exponential backoff for transient failures
    • Connection pooling via httpx.AsyncClient
  • transport_protocol.pyA2aTransport Protocol (shared with stdio transport)
  • transport_selector.pyTransportSelector updated to pick A2aRemoteTransport when server.url is configured

Test files

  • features/a2a_http_transport.feature + step definitions — BDD tests for HTTP transport, SSE streaming, and authentication
  • robot/a2a_http_transport.robot + helper — Integration tests for end-to-end HTTP communication

Note

Both #691 (stdio) and #692 (HTTP) independently created transport_protocol.py and transport_selector.py since they branched from the same parent (#690). These will need reconciliation when merging — the Protocol definitions are compatible and the selector logic is complementary.

Quality Checks

  • nox -e typecheck — 0 Pyright errors
  • nox -e lint — all checks passed
  • nox -e format — all files unchanged
## Summary Implements the A2A HTTP transport for server mode per the specification (§Architecture > Transport Modes), enabling client-server communication via a single JSON-RPC 2.0 HTTP endpoint with SSE streaming support. Closes #692 ## Changes ### New modules in `src/cleveragents/a2a/` - **`http_transport.py`** — `A2aRemoteTransport` class implementing: - HTTP POST to single JSON-RPC endpoint using A2A SDK `A2AClient` - SSE streaming for long-running operations via `TaskStatusUpdateEvent` and `TaskArtifactUpdateEvent` - Authentication integration (OAuth2, API key, bearer token via HTTP headers) - Automatic retry with exponential backoff for transient failures - Connection pooling via `httpx.AsyncClient` - **`transport_protocol.py`** — `A2aTransport` Protocol (shared with stdio transport) - **`transport_selector.py`** — `TransportSelector` updated to pick `A2aRemoteTransport` when `server.url` is configured ### Test files - `features/a2a_http_transport.feature` + step definitions — BDD tests for HTTP transport, SSE streaming, and authentication - `robot/a2a_http_transport.robot` + helper — Integration tests for end-to-end HTTP communication ### Note Both #691 (stdio) and #692 (HTTP) independently created `transport_protocol.py` and `transport_selector.py` since they branched from the same parent (#690). These will need reconciliation when merging — the Protocol definitions are compatible and the selector logic is complementary. ## Quality Checks - `nox -e typecheck` — 0 Pyright errors - `nox -e lint` — all checks passed - `nox -e format` — all files unchanged
refactor(a2a): rename ACP module and symbols to A2A standard
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 20s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 35s
CI / security (pull_request) Successful in 47s
CI / typecheck (pull_request) Successful in 1m37s
CI / integration_tests (pull_request) Successful in 3m38s
CI / unit_tests (pull_request) Successful in 4m44s
CI / docker (pull_request) Successful in 1m6s
CI / coverage (pull_request) Successful in 5m30s
CI / benchmark-regression (pull_request) Successful in 35m37s
2fe95d1b38
Renamed src/cleveragents/acp/ to src/cleveragents/a2a/ and all 13
Acp* classes to A2a* per ADR-047 (A2A Standard Adoption). Updated
all imports, structlog event names (acp.* → a2a.*), field names
(acp_version → a2a_version), and test references across the entire
codebase. This is a cosmetic rename only — no behavioral changes.

ISSUES CLOSED: #688
feat(a2a): implement JSON-RPC 2.0 wire format and method routing
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 18s
CI / security (pull_request) Successful in 35s
CI / typecheck (pull_request) Successful in 55s
CI / unit_tests (pull_request) Successful in 2m57s
CI / integration_tests (pull_request) Successful in 3m23s
CI / docker (pull_request) Successful in 41s
CI / coverage (pull_request) Successful in 5m36s
CI / benchmark-regression (pull_request) Successful in 35m11s
33900eab03
Implement the JSON-RPC 2.0 wire format layer and method routing for the
A2A protocol, building on the ACP-to-A2A rename from #688.

New modules in src/cleveragents/a2a/:
- jsonrpc_models.py: Pydantic v2 models for JSON-RPC 2.0 request,
  response, error, and notification envelopes
- jsonrpc_router.py: Method router that dispatches JSON-RPC requests
  to registered handlers, with support for standard A2A methods and
  _cleveragents/ extension methods
- jsonrpc_handlers.py: Handlers for standard A2A methods (message/send,
  message/stream, tasks/get, tasks/cancel) and extension method factory
  that delegates to A2aLocalFacade
- jsonrpc_errors.py: Maps domain error taxonomy to JSON-RPC 2.0 error
  codes (standard -32700 to -32603, application -32001 to -32008)
- agent_card.py: Agent Card model and generation for the
  /.well-known/agent.json capability advertisement endpoint

Standard A2A methods:
- message/send: Create/update tasks via messages
- message/stream: Streaming variant with SSE event indicators
- tasks/get: Retrieve task by ID
- tasks/cancel: Cancel running tasks

CleverAgents extension methods (_cleveragents/ prefix):
- plan/use, execute, status, diff, apply, cancel
- registry/list_tools, list_resources
- context/show
- sync/status
- namespace/list
- health

Tests:
- Behave BDD: features/a2a_jsonrpc.feature (28 scenarios)
- Robot Framework: robot/a2a_jsonrpc.robot (9 integration tests)

ISSUES CLOSED: #690
feat(a2a): implement A2A HTTP transport for server mode
Some checks failed
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Failing after 14s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 38s
CI / coverage (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Has been skipped
CI / security (pull_request) Successful in 52s
CI / unit_tests (pull_request) Successful in 3m12s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 3m29s
25605b1ba4
Implement the client-side A2A HTTP transport for server mode, enabling
JSON-RPC 2.0 communication over HTTP with SSE streaming support.

New components:
- A2aTransport Protocol (transport_protocol.py): Abstract interface that
  all transport implementations (HTTP, stdio) must satisfy, with methods
  for connect/disconnect lifecycle, send, and send_streaming.
- A2aRemoteTransport (http_transport.py): Client-side HTTP transport using
  httpx that sends JSON-RPC 2.0 requests to a remote A2A server. Supports
  SSE streaming for message/stream (TaskStatusUpdateEvent and
  TaskArtifactUpdateEvent), authentication via bearer token/API key/custom
  headers (AuthConfig), TLS verification, and context manager usage.
- TransportSelector (transport_selector.py): Picks the appropriate transport
  based on ServerConnectionConfig — returns A2aRemoteTransport when
  server.url is configured, raises A2aNotAvailableError for local/stdio
  mode (pending stdio transport implementation).
- SSE event parser for consuming Server-Sent Events streams.
- httpx added as a project dependency.

Tests:
- 26 Behave BDD scenarios covering protocol definition, auth config,
  transport construction, connection lifecycle, request serialization,
  response parsing, SSE parsing, TransportSelector, and contract tests.
- 9 Robot Framework integration tests with helper script verifying
  end-to-end transport behavior.

ISSUES CLOSED: #692
freemo added this to the v3.8.0 milestone 2026-03-12 02:09:48 +00:00
fix(lint): remove unused MagicMock import from HTTP transport steps
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 16s
CI / build (pull_request) Successful in 17s
CI / quality (pull_request) Successful in 20s
CI / security (pull_request) Successful in 37s
CI / typecheck (pull_request) Successful in 59s
CI / unit_tests (pull_request) Successful in 3m5s
CI / integration_tests (pull_request) Successful in 3m27s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 5m28s
CI / benchmark-regression (pull_request) Successful in 36m25s
3249b87926
freemo self-assigned this 2026-03-12 20:33:30 +00:00
Author
Owner

PM Status — Day 32

State: CONFLICTED — needs rebase onto master.

Priority: Low — M9 (v3.8.0), no deadline. Current focus should be M3-M6.

Dependencies: Depends on #708 (JSON-RPC) and #713 (stdio) being merged first. #722 (LangGraph Platform) depends on this.

File overlap with #713: Both PRs create transport_protocol.py and transport_selector.py. #713 (stdio) should merge first, then this PR rebases to reconcile the shared modules. The Protocol definitions are compatible and the selector logic is complementary (one adds stdio, the other adds HTTP).

Missing labels: Adding Priority/Low, MoSCoW/Could have, Points/13, State/In Progress.

@freemo — No immediate action needed. This is third in the M9 merge chain (#708#713#720#722).

### PM Status — Day 32 **State:** CONFLICTED — needs rebase onto master. **Priority:** Low — M9 (v3.8.0), no deadline. Current focus should be M3-M6. **Dependencies:** Depends on #708 (JSON-RPC) and #713 (stdio) being merged first. #722 (LangGraph Platform) depends on this. **File overlap with #713:** Both PRs create `transport_protocol.py` and `transport_selector.py`. #713 (stdio) should merge first, then this PR rebases to reconcile the shared modules. The Protocol definitions are compatible and the selector logic is complementary (one adds stdio, the other adds HTTP). **Missing labels:** Adding Priority/Low, MoSCoW/Could have, Points/13, State/In Progress. @freemo — No immediate action needed. This is third in the M9 merge chain (#708 → #713 → #720 → #722).
Author
Owner

Rebase Required

@freemo — This PR has merge conflicts with master. Please rebase onto the latest master and force-push. See also: #668, #669, #703, #708, #713, #722 (all need rebase).

## Rebase Required @freemo — This PR has merge conflicts with `master`. Please rebase onto the latest `master` and force-push. See also: #668, #669, #703, #708, #713, #722 (all need rebase).
Author
Owner

PM Review — Day 34

Status: NOT mergeable (conflicts), 0 reviews, M9 (v3.8.0), Priority/Low, Points/13
Author: @freemo

A2A HTTP transport for server mode. M9 — lowest urgency. Rebase deferred.

Action Items

Who Action Deadline
@freemo Rebase when M9 sprint begins M9 sprint
## PM Review — Day 34 **Status**: NOT mergeable (conflicts), 0 reviews, M9 (v3.8.0), Priority/Low, Points/13 **Author**: @freemo A2A HTTP transport for server mode. M9 — lowest urgency. Rebase deferred. ### Action Items | Who | Action | Deadline | |-----|--------|----------| | @freemo | Rebase when M9 sprint begins | M9 sprint |
Author
Owner

PM Status — Day 36 (2026-03-16)

Confirmed deferred status. M8/M9 rebase and review deferred until M3-M6 queue clears. No action required at this time.

Next check: Day 40 or when M6 work is substantially complete.

## PM Status — Day 36 (2026-03-16) Confirmed deferred status. M8/M9 rebase and review deferred until M3-M6 queue clears. No action required at this time. **Next check**: Day 40 or when M6 work is substantially complete.
freemo left a comment

PM Day 36: A2A HTTP transport for server mode. M9 scope (deferred). @freemo author.

PM Day 36: A2A HTTP transport for server mode. M9 scope (deferred). @freemo author.
Author
Owner

This feature is for a later version, so closing it and will do it at the appropriate time.

This feature is for a later version, so closing it and will do it at the appropriate time.
freemo closed this pull request 2026-03-16 22:35:09 +00:00
All checks were successful
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 16s
Required
Details
CI / build (pull_request) Successful in 17s
Required
Details
CI / quality (pull_request) Successful in 20s
Required
Details
CI / security (pull_request) Successful in 37s
Required
Details
CI / typecheck (pull_request) Successful in 59s
Required
Details
CI / unit_tests (pull_request) Successful in 3m5s
Required
Details
CI / integration_tests (pull_request) Successful in 3m27s
Required
Details
CI / docker (pull_request) Successful in 40s
Required
Details
CI / coverage (pull_request) Successful in 5m28s
Required
Details
CI / benchmark-regression (pull_request) Successful in 36m25s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core!720
No description provided.