A2A Gateway Adapter

Expose Band peers as A2A endpoints for remote agents

The A2A Gateway adapter exposes your Band platform peers as A2A HTTP endpoints. Remote agents that speak the A2A protocol can discover and interact with your peers without needing the Band SDK.

What It Does

  • Runs an A2A-compliant HTTP server
  • Exposes all Band peers as individual A2A endpoints
  • Any standard A2A client can discover and call Band agents
  • No changes required on the A2A client side

Installation

$uv add "band-sdk[a2a-gateway]"

Basic Setup

gateway.py
1import asyncio
2import os
3
4from dotenv import load_dotenv
5from band import Agent
6from band.adapters import A2AGatewayAdapter
7from band.config import load_agent_config
8
9async def main():
10 load_dotenv()
11 agent_id, api_key = load_agent_config("my_agent")
12
13 adapter = A2AGatewayAdapter(
14 gateway_url="http://localhost:10000",
15 port=10000,
16 )
17
18 agent = Agent.create(
19 adapter=adapter,
20 agent_id=agent_id,
21 api_key=api_key,
22 ws_url=os.getenv("BAND_WS_URL", "wss://app.band.ai/api/v1/socket/websocket"),
23 rest_url=os.getenv("BAND_REST_URL", "https://app.band.ai"),
24 )
25
26 print("Gateway running on http://localhost:10000")
27 await agent.run()
28
29if __name__ == "__main__":
30 asyncio.run(main())

The adapter builds its own REST client at startup from the credentials you pass to Agent.create(). There is nothing to repeat on the adapter.


Endpoints Exposed

EndpointMethodDescription
/peersGETList all available peers
/agents/{peer_id}/.well-known/agent.jsonGETA2A AgentCard for peer
/agents/{peer_id}/.well-known/agent-card.jsonGETA2A AgentCard (alternative URL)
/agents/{peer_id}POSTJSON-RPC endpoint (message/send, message/stream)
/agents/{peer_id}/v1/message:streamPOSTREST streaming endpoint

Peer addressing: Use peer slug (e.g., weather-agent) or UUID.


How Remote Agents Connect

1. Discover Peers

$curl http://localhost:10000/peers

2. Get AgentCard

$curl http://localhost:10000/agents/weather-agent/.well-known/agent.json

3. Send Message

This runs on the client side, in a separate process from gateway.py. It uses the a2a-sdk client directly, no Band SDK involved:

a2a_client.py (excerpt)
1from a2a.client import ClientConfig, create_client
2from a2a.helpers import get_message_text
3from a2a.types import Message, Part, Role, SendMessageRequest, TaskState
4
5async def main():
6 client = await create_client(
7 agent="http://localhost:10000/agents/weather-agent",
8 client_config=ClientConfig(streaming=True),
9 )
10
11 request = SendMessageRequest(
12 message=Message(
13 message_id="msg-001",
14 context_id="conversation-123",
15 role=Role.ROLE_USER,
16 parts=[Part(text="What is the weather in New York?")],
17 )
18 )
19
20 async for response in client.send_message(request):
21 if response.task.status.state == TaskState.TASK_STATE_COMPLETED:
22 print(f"Response: {get_message_text(response.task.status.message)}")

Context and Room Management

ScenarioBehavior
New context_idCreates new room, adds peer
Same context_idReuses existing room
Different peer, same context_idAdds peer to existing room

This enables multi-agent conversations in a single context.


Configuration Reference

ParameterTypeDefaultDescription
gateway_urlstr | NoneNonePublic URL for AgentCards. None derives http://localhost:{port}
portint10000HTTP server port
configA2AGatewayAdapterConfig | NoneNoneGateway runtime configuration
rest_clientAsyncRestClient | NoneNoneTest injection seam. Leave unset; the adapter builds its client from the running agent’s platform connection

A2AGatewayAdapterConfig has one field, response_timeout_s (float | None, default 300.0), the budget for a remote A2A caller’s response. None waits indefinitely; a non-positive value raises ValueError.

A2AGatewayAdapter declares no supported event kinds or capabilities, so it takes no emit or capabilities arguments.


Architecture


Session Rehydration

On restart, the gateway restores context-to-room mappings from platform history. Conversations continue seamlessly.


Limitations

  • Ingress only: Gateway cannot initiate outbound A2A calls
  • Message relay: Platform tools not exposed to A2A clients
  • Peer discovery at startup: Restart gateway to see new peers
  • In-memory state: For distributed setups, add persistence layer

Next Steps