feat: add A2A (Agent-to-Agent) protocol integration#4135
feat: add A2A (Agent-to-Agent) protocol integration#4135Ridwannurudeen wants to merge 2 commits into
Conversation
4ef0f09 to
f0f3a9a
Compare
|
Hey @teknium1 — this implements all three phases from #514 (client, server, orchestration). What it does:
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. |
|
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)
f0f3a9a to
99b421d
Compare
|
Thanks for triaging @alt-glitch — happy to consolidate. Just rebased this PR onto current main (was ~3,600 commits behind). Conflicts resolved in 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 #4135 also implements Phase 3 — multi-agent orchestration ( Proposal:
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. |
|
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. |
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 endpointa2a_call— Send tasks with sync/streaming + multi-turn (INPUT_REQUIRED) supporta2a_list— List all known agents from config and discovery cachea2a_orchestrate— Fan out goals to multiple agents in parallel (modes:all,first,best) with auto-selection by skill matchingCommit 2: Server adapter (
a2a_adapter/)/.well-known/agent.json--bearer-token/HERMES_A2A_BEARER_TOKENenv var)127.0.0.1(localhost-only) — explicit opt-in for remote accesshermes-a2a --port 9990orpython -m a2a_adapterWiring
model_tools.py— Added to tool discovery so tools load at runtimetoolsets.py— Newa2atoolset with all 4 toolspyproject.toml—[a2a]optional dep (a2a-sdk[http-server]>=0.3.24), added to[all],hermes-a2aentry pointArchitecture
mcp_tool.py)~/.hermes/config.yamlundera2a_agentskeyasyncio.Lock(async) +threading.Lock(sync readers)ClientFactory(v0.3.25+) and legacyA2AClienta2a-sdknot installedConfig example
Test plan
test_a2a_tool.py+test_a2a_server.py), all mockedtest_a2a_integration.py) — real HTTP roundtrip with mocked AIAgent, marked@pytest.mark.integrationpip install -e '.[a2a]'→hermes-a2astarts, Agent Card serveda2a_discover+a2a_callfrom Hermes CLIFiles changed (12 files, +2,831 lines)
tools/a2a_tool.pya2a_adapter/__init__.pya2a_adapter/session.pya2a_adapter/server.pya2a_adapter/entry.pya2a_adapter/__main__.pypython -msupporttests/tools/test_a2a_tool.pytests/tools/test_a2a_server.pytests/tools/test_a2a_integration.pymodel_tools.pytoolsets.pypyproject.toml