UAT: Local mode A2A stdio transport not implemented — spec requires agent to run as subprocess with JSON-RPC over stdin/stdout #2170

Open
opened 2026-04-03 04:44:56 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/a2a-stdio-transport-local-mode
  • Commit Message: fix(a2a): implement A2aStdioTransport for local mode JSON-RPC over stdin/stdout
  • Milestone: v3.7.0
  • Parent Epic: #933

Background and Context

The specification designates the A2A Protocol as the sole communication protocol for all client-server interaction (spec §Architecture, §A2A Protocol). In local mode, the transport layer is stdio: the agent runs as a subprocess and JSON-RPC 2.0 messages flow over stdin/stdout. Platform extension methods (_cleveragents/*) are intercepted by A2aLocalFacade and routed to in-process Application-layer services — with no network, no authentication overhead, and no serialization beyond JSON-RPC framing.

The specification states explicitly:

"Local | A2A over stdio | Client spawns agent as subprocess; JSON-RPC messages flow over stdin/stdout. Platform extension methods are resolved in-process via A2aLocalFacade. | Bypassed (local user permissions)"

"In local mode, the agent runs as a subprocess. Standard A2A operations (message/send, message/stream) drive the conversation. Extension methods (_cleveragents/*) are intercepted by A2aLocalFacade and routed to in-process Application-layer services. No serialization beyond JSON-RPC framing, no network, no authentication overhead."

This is the primary mode for CLI, TUI, and IDE plugin clients. Without it, all clients must bypass the A2A protocol entirely and call A2aLocalFacade directly via Python imports — violating the architectural boundary.

Current Behavior

There is no stdio transport implementation anywhere in the codebase:

  • No A2aStdioTransport class exists in src/cleveragents/a2a/transport.py — only A2aHttpTransport (a stub that raises A2aNotAvailableError on all operations) is present.
  • No stdin/stdout JSON-RPC server loop exists in src/cleveragents/__main__.py — the module does not implement a subprocess-mode entry point.
  • A2aLocalFacade is not wired to any stdio transport — it is only used via cli_bootstrap.py for direct in-process Python calls, bypassing the A2A protocol entirely.

Searching the codebase confirms:

  • No A2aStdioTransport or equivalent class
  • No sys.stdin / sys.stdout JSON-RPC read/write loop
  • No subprocess entry point that reads JSON-RPC requests and writes JSON-RPC responses

Affected files:

  • src/cleveragents/a2a/transport.py — only A2aHttpTransport (stub) exists; no A2aStdioTransport
  • src/cleveragents/__main__.py — no stdio server loop / subprocess mode

Expected Behavior

Per the specification, in local mode the CleverAgents agent must be launchable as a subprocess that:

  1. Reads newline-delimited JSON-RPC 2.0 request objects from stdin
  2. Writes newline-delimited JSON-RPC 2.0 response objects to stdout
  3. Routes standard A2A operations (message/send, message/stream) through the conversation layer
  4. Intercepts _cleveragents/* extension methods via A2aLocalFacade and dispatches them to in-process Application-layer services
  5. Handles JSON-RPC 2.0 error framing ({"jsonrpc":"2.0","id":...,"error":{"code":...,"message":...}}) for all failure cases

A client (CLI, TUI, IDE plugin) must be able to spawn the agent as a subprocess and communicate exclusively via the A2A protocol over stdio — with no direct Python imports required.

Subtasks

  • Implement A2aStdioTransport class in src/cleveragents/a2a/transport.py — reads JSON-RPC 2.0 requests from stdin, writes responses to stdout
  • Implement the stdio server loop in src/cleveragents/__main__.py — entry point for subprocess/local mode
  • Wire A2aLocalFacade to A2aStdioTransport so extension methods are dispatched in-process
  • Implement JSON-RPC 2.0 framing for all stdio messages (request parsing, response serialisation, error envelope)
  • Handle message/send and message/stream standard A2A operations via stdio transport
  • Handle graceful shutdown (EOF on stdin, SIGTERM)
  • Add unit tests (pytest) for A2aStdioTransport — request parsing, response writing, error framing
  • Add Behave scenario: client spawns agent subprocess and exchanges JSON-RPC 2.0 messages over stdio
  • Add Robot integration test: end-to-end local mode round-trip via stdio transport
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • A2aStdioTransport exists and correctly reads JSON-RPC 2.0 requests from stdin and writes responses to stdout
  • src/cleveragents/__main__.py implements a subprocess entry point that starts the stdio JSON-RPC server loop
  • A2aLocalFacade is wired to A2aStdioTransport_cleveragents/* extension methods are dispatched in-process without any network calls
  • Standard A2A operations (message/send, message/stream) are handled correctly over stdio
  • JSON-RPC 2.0 error framing is correct for all failure cases
  • A client can spawn the agent as a subprocess and communicate exclusively via the A2A protocol over stdio
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/a2a-stdio-transport-local-mode` - **Commit Message**: `fix(a2a): implement A2aStdioTransport for local mode JSON-RPC over stdin/stdout` - **Milestone**: v3.7.0 - **Parent Epic**: #933 ## Background and Context The specification designates the A2A Protocol as the **sole** communication protocol for all client-server interaction (spec §Architecture, §A2A Protocol). In **local mode**, the transport layer is **stdio**: the agent runs as a subprocess and JSON-RPC 2.0 messages flow over stdin/stdout. Platform extension methods (`_cleveragents/*`) are intercepted by `A2aLocalFacade` and routed to in-process Application-layer services — with no network, no authentication overhead, and no serialization beyond JSON-RPC framing. The specification states explicitly: > "**Local** | A2A over **stdio** | Client spawns agent as subprocess; JSON-RPC messages flow over stdin/stdout. Platform extension methods are resolved in-process via `A2aLocalFacade`. | Bypassed (local user permissions)" > "In **local mode**, the agent runs as a subprocess. Standard A2A operations (`message/send`, `message/stream`) drive the conversation. Extension methods (`_cleveragents/*`) are intercepted by `A2aLocalFacade` and routed to in-process Application-layer services. No serialization beyond JSON-RPC framing, no network, no authentication overhead." This is the **primary mode** for CLI, TUI, and IDE plugin clients. Without it, all clients must bypass the A2A protocol entirely and call `A2aLocalFacade` directly via Python imports — violating the architectural boundary. ## Current Behavior There is no stdio transport implementation anywhere in the codebase: - **No `A2aStdioTransport` class** exists in `src/cleveragents/a2a/transport.py` — only `A2aHttpTransport` (a stub that raises `A2aNotAvailableError` on all operations) is present. - **No stdin/stdout JSON-RPC server loop** exists in `src/cleveragents/__main__.py` — the module does not implement a subprocess-mode entry point. - **`A2aLocalFacade` is not wired to any stdio transport** — it is only used via `cli_bootstrap.py` for direct in-process Python calls, bypassing the A2A protocol entirely. Searching the codebase confirms: - No `A2aStdioTransport` or equivalent class - No `sys.stdin` / `sys.stdout` JSON-RPC read/write loop - No subprocess entry point that reads JSON-RPC requests and writes JSON-RPC responses **Affected files:** - `src/cleveragents/a2a/transport.py` — only `A2aHttpTransport` (stub) exists; no `A2aStdioTransport` - `src/cleveragents/__main__.py` — no stdio server loop / subprocess mode ## Expected Behavior Per the specification, in local mode the CleverAgents agent must be launchable as a subprocess that: 1. Reads newline-delimited JSON-RPC 2.0 request objects from **stdin** 2. Writes newline-delimited JSON-RPC 2.0 response objects to **stdout** 3. Routes standard A2A operations (`message/send`, `message/stream`) through the conversation layer 4. Intercepts `_cleveragents/*` extension methods via `A2aLocalFacade` and dispatches them to in-process Application-layer services 5. Handles JSON-RPC 2.0 error framing (`{"jsonrpc":"2.0","id":...,"error":{"code":...,"message":...}}`) for all failure cases A client (CLI, TUI, IDE plugin) must be able to spawn the agent as a subprocess and communicate exclusively via the A2A protocol over stdio — with no direct Python imports required. ## Subtasks - [ ] Implement `A2aStdioTransport` class in `src/cleveragents/a2a/transport.py` — reads JSON-RPC 2.0 requests from stdin, writes responses to stdout - [ ] Implement the stdio server loop in `src/cleveragents/__main__.py` — entry point for subprocess/local mode - [ ] Wire `A2aLocalFacade` to `A2aStdioTransport` so extension methods are dispatched in-process - [ ] Implement JSON-RPC 2.0 framing for all stdio messages (request parsing, response serialisation, error envelope) - [ ] Handle `message/send` and `message/stream` standard A2A operations via stdio transport - [ ] Handle graceful shutdown (EOF on stdin, SIGTERM) - [ ] Add unit tests (pytest) for `A2aStdioTransport` — request parsing, response writing, error framing - [ ] Add Behave scenario: client spawns agent subprocess and exchanges JSON-RPC 2.0 messages over stdio - [ ] Add Robot integration test: end-to-end local mode round-trip via stdio transport - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - [ ] `A2aStdioTransport` exists and correctly reads JSON-RPC 2.0 requests from stdin and writes responses to stdout - [ ] `src/cleveragents/__main__.py` implements a subprocess entry point that starts the stdio JSON-RPC server loop - [ ] `A2aLocalFacade` is wired to `A2aStdioTransport` — `_cleveragents/*` extension methods are dispatched in-process without any network calls - [ ] Standard A2A operations (`message/send`, `message/stream`) are handled correctly over stdio - [ ] JSON-RPC 2.0 error framing is correct for all failure cases - [ ] A client can spawn the agent as a subprocess and communicate exclusively via the A2A protocol over stdio - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-03 04:45:01 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: High (confirmed) — The stdio transport is the primary mode for CLI, TUI, and IDE plugin clients. Without it, all clients bypass the A2A protocol entirely.
  • Milestone: v3.7.0 (confirmed — A2A Protocol Compliance Epic #933)
  • MoSCoW: Should Have — The stdio transport is architecturally important as it enforces the A2A protocol boundary for local mode. Currently, clients call A2aLocalFacade directly via Python imports, which works but violates the architectural boundary.
  • Parent Epic: #933 (confirmed correct)

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: High (confirmed) — The stdio transport is the **primary mode** for CLI, TUI, and IDE plugin clients. Without it, all clients bypass the A2A protocol entirely. - **Milestone**: v3.7.0 (confirmed — A2A Protocol Compliance Epic #933) - **MoSCoW**: Should Have — The stdio transport is architecturally important as it enforces the A2A protocol boundary for local mode. Currently, clients call `A2aLocalFacade` directly via Python imports, which works but violates the architectural boundary. - **Parent Epic**: #933 (confirmed correct) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo self-assigned this 2026-04-03 16:57:59 +00:00
Author
Owner

Starting implementation on branch fix/a2a-stdio-transport-local-mode.

Issue: UAT: Local mode A2A stdio transport not implemented — spec requires agent to run as subprocess with JSON-RPC over stdin/stdout

Plan: Implementing A2aStdioTransport class, stdio server loop in __main__.py, wiring A2aLocalFacade, JSON-RPC 2.0 framing, graceful shutdown, and full test coverage.

Subtask dependency analysis:

  • Wave 1 (parallel): Subtasks 1-6 (core implementation — transport class, server loop, facade wiring, JSON-RPC framing, message/send+stream handling, graceful shutdown)
  • Wave 2 (parallel): Subtasks 7-9 (tests — unit tests, Behave scenario, Robot integration test)
  • Wave 3 (sequential): Subtasks 10-11 (coverage verification and nox run)

Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker

Starting implementation on branch `fix/a2a-stdio-transport-local-mode`. **Issue**: UAT: Local mode A2A stdio transport not implemented — spec requires agent to run as subprocess with JSON-RPC over stdin/stdout **Plan**: Implementing `A2aStdioTransport` class, stdio server loop in `__main__.py`, wiring `A2aLocalFacade`, JSON-RPC 2.0 framing, graceful shutdown, and full test coverage. **Subtask dependency analysis:** - Wave 1 (parallel): Subtasks 1-6 (core implementation — transport class, server loop, facade wiring, JSON-RPC framing, message/send+stream handling, graceful shutdown) - Wave 2 (parallel): Subtasks 7-9 (tests — unit tests, Behave scenario, Robot integration test) - Wave 3 (sequential): Subtasks 10-11 (coverage verification and nox run) --- **Automated by CleverAgents Bot** Supervisor: Implementation | Agent: ca-issue-worker
Sign in to join this conversation.
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#2170
No description provided.