Skip to content

Conversation

@r-marques
Copy link
Member

Summary

  • Adds A2A (Agent-to-Agent) protocol as a new entry point alongside the existing HTTP/x402 mode for both seller and buyer agents
  • Seller gets poetry run agent-a2a with standard agent card discovery at /.well-known/agent.json and payment-protected JSON-RPC messaging via PaymentsA2AServer
  • Buyer gets discover_agent and purchase_a2a tools plus a scripted poetry run client-a2a demo
  • Payment handled at A2A message level by PaymentsRequestHandler (seller tools are plain @tool, no @requires_payment)

Files changed

File Action Description
seller/pyproject.toml Modified Add a2a extra to strands-agents, add agent-a2a script
seller/src/strands_agent_plain.py Created Plain @tool versions (no @requires_payment) for A2A mode
seller/src/agent_a2a.py Created A2A server: executor + agent card + PaymentsA2AServer
seller/.env.example Modified Add A2A_PORT
buyer/pyproject.toml Modified Add a2a extra to payments-py, add client-a2a script
buyer/src/tools/discover_a2a.py Created Fetch and parse agent card
buyer/src/tools/purchase_a2a.py Created A2A message via PaymentsClient
buyer/src/strands_agent.py Modified Add discover_agent and purchase_a2a tools + updated system prompt
buyer/src/client_a2a.py Created Scripted A2A demo
buyer/.env.example Modified Add SELLER_A2A_URL
READMEs + CLAUDE.md Modified Document A2A mode

Test plan

  • cd agents/seller-simple-agent && poetry install && poetry run agent-a2a starts without errors
  • curl -s http://localhost:9000/.well-known/agent.json returns agent card with urn:nevermined:payment extension
  • cd agents/buyer-simple-agent && poetry install && poetry run client-a2a discovers agent card and sends A2A message
  • Existing HTTP mode (poetry run agent / poetry run client) still works unchanged
  • Buyer interactive agent (poetry run agent) has both HTTP and A2A tools available

🤖 Generated with Claude Code

r-marques and others added 2 commits February 12, 2026 16:08
Add A2A (Agent-to-Agent) protocol as a new entry point alongside the
existing HTTP/x402 mode, enabling standard agent card discovery and
JSON-RPC messaging with payment-protected interactions.

Seller changes:
- New `poetry run agent-a2a` entry point with PaymentsA2AServer
- Agent card at /.well-known/agent.json with urn:nevermined:payment extension
- StrandsA2AExecutor wraps Strands agent for A2A message handling
- Plain tools (no @requires_payment) since PaymentsRequestHandler
  handles payment at the A2A message level

Buyer changes:
- New `discover_agent` tool fetches and parses A2A agent cards
- New `purchase_a2a` tool sends A2A messages via PaymentsClient
- New `poetry run client-a2a` scripted demo for A2A flow
- Updated system prompt to describe both HTTP and A2A workflows

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Seller: bump uvicorn to >=0.34.2 (required by strands-agents[a2a])
- Seller: require NVM_AGENT_ID for A2A mode (needed by agent card builder)
- Buyer: use direct JSON-RPC+httpx instead of PaymentsClient (avoids
  sync/async mismatch in PaymentsClient._get_access_token)
- Buyer: simplify client_a2a.py to reuse purchase_a2a_impl directly

Tested e2e: seller agent-a2a -> agent card -> buyer discovery -> A2A
JSON-RPC message with x402 token -> Strands agent execution -> response
with credits_used=1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@r-marques r-marques marked this pull request as draft February 12, 2026 15:28
r-marques and others added 3 commits February 12, 2026 16:32
Replace the manual JSON-RPC + httpx workaround in purchase_a2a.py with
PaymentsClient from payments-py, which handles x402 token generation
and injection automatically.

Key changes:
- buyer purchase_a2a.py: use PaymentsClient.send_message_stream() to
  collect SSE events and extract the final completed response
- seller agent_a2a.py: enable streaming in agent card capabilities
  (required by PaymentsClient which uses message/stream)
- Handle tuple-based SSE events (Task, TaskStatusUpdateEvent) returned
  by the a2a-sdk streaming client

Requires payments-py fix: nevermined-io/payments-py#135

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Released version includes the sync/async fix for
PaymentsClient._get_access_token (nevermined-io/payments-py#135).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix agent history accumulation bug: _calculate_credits() was scanning
all messages ever sent through the shared Strands agent, causing
incorrect credit counts on subsequent requests. Now snapshots the
message offset before each invocation and only counts new messages.

Code cleanup (code-simplifier):
- Extract _error()/_success() helpers in purchase_a2a.py
- Replace string-based error detection with proper exception types
- Extract _now_iso(), _make_status_event() helpers in agent_a2a.py
- Remove unused import json and pretty_json() in client_a2a.py
- Sort imports alphabetically

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@r-marques r-marques marked this pull request as ready for review February 12, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant