Add A2A protocol bridge and client primitives#6
Conversation
A2A support is implemented as localized bridge/client packages. The server bridge wraps a Runner through the official a2a-go request handler and maps A2A tasks onto Runner.Start, StreamEvents, Wait, and Cancel. The thin client wraps official discovery and transport behavior behind stable agent-adaptor DTOs so remote protocol traffic is not flattened into local CLI semantics. Constraint: Issue #4 requires the official A2A Go SDK and no core SDK A2A API. Constraint: Existing workspace had unrelated dirty changes, so this work was isolated in a clean worktree. Rejected: Hand-rolled JSON-RPC/SSE bridge | duplicates official SDK wire behavior and violates dependency requirement. Rejected: Remote A2A AgentBinding | conflates remote protocol tasks with local CLI workspace/profile/stdout semantics and is out of scope. Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep A2A imports confined to pkg/bridges/a2a and pkg/clients/a2a; do not add A2A-specific core SDK APIs without a new design. Tested: go test ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test ./... Tested: go vet ./... Not-tested: go test -race ./pkg/clients/a2a ./pkg/bridges/a2a | Windows race detector requires cgo and no gcc/clang/zig C compiler is installed in PATH. Not-tested: live third-party A2A endpoint interop. Related: #4
Owner Review: Request ChangesThis PR is directionally aligned with the repository boundary: A2A stays localized under Blocking / High
Medium
Verification PerformedLocal verification on a detached PR worktree:
Recommendation: Request changes until the A2A final-state semantics and CI failure are fixed. |
Owner Review: Request ChangesThis PR is directionally aligned with issue #4 on the package boundary: A2A stays localized under Blocking / High
Medium
Files: The served card includes security schemes/requirements, capability extensions, and rich skill fields, but
Files: Current tests cover happy paths, basic cancel, one protocol error, and import boundaries. Missing high-value coverage includes start failure, partial stream then wait failure, Verification PerformedOn a clean detached PR worktree at
Recommendation: REQUEST CHANGES until the protocol final-state semantics, cancellation race, capability truthfulness, lifecycle ownership, credential boundary, raw-data exposure, and CI failure are addressed. |
Additional Owner Review FindingThe rerun code-reviewer subagent found one additional issue that was not explicitly called out in my consolidated owner review, and I agree it should be tracked before merge. Medium: streamed A2A artifacts never mark their final chunkFiles:
Required fix: set |
Owner review found that the first A2A slice had protocol-final, lifecycle, capability, credential, and remote exposure gaps. This change keeps A2A localized while making the public bridge/client contracts truthful under review pressure. Constraint: PR #6 review required production-grade fixes without adding A2A concepts to core SDK execution semantics Constraint: A2A 1.0 SubscribeToTask has no cursor replay field Rejected: Trust Agent Card cross-origin interface URLs by default | bearer credentials could be leaked to attacker-controlled endpoints Rejected: Continue using upstream default in-memory task store | it is process-local and unbounded for bridge defaults Rejected: Advertise push or extended-card support from booleans alone | runtime collaborators are required for truthful capability discovery Confidence: high Scope-risk: moderate Directive: Keep A2A lifecycle, auth-origin, and raw-exposure policy inside pkg/bridges/a2a and pkg/clients/a2a; do not move these concerns into core SDK Tested: go test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test ./... Tested: go vet ./... Tested: git diff --check Not-tested: Local Windows race detector because cgo needs gcc and no C compiler is installed in PATH; CI now runs go test -race for A2A packages on Ubuntu
|
Owner follow-up after review fixes: I reviewed the comments and found the substantive findings reasonable. I did not find a comment that should be rejected as incorrect. Addressed in 79b78bc:
Verification:
Local note: go test -race could not run on this Windows host because cgo requires a C compiler and gcc/clang/zig are not installed in PATH. The workflow now runs the A2A race test on Ubuntu. |
Issue #5 needs the A2A client to carry tenant-aware lookup and cancellation metadata without another public API break after issue #4 merges. This changes task lookup and cancellation to request DTOs before the A2A package is merged, and promotes bridge-owned artifact names to exported constants so the visual subagent mux can consume stable wire conventions instead of string literals. Constraint: Issue #4 must remain localized to A2A protocol primitives and not implement the issue #5 delegation bus or MCP tool surface Constraint: A2A GetTask and CancelTask both carry tenant fields upstream; GetTask also carries historyLength and CancelTask carries metadata Rejected: Leave GetTask/CancelTask string-only until issue #5 | would force a public API break or lossy tenant/cancel semantics in the delegation workstream Rejected: Let issue #5 match assistant-output by magic string | brittle and undocumented bridge contract Confidence: high Scope-risk: narrow Directive: Keep visual delegation implementation in issue #5 packages; issue #4 should only expose stable A2A primitives and bridge wire conventions Tested: go test ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test ./... Tested: go vet ./... Tested: git diff --check Not-tested: Local Windows race detector; this host still lacks a C compiler for cgo
|
Follow-up substrate optimization for issue #5 in
This keeps PR #6 inside the issue #4 boundary while removing avoidable API churn for issue #5. Verification after the change:
|
The A2A bridge and client now have a runnable local example that exercises Agent Card discovery, streaming task execution, bridge-owned artifacts, and GetTask polling against a real local runner. The demo creates an isolated workspace and cloned provider profile so it does not write state into a host's active agent profile, while still seeding native settings and linking auth files so custom API key and base URL setups work in the isolated run. Constraint: A2A bridge execution always requests SDK streaming, so the example must exercise provider streaming paths rather than a fake runner or non-streaming CLI shortcut. Constraint: Local provider credentials may live in settings files instead of recognized auth files, especially custom API key/proxy setups. Rejected: Use a mock runner for the demo | it would not prove the bridge/client/SDK/provider integration that issue #4 is meant to expose. Rejected: Use native profiles directly | that could write demo state into the user's active provider profile. Rejected: Clone auth files only | custom API key/base URL settings were lost in isolated Claude/Codex runs. Confidence: high Scope-risk: narrow Directive: Keep this example isolated by default; do not switch it to WithNativeProfile or a shared workspace for convenience. Tested: go test ./examples/a2a-local ./pkg/clients/a2a ./pkg/bridges/a2a Tested: go test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2a ./examples/a2a-local Tested: go test ./... Tested: go vet ./... Tested: git diff --check Tested: go run ./examples/a2a-local -agent=claude -timeout=2m Tested: go run ./examples/a2a-local -agent=codex -timeout=2m Tested: go run ./examples/a2a-local -agent=codex -serve-only -timeout=1s
|
Added an isolated runnable A2A example in commit c9aad7f.\n\nWhat changed:\n- New �xamples/a2a-local starts a local A2A JSON-RPC server around a real SDK runner, then calls it through pkg/clients/a2a.\n- The demo verifies Agent Card discovery, streaming task events/artifacts, terminal result artifact exposure, and GetTask polling.\n- The demo uses a temporary workspace and cloned provider profile by default. It copies native settings into the isolated profile for custom API key/base URL setups, links auth files via CloneProfileAuthLink, and does not write to the host's active profile.\n- README/docs and the example smoke runner now include the A2A demo.\n\nVerification:\n- go test ./examples/a2a-local ./pkg/clients/a2a ./pkg/bridges/a2a\n- go test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2a ./examples/a2a-local\n- go test ./...\n- go vet ./...\n- git diff --check\n- go run ./examples/a2a-local -agent=claude -timeout=2m\n- go run ./examples/a2a-local -agent=codex -timeout=2m\n- go run ./examples/a2a-local -agent=codex -serve-only -timeout=1s\n\nCI: build passed on c9aad7f. |
Summary
agentadaptor.Runnerthrough the officiala2a-go/v2server handler without importing concrete adapters or changing core SDK APIs.Verification
go test ./pkg/clients/a2a ./pkg/bridges/a2ago test -count=20 ./pkg/clients/a2a ./pkg/bridges/a2ago test ./...go vet ./...git diff --check --cachedKnown verification gap
go test -race ./pkg/clients/a2a ./pkg/bridges/a2acould not run on this Windows host because the race detector requires cgo and nogcc,clang, orzigcompiler is installed in PATH.Closes #4