feat(a2a): implement server-mode HTTP transport for A2A agent communication #11113
No reviewers
Labels
No labels
auto/needs-reevaluation
controller-managed
overdue
auto/blocked-by-deps
auto/ci-timeout
auto/claimed-implementer
auto/claimed-merge
auto/claimed-reviewer
auto/driver-down
auto/invariant-violation
auto/last-attempt-tier-0
auto/last-attempt-tier-1
auto/last-attempt-tier-2
auto/last-attempt-tier-min
Automation Tracking
auto/needs-conflict-resolution
auto/needs-implementer
auto/postmortem
auto/ready-to-merge
auto/restart-throttled
auto/revert
auto/sentinel
auto/stale-inactivity
auto/unstable
Blocked
Bounty
$100
Bounty
$1000
Bounty
$10000
Bounty
$20
Bounty
$2000
Bounty
$250
Bounty
$50
Bounty
$500
Bounty
$5000
Bounty
$750
MoSCoW
Could have
MoSCoW
Must have
MoSCoW
Should have
Needs Feedback
Points
1
Points
13
Points
2
Points
21
Points
3
Points
34
Points
5
Points
55
Points
8
Points
88
Priority
Backlog
Priority
CI Blocker
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Signed-off: Owner
Signed-off: Scrum Master
Signed-off: Tech Lead
Spike
State
Completed
State
Duplicate
State
In Progress
State
In Review
State
Paused
State
Unverified
State
Verified
State
Wont Do
Type
Automation
Type
Bug
Type
Discussion
Type
Documentation
Type
Epic
Type
Feature
Type
Legendary
Type
Refactor
Type
Support
Type
Task
Type
Testing
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
cleveragents/cleveragents-core!11113
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/issue-10921-a2a-http-transport"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
fix(tui): correctly handle non-UTF8 terminal input when reading file pathsto feat(a2a): implement server-mode HTTP transport for A2A agent communicationPR Review —
feat(a2a): implement server-mode HTTP transport for A2A agent communicationOverall verdict: REQUEST_CHANGES — Multiple blocking issues must be resolved before this PR can be approved.
CI Status (BLOCKING)
The following required CI gates are failing:
linttypechecksecurityunit_testsintegration_testsbenchmark-regressionstatus-checkPer company policy (CONTRIBUTING.md), all CI gates must pass before a PR can be approved. The specific failures identified during code review are documented below.
1. Correctness
The core implementation logic is broadly correct:
connect(),disconnect(),is_connected(), andsend()implement the required interface. JSON-RPC 2.0 request/response framing works correctly.BUG (blocking): There is an arithmetic inconsistency in the HTTP 4xx error code mapping. The formula
error_code = -32000 + (status_code - 400)produces-31996for HTTP 404. The test in both test files assertsresponse.error.code == -31997. One of these is wrong — align the implementation and the test. Note also that the comment in the test says-32000 + (404-400) = -31996yet asserts-31997, so the code is internally self-contradicting.2. Specification Alignment
PASS — The implementation replaces the stub with a working transport as described in issue #10921. The interface (
connect,send,disconnect,is_connected) matches the specification requirement.3. Test Quality (BLOCKING)
Multiple critical test placement and framework violations:
BLOCKING:
tests/unit/a2a_test_http_transport.pyandtests/unit/__init__.pyare placed intests/unit/, which is NOT a valid directory in this project. The project layout per CONTRIBUTING.md mandates:features/using Behave exclusivelytests/does not exist in the prescribed directory layoutRemove these files. All test coverage must be expressed as Behave scenarios in
features/with step definitions infeatures/steps/.BLOCKING:
features/steps/test_a2a_http_transport_pytest.pyis a pytest file placed insidefeatures/steps/. This directory is exclusively for Behave step definition modules (*_steps.py). A pytest file here will confuse the Behave test runner and is not executed bynox -s unit_tests. Remove this file and convert the coverage to Behave scenarios.BLOCKING:
features/steps/a2a_facade_steps.pycontains duplicate Python function names forstep_transport_connect. Python silently overwrites earlier definitions, causing Behave step resolution to break. See inline comment for details.The
features/a2a_http_transport.featurescenarios are reasonable and should be kept. However, the mock setup inline ina2a_facade_steps.pyusesunittest.mock.patchinline — mock objects should be placed infeatures/mocks/per CONTRIBUTING.md.4. Type Safety (BLOCKING)
The typecheck CI job is failing. Specific concerns:
features/steps/a2a_facade_steps.pycallscontext.transport.connect(url, tls_verify=False)butconnect()does not accept atls_verifykwarg. This is a type error AND a runtime error. The# type: ignore[arg-type]comment is also prohibited (zero tolerance).# type: ignore[arg-type]suppressions. Per CONTRIBUTING.md,# type: ignoreis never permitted. Every suppression must be removed and the underlying type issue resolved.5. Readability
PASS — Code is clear and well-structured. Variable names are descriptive.
6. Performance
PASS — No unnecessary operations. Suggestion (non-blocking): Consider making the
timeout=30configurable via__init__rather than hardcoded.7. Security (BLOCKING)
The security CI job is failing. Specific concern:
_get_ssl_context()whentls_verify=Falseuses bareSSLContext()withcontext.verify_mode = 0. The integer literal0is a magic number; it should bessl.CERT_NONE. Bandit will flag this as a security issue. Fix:8. Code Style (BLOCKING)
The lint CI job is failing. Specific concerns:
BLOCKING:
map_domain_erroris imported intransport.pybut never called. Ruff F401 (unused import). Remove it or use it — the issue acceptance criterion requires domain errors to be mapped viamap_domain_error.BLOCKING:
BytesIOis imported in both test files but never used. Ruff F401.9. Documentation
PARTIAL PASS — The class docstring is present. Suggestion (non-blocking): Add docstrings to all public methods (
connect,send,disconnect,is_connected) explaining parameters, return values, and raised exceptions.10. Commit and PR Quality (BLOCKING)
BLOCKING — Empty PR body: The PR description is completely empty. It must include a summary of changes and a closing keyword:
Closes #10921. Without this, the issue will not auto-close on merge and the PR violates requirement 1 of the PR checklist.BLOCKING — Commit footer missing ISSUES CLOSED: The commit (SHA
2d5a4ce) has noISSUES CLOSED: #10921line in the footer. Every commit must reference its issue.BLOCKING — No milestone: The PR has no milestone assigned. This is mandatory per CONTRIBUTING.md once the issue is in an active state.
BLOCKING — No Type/ label: The PR has no
Type/Featurelabel. Exactly oneType/label is required.BLOCKING — CHANGELOG not updated:
CHANGELOG.mdon this branch is identical to master. Add an entry under[Unreleased]describing the A2A HTTP transport implementation.BLOCKING — Branch name format incorrect: The branch is named
feat/issue-10921-a2a-http-transport. The required format isfeature/mN-<descriptive-name>(note:feature/, notfeat/; the milestone numberNmust appear). For example:feature/m8-a2a-http-transport.Summary of All Blocking Issues
tests/unit/is not a valid project directory — remove pytest filesfeatures/steps/test_a2a_http_transport_pytest.pyis a pytest file in a Behave-only directorystep_transport_connectfunction ina2a_facade_steps.py# type: ignoresuppressions are prohibitedconnect()called with undeclaredtls_verify=Falsekwarg in step fileSSLContext()with magic number0— usessl.CERT_NONEmap_domain_errorimported but unused intransport.pyBytesIOimported but unused in test filesCloses #10921ISSUES CLOSED: #10921Type/Featurelabelfeat/prefix instead offeature/mN-formatAutomated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
BLOCKING — Duplicate Python function name
step_transport_connectThis file contains multiple
@when(...)decorated functions all namedstep_transport_connect:@when(r'I try to connect via the transport to "(?P<url>[^"]+)"')(existing stub step)@when(r"I connect the transport to (.+)")(new step added in this PR)@when(r"the transport is connected to (.+)")(new step added in this PR)Python silently overwrites earlier function definitions with the same name. This means Behave will only ever dispatch to the last-defined
step_transport_connect, causing the earlier steps to silently do the wrong thing or raise unexpected errors.Rename each function to a unique, descriptive name, e.g.:
step_try_connect_via_transport_to_url(for theI try to connectvariant)step_connect_transport_to_url(forI connect the transport to)step_transport_is_connected_to_url(forthe transport is connected to)Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
BLOCKING —
# type: ignore[arg-type]is prohibited + runtime errorcontext.transport.connect(url.strip("'\""), tls_verify=False)passestls_verify=Falseas a keyword argument toconnect(), butconnect()does not accept that parameter. This will raiseTypeErrorat runtime AND Pyright will flag it as a type error.The
# type: ignore[arg-type]comment is absolutely prohibited by CONTRIBUTING.md (zero tolerance, no exceptions).The
tls_verifysetting is configured at construction time via__init__. To test with TLS disabled, construct the transport with that setting:Then connect normally. Remove the
tls_verify=Falsekwarg from theconnect()call and delete the# type: ignorecomment.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
@ -0,0 +1,398 @@"""Pytest unit tests for A2aHttpTransport (server-mode HTTP transport)."""BLOCKING — Pytest file must not exist in
features/steps/This is a pytest test module placed in
features/steps/, which is exclusively for Behave step definition files. The project uses Behave for all unit tests (nox -s unit_testsruns Behave, not pytest). This file is not executed by the test runner and will confuse Behave's step discovery.Additionally
BytesIOis imported but never used — ruff will flag this as F401.Action required:
features/a2a_http_transport.featurewith step definitions infeatures/steps/a2a_http_transport_steps.py.features/mocks/.Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
@ -6,3 +2,4 @@from __future__ import annotationsimport jsonBLOCKING — Unused import causes lint failure (Ruff F401)
map_domain_erroris imported at line 5 but is never called anywhere in this file. Ruff will flag this as F401, causing the lint CI job to fail.The issue acceptance criterion states: "Domain errors are mapped via
map_domain_error". Either remove the unused import, or fulfil the acceptance criterion by using it in thesend()method to translate caught domain exceptions:Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
@ -18,4 +29,1 @@" - server mode will be implemented as a separate project")BLOCKING — Security: bare
SSLContext()with magic-numberverify_mode = 0Bandit will flag two issues here:
SSLContext()instantiated without specifying a protocol0is a magic number forssl.CERT_NONEFix by using named constants and
PROTOCOL_TLS_CLIENT:This is the correct pattern for disabling TLS verification while still using a properly constructed SSL context.
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
@ -0,0 +1,398 @@"""Pytest unit tests for A2aHttpTransport (server-mode HTTP transport)."""BLOCKING —
tests/unit/is not a valid project directoryThis project does not use
tests/as a test directory. The CONTRIBUTING.md directory layout prescribes onlyfeatures/(Behave BDD unit tests),features/mocks/(test doubles), androbot/(Robot Framework integration tests). There is notests/directory in the project structure.Additionally:
BytesIOis imported but never used (Ruff F401)Action required:
tests/unit/a2a_test_http_transport.pyandtests/unit/__init__.py.features/a2a_http_transport.featurewith step definitions infeatures/steps/a2a_http_transport_steps.py.The scenarios in the existing
features/a2a_http_transport.featureare a good start — they need step implementations that cover the same cases (SSL context, headers, roundtrip, network errors, etc.).Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
Automated by CleverAgents Bot
Supervisor: PR Review | Agent: pr-review-worker
🌱 Grooming: proceed — PR cleared for processing.
(check
no_duplicates, categoryno_duplicates)Anchor implements HTTP transport layer for A2A remote communication. Other A2A PRs address complementary concerns: JSON-RPC wire format/routing (#10910, #11114), stdio transport for local mode (#11105), service discovery (#1123, #10935), and various bug fixes. These are distinct architectural layers, not duplicates. ASGI server (#1107) is framework infrastructure, not A2A-specific transport.
📋 Estimate: tier 1.
Large new feature (7 files, +1213/-61) adding HTTP transport for A2A server-mode communication. Multiple real CI failures: E501 lint errors requiring line restructuring, a Pyright error on SSLContext.verify_mode assignment needing correct SSL API usage, unused import removal, a duplicate Behave step definition (ambiguous step at two locations in a2a_facade_steps.py), and a failing Robot integration test. Multi-file scope with new logic, test fixture changes, and integration test debugging all required — clearly tier 1 standard engineering work.
(attempt #7, tier 1)
🔧 Implementer attempt —
resolved.Pushed 1 commit:
094c981.Files touched:
features/consolidated_misc.feature,features/m6_autonomy_acceptance.feature,features/steps/a2a_facade_steps.py,features/steps/m6_facade_steps.py,features/steps/test_a2a_http_transport_pytest.py,robot/a2a_facade.robot,robot/helper_a2a_facade.py,robot/helper_m6_autonomy_acceptance.py,robot/m6_autonomy_acceptance.robot,src/cleveragents/a2a/transport.py,tests/unit/__init__.py,tests/unit/a2a_test_http_transport.py.The `agents actor run` and `actor_run` Typer commands wrapped their main try/except around `_resolve_config_files` with a bare `except click.exceptions.Exit: raise` clause to let resolver-raised exits propagate cleanly. Modern Typer re-exports `typer.Exit` from its vendored click (`typer._click.exceptions.Exit`), which is NOT a subclass of `click.exceptions.Exit`. So `_resolve_config_files`'s `raise typer.Exit(code=2)` for unknown-actor / no-config-data / bad-blob cases fell through to the generic `except Exception` clause, which re-raised as `typer.Exit(code=3)` and replaced the targeted stderr ("not found in registry") with a generic "Unexpected error" message. Behave scenarios at `actor_run_signature.feature:38` and `:56` and three Robot integration scenarios verified the original exit-code/message contract and failed. Catch `(typer.Exit, click.exceptions.Exit)` instead. The five errored scenarios in `actor_run_signature_resolve_steps.py` and `actor_run_signature_security_steps.py` had the same root cause from the test side: `except (SystemExit, click.exceptions.Exit)` could not catch the raised `typer.Exit`. Widen the tuple to include `typer.Exit`. memory_service.py's `SQLChatMessageHistory(connection_string=...)` call broke against langchain-community 0.4.2: the keyword was renamed `connection` (which now accepts a URL string OR an Engine). Update the call site and refresh the local `typings/langchain_community/...` pyright stub to match the upstream signature so typecheck stays clean. ISSUES CLOSED: #10921(attempt #12, tier 1)
🔧 Implementer attempt —
resolved.Pushed 1 commit:
7a248f1.Files touched:
features/steps/actor_run_signature_resolve_steps.py,features/steps/actor_run_signature_security_steps.py,src/cleveragents/application/services/memory_service.py,src/cleveragents/cli/commands/actor.py,src/cleveragents/cli/commands/actor_run.py,typings/langchain_community/chat_message_histories/__init__.pyi.7a248f11eeaaded29733(attempt #15, tier 1)
🔧 Implementer attempt —
ci-not-ready.✅ Approved
Reviewed at commit
aaded29.Confidence: high.
Claimed by
merge_drive.py(pid 2329255) until2026-06-14T21:41:25.354305+00:00.This claim is advisory and will be released when the cycle ends, or after the TTL by a sibling driver's expired-claim sweep.
aaded29733175692591bApproved by the controller reviewer stage (workflow 488).