Skip to content

feat: Add X402RemoteAgentToolset for local agent orchestration#22

Merged
pcarranzav merged 9 commits intomainfrom
feat/x402-local-agent-toolset
Dec 10, 2025
Merged

feat: Add X402RemoteAgentToolset for local agent orchestration#22
pcarranzav merged 9 commits intomainfrom
feat/x402-local-agent-toolset

Conversation

@pcarranzav
Copy link
Member

@pcarranzav pcarranzav commented Dec 5, 2025

Summary

Implements X402RemoteAgentToolset - a reusable BaseToolset component that enables local ADK agents to orchestrate multiple remote A2A agents as tools with automatic x402 payment handling.

What's Included

X402RemoteAgentToolset

Location: python/ampersend-sdk/src/ampersend_sdk/a2a/client/x402_remote_agent_toolset.py

A toolset that provides two ADK tools for interacting with remote A2A agents:

  • x402_a2a_list_agents - List available remote agents with descriptions
  • x402_a2a_send_to_agent - Send messages to specific agents

Key features:

  • Automatic remote agent discovery via before_agent_callback
  • Transparent x402 payment handling via existing middleware
  • Per-agent conversation context management using ADK state
  • Full type safety (mypy strict mode)
  • Comprehensive docstrings

Usage Example

from ampersend_sdk.a2a.client import X402RemoteAgentToolset
from ampersend_sdk.x402.treasurers import NaiveTreasurer
from ampersend_sdk.x402.wallets.account import AccountWallet
from google.adk import Agent

# Setup
wallet = AccountWallet(private_key="0x...")
treasurer = NaiveTreasurer(wallet=wallet)

toolset = X402RemoteAgentToolset(
    remote_agent_urls=["https://subgraph-a2a.x402.staging.thegraph.com"],
    treasurer=treasurer
)

# Create orchestrator agent
agent = Agent(
    name="orchestrator",
    model="gemini-2.0-flash",
    tools=[toolset],
    before_agent_callback=toolset.get_before_agent_callback()
)

This enables building multi-agent systems where a local orchestrator can delegate tasks to specialized remote agents with automatic payment handling and spend limits.

Testing

  • ✅ Type checking: uv run mypy python/ampersend-sdk/src/ampersend_sdk/a2a/client/x402_remote_agent_toolset.py
  • ✅ Linting: uv run ruff check python/ampersend-sdk/src/ampersend_sdk/a2a/client/x402_remote_agent_toolset.py

🤖 Generated with Claude Code

Add X402RemoteAgentToolset, a BaseToolset implementation that enables
local ADK agents to orchestrate multiple remote A2A agents as tools.

Key features:
- Automatic remote agent discovery via before_agent_callback
- Two ADK tools: x402_a2a_list_agents and x402_a2a_send_to_agent
- Automatic x402 payment handling via existing middleware
- Per-agent conversation context management using ADK state
- Full type safety and comprehensive docstrings

This enables building multi-agent systems where a local orchestrator
can delegate tasks to specialized remote agents with transparent
payment handling and spend limits via AmpersendTreasurer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Prevent conflicts when multiple remote agents have the same name
in their agent cards by raising a clear error during discovery.
Add optional task_callback parameter and artifact chunking to properly
handle streaming responses from remote agents.

Changes:
- Add task_callback parameter for progress updates
- Implement _process_artifact_event for chunked artifact handling
- Fix streaming iteration to accumulate Task properly
- Handle Message early return (immediate completion)
- Process TaskArtifactUpdateEvent and TaskStatusUpdateEvent

This makes the toolset more versatile and correctly handles streaming
responses, following the pattern from google-agentic-commerce/a2a-x402
example while leveraging our x402 middleware for payment handling.
Add test suite covering core toolset functionality:

Initialization tests (3):
- Default and custom parameters
- before_agent_callback returns callable

Agent discovery tests (3):
- Successful agent discovery
- Duplicate agent name detection
- Discovery runs only once

Tool registration tests (2):
- get_tools returns FunctionTool instances
- Tool names are correctly set

list_agents tests (2):
- Returns empty before discovery
- Returns agent info after discovery

send_to_agent tests (4):
- Agent not found raises ValueError
- Message response handling
- Task response handling
- Context ID storage and updates

Callback tests (2):
- Callback called on updates
- No error when callback is None

Artifact chunking tests (2):
- Complete artifact (no chunking)
- Streaming artifact chunks assembled correctly

Error handling tests (2):
- JSONRPCErrorResponse raises RuntimeError
- No response raises RuntimeError

All 20 tests pass. Uses mocks to avoid network calls.
Added mypy override for test files to relax strict typing rules.
Add third tool to retrieve detailed information about specific agents
including full agent card with capabilities, skills, version, and
documentation URL.

This allows the LLM to inspect agent details before delegating tasks,
making more informed decisions about which agent to use.

Updated tests: Now 22 tests (added 2 for new tool), all passing.
Use full tool names (x402_a2a_get_agent_details, x402_a2a_send_to_agent)
in docstring examples to match the actual tool names that the LLM sees.
Update parameter descriptions to reference x402_a2a_list_agents
instead of list_agents to match the actual tool name.
@pcarranzav pcarranzav marked this pull request as ready for review December 8, 2025 16:36
Copy link
Contributor

@cmwhited cmwhited left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My python knowledge is... smol. But, the code looks well-written. I like the comments and tests. So gonna give it a LGTM

Copy link

@benface benface left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PLGTM

Pass the toolset's httpx_client to ClientConfig so that A2A clients
use the same timeout (30s default or user-provided) instead of
creating their own client with the default 5s timeout.

This fixes timeout errors when remote agents take longer than 5s to respond.
@pcarranzav pcarranzav merged commit 9f3e719 into main Dec 10, 2025
6 checks passed
@pcarranzav pcarranzav deleted the feat/x402-local-agent-toolset branch December 10, 2025 17:43
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.

3 participants