Skip to content

feat: add A2A (Agent-to-Agent) protocol integration#4135

Closed
Ridwannurudeen wants to merge 2 commits into
NousResearch:mainfrom
Ridwannurudeen:feat/a2a-protocol-integration
Closed

feat: add A2A (Agent-to-Agent) protocol integration#4135
Ridwannurudeen wants to merge 2 commits into
NousResearch:mainfrom
Ridwannurudeen:feat/a2a-protocol-integration

Conversation

@Ridwannurudeen

@Ridwannurudeen Ridwannurudeen commented Mar 31, 2026

Copy link
Copy Markdown

Summary

Adds full A2A protocol support — client, server, and multi-agent orchestration — making Hermes the first open-source framework bridging MCP + ACP + A2A.

Closes #514

What's included

Commit 1: Client tools (tools/a2a_tool.py)

  • a2a_discover — Fetch Agent Cards from any A2A-compliant endpoint
  • a2a_call — Send tasks with sync/streaming + multi-turn (INPUT_REQUIRED) support
  • a2a_list — List all known agents from config and discovery cache
  • a2a_orchestrate — Fan out goals to multiple agents in parallel (modes: all, first, best) with auto-selection by skill matching

Commit 2: Server adapter (a2a_adapter/)

  • Exposes Hermes as an A2A-discoverable agent via JSON-RPC + Agent Card at /.well-known/agent.json
  • Session-per-task with AIAgent in ThreadPoolExecutor (mirrors ACP pattern)
  • Bearer token auth middleware (--bearer-token / HERMES_A2A_BEARER_TOKEN env var)
  • Defaults to 127.0.0.1 (localhost-only) — explicit opt-in for remote access
  • Entry: hermes-a2a --port 9990 or python -m a2a_adapter

Wiring

  • model_tools.py — Added to tool discovery so tools load at runtime
  • toolsets.py — New a2a toolset with all 4 tools
  • pyproject.toml[a2a] optional dep (a2a-sdk[http-server]>=0.3.24), added to [all], hermes-a2a entry point

Architecture

  • Background event loop in daemon thread (mirrors mcp_tool.py)
  • Config-driven agents via ~/.hermes/config.yaml under a2a_agents key
  • Thread-safe agent card caching with asyncio.Lock (async) + threading.Lock (sync readers)
  • Credential stripping in all error messages
  • Supports both ClientFactory (v0.3.25+) and legacy A2AClient
  • Optional dependency — graceful no-op when a2a-sdk not installed

Config example

a2a_agents:
  researcher:
    url: "http://localhost:9999"
    auth:
      type: "bearer"
      token: "sk-..."
    timeout: 120

Test plan

  • 71 unit tests passing (56 client/orchestration + 21 server — test_a2a_tool.py + test_a2a_server.py), all mocked
  • 3 integration tests (test_a2a_integration.py) — real HTTP roundtrip with mocked AIAgent, marked @pytest.mark.integration
  • CI passes (first fork run — needs maintainer approval)
  • Manual: pip install -e '.[a2a]'hermes-a2a starts, Agent Card served
  • Manual: configure a remote A2A agent, use a2a_discover + a2a_call from Hermes CLI

Files changed (12 files, +2,831 lines)

File Change
tools/a2a_tool.py NEW — Client tools + orchestration (~986 lines)
a2a_adapter/__init__.py NEW — Package init
a2a_adapter/session.py NEW — Session manager
a2a_adapter/server.py NEW — A2A server adapter + auth middleware
a2a_adapter/entry.py NEW — CLI entry point
a2a_adapter/__main__.py NEW — python -m support
tests/tools/test_a2a_tool.py NEW — 56 client/orchestration tests
tests/tools/test_a2a_server.py NEW — 21 server unit tests
tests/tools/test_a2a_integration.py NEW — 3 integration tests (real HTTP roundtrip)
model_tools.py +1 line (tool discovery)
toolsets.py +5 lines (a2a toolset)
pyproject.toml +5 lines (dep, entry point, all group)

Note: This PR implements all three phases from #514 in one PR since they share types, config, and the background event loop. Happy to split into separate PRs if preferred.

@Ridwannurudeen Ridwannurudeen force-pushed the feat/a2a-protocol-integration branch 2 times, most recently from 4ef0f09 to f0f3a9a Compare April 5, 2026 21:02
@Ridwannurudeen

Copy link
Copy Markdown
Author

Hey @teknium1 — this implements all three phases from #514 (client, server, orchestration).

What it does:

  • 4 client tools: a2a_discover, a2a_call, a2a_list, a2a_orchestrate
  • Server adapter exposing Hermes as an A2A-discoverable agent (hermes-a2a CLI)
  • Mirrors mcp_tool.py architecture (background event loop, optional dep, config-driven)

Since initial submission: rebased onto latest main, resolved conflicts, fixed 7 bugs found in self-review (factory client crash, auth propagation, concurrent request IDs, event loop blocking, middleware injection order). Squashed into 2 clean commits (client + server).

74 tests total (71 unit + 3 integration). Zero core architecture changes — plugs into existing tool registry and toolset system.

Happy to split into separate client/server PRs if you'd prefer smaller reviews. CI needs first-fork-run approval.

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/tools Tool registry, model_tools, toolsets labels May 2, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #11025 — same A2A protocol integration scope. Multiple prior attempts (#4952, #4948) also closed. Tracking issue: #514.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Likely duplicate of #11025 — same A2A protocol integration scope.

Add full A2A protocol client support — agent discovery, task delegation,
and multi-agent orchestration — making Hermes the first open-source
framework bridging MCP + ACP + A2A.

Client tools (tools/a2a_tool.py):
  - a2a_discover: fetch Agent Cards from any A2A-compliant endpoint
  - a2a_call: send tasks with sync/streaming + multi-turn support
  - a2a_list: list all known agents from config and discovery cache
  - a2a_orchestrate: fan out goals to multiple agents in parallel
    (modes: all, first, best) with auto-selection by skill matching

Architecture:
  - Background event loop in daemon thread (mirrors mcp_tool.py)
  - Config-driven agents via ~/.hermes/config.yaml (a2a_agents key)
  - Thread-safe agent card caching, credential stripping in errors
  - Supports both ClientFactory (v0.3.25+) and legacy A2AClient
  - Optional dependency — graceful no-op when a2a-sdk not installed

Tests: 56 client/orchestration tests, all mocked

Closes NousResearch#514
Expose Hermes as an A2A-discoverable agent via JSON-RPC + Agent Card
at /.well-known/agent.json, enabling external agents to call Hermes.

Server adapter (a2a_adapter/):
  - Session-per-task with AIAgent in ThreadPoolExecutor
  - Bearer token auth middleware (--bearer-token / env var)
  - Defaults to 127.0.0.1 (localhost-only) for security
  - Proper cancel with agent.interrupt() matching ACP pattern
  - Entry: hermes-a2a --port 9990 or python -m a2a_adapter

Tests: 21 server unit tests + 3 integration tests (real HTTP roundtrip
with mocked AIAgent, marked @pytest.mark.integration)
@Ridwannurudeen Ridwannurudeen force-pushed the feat/a2a-protocol-integration branch from f0f3a9a to 99b421d Compare May 3, 2026 09:10
@Ridwannurudeen

Copy link
Copy Markdown
Author

Thanks for triaging @alt-glitch — happy to consolidate.

Just rebased this PR onto current main (was ~3,600 commits behind). Conflicts resolved in pyproject.toml, model_tools.py, and toolsets.py; the model_tools.py change is now obsolete since upstream's auto-discovery picks up tools/a2a_tool.py automatically. The PR is ready for CI.

Context on PR ordering: #4135 was opened Mar 31, 16 days before #11025 (Apr 16). The earlier closures (#4948, #4952 by @balaji-embedcentrum) had no comments or reviews — they appear to be author self-closures rather than maintainer rejections, so they don't represent a rejected architecture.

Where the two PRs complement each other:

#11025 implements Phases 1+2 of @teknium1's roadmap in #514. Their gateway-platform-adapter placement is a defensible architectural call (#514 leaves placement open), and their security posture is genuinely stronger — 9 injection filters, outbound redaction, audit log to ~/.hermes/a2a_audit.jsonl. Happy to defer to #11025 for Phases 1+2.

#4135 also implements Phase 3 — multi-agent orchestration (a2a_orchestrate: fan-out goals to multiple agents in parallel, auto-selection by skill matching, modes all / first / best), which #11025 explicitly notes is out of scope. The orchestration tool is independent of the server adapter and could sit cleanly on top of #11025's gateway-adapter.

Proposal:

  1. Defer this PR in favor of feat: add A2A (Agent-to-Agent) protocol support #11025 for Phases 1+2.
  2. Once feat: add A2A (Agent-to-Agent) protocol support #11025 lands, I'll open a focused follow-up PR rebasing only the Phase 3 orchestration tool (a2a_orchestrate + its 56 unit tests) on top of their gateway-adapter base.
  3. Close feat: add A2A (Agent-to-Agent) protocol integration #4135 once feat: add A2A (Agent-to-Agent) protocol support #11025 merges.

If Phase 3 isn't on the near-term roadmap, happy to close #4135 now and revisit when orchestration becomes a priority. Let me know which works.

@teknium1

teknium1 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Closing in favor of #41711, which consolidates the entire A2A protocol cluster into a single platform-adapter plugin with zero core edits.

This pr contributed the canonical full client+server+orchestration A2A effort. Your design (client tools mirroring mcp_tool, server adapter mirroring acp_adapter, config-driven a2a_agents, credential stripping) directly shaped the consolidated plugin — the a2a_discover/a2a_call/a2a_list tools and the localhost-default bearer-auth posture come straight from your PR. Thanks @Ridwannurudeen!

See #41711 — the PR body has a table tracing each requirement back to its source issue/PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: A2A (Agent-to-Agent) Protocol Support — Remote Agent Discovery, Communication & Interoperability

3 participants