Skip to navigation

Protocol and App Bridges

A2AAdapter, A2AGatewayAdapter, the ACP server, and SlackAdapter

These adapters connect Band to something that is not an agent framework: a remote A2A agent, A2A clients, an ACP editor, or Slack. The bridges that need Band credentials read them from the PlatformConnection the runtime injects, so none takes api_key or rest_url. Every adapter follows the shared adapter construction rules and takes the feature keywords.

A2AAdapter

Brings a remote A2A agent into a room as a Band participant.

from band.adapters import A2AAdapter, A2AAdapterConfig
from band.adapters.a2a import A2AAuth
adapter = A2AAdapter(
config: A2AAdapterConfig,
**features: Unpack[FeatureKwargs],
)
A2AAdapterConfig fieldTypeRequiredDescription
remote_urlstrYesBase URL of the A2A agent
authA2AAuth | NoneNoAuthentication: API key, bearer token, or headers
streamingboolNoEnable SSE streaming for responses; default is True
from band.adapters import A2AAdapter, A2AAdapterConfig
adapter = A2AAdapter(A2AAdapterConfig(remote_url="http://localhost:9999"))

Declares no emit kinds or capabilities, and the remote agent’s turns are not judged by the turn-outcome rule. See A2A Adapter for a worked example.

A2AGatewayAdapter

Exposes Band peers as A2A HTTP endpoints.

from band.adapters import A2AGatewayAdapter, A2AGatewayAdapterConfig
adapter = A2AGatewayAdapter(
config: A2AGatewayAdapterConfig | None = None,
*,
rest_client: AsyncRestClient | None = None,
**features: Unpack[FeatureKwargs],
)
A2AGatewayAdapterConfig fieldTypeRequiredDescription
gateway_urlstr | NoneNoPublic URL for AgentCards; unset derives http://localhost:{port}
portintNoHTTP server port; default is 10000
response_timeout_sfloat | NoneNoSeconds to wait for a Band peer to answer an inbound A2A request; default is 300.0. None waits indefinitely; 0 or less raises ValidationError (Input should be greater than 0)

rest_client is a test injection seam; normally leave it unset. api_key and rest_url are not constructor parameters; passing either raises TypeError. The adapter builds its REST client at startup from the injected PlatformConnection. Declares no emit kinds or capabilities. See A2A Gateway for a worked example.

ACP Server

BandACPServerAdapter

Platform bridge for editor-facing ACP integrations. Import it from band.adapters.

from band.adapters import BandACPServerAdapter
adapter = BandACPServerAdapter(
config: BandACPServerAdapterConfig | None = None,
*,
rest_client: AsyncRestClient | None = None,
**features: Unpack[FeatureKwargs],
)

BandACPServerAdapterConfig has no fields yet. rest_client is a test injection seam. api_key and rest_url are not constructor parameters; passing either raises TypeError. The adapter builds its REST client from the injected PlatformConnection and declares no emit kinds or capabilities, so a nonempty emit or capabilities raises BandConfigError.

ACPServer

ACP protocol handler used with BandACPServerAdapter.

from band import Agent
from band.adapters import ACPServer, BandACPServerAdapter
adapter = BandACPServerAdapter()
server = ACPServer(adapter)
agent = Agent.from_config("my_agent", adapter=adapter)

ACPServer implements twelve ACP methods:

HandlerACP method
initializeinitialize
authenticateauthenticate
new_sessionsession/new
load_sessionsession/load
list_sessionssession/list
set_session_modesession/set_mode
set_config_optionsession/set_config_option
promptsession/prompt
cancelsession/cancel (notification)
fork_sessionsession/fork
resume_sessionsession/resume
close_sessionsession/close

It also exposes ext_method and ext_notification for ACP extension traffic. set_config_option is acknowledged and ignored. initialize advertises session/list, session/resume, session/fork, and session/close; the last three are unstable ACP routes that answer only when the server runs through run_acp_server(server) from band.integrations.acp, which is what band-acp uses, and plain acp.run_agent(server) returns method_not_found for them. session/close cancels the session’s active prompt.

See ACP Server for a worked example.

SlackAdapter

Wraps an inner framework adapter and bridges it into Slack.

from band.integrations.slack import SlackAdapter, SlackAdapterConfig, SlackApp
adapter = SlackAdapter(
config: SlackAdapterConfig,
*,
inner: SimpleAdapter,
web_client_factory: WebClientFactory | None = None,
rest_client: AsyncRestClient | None = None,
**features: Unpack[FeatureKwargs],
)
SlackAdapterConfig fieldTypeDefaultDescription
appstuple[SlackApp, ...]requiredOne or more Slack app configurations with unique slugs; each gets an HTTP route at /{slug}/events. A repeated slug raises ValidationError (Duplicate SlackApp slug: ...)
transport"http" | "socket""http""http" mounts a router via adapter.router; "socket" opens a Socket Mode WebSocket per app
write_tool_namesfrozenset[str]the platform’s write toolsTool names treated as state-changing writes for Slack progress rendering, such as band_send_message and band_add_participant
show_tool_progressboolTrueRender Block Kit plan and task progress blocks in Slack
mirror_slack_contextboolTrueMirror inbound Slack turns into the bound Band room as context-only events
ArgumentTypeRequiredDescription
innerSimpleAdapterYesFramework adapter that runs the reasoning, such as AnthropicAdapter
web_client_factoryWebClientFactory | NoneNoFactory for Slack web clients, mainly for tests
rest_clientAsyncRestClient | NoneNoREST client injection seam, mainly for tests. Left unset, the bridge builds its own from the injected PlatformConnection
from band.adapters import AnthropicAdapter
from band.integrations.slack import SlackAdapter, SlackAdapterConfig, SlackApp
adapter = SlackAdapter(
SlackAdapterConfig(
apps=(SlackApp(slug="dev", bot_token="xoxb-...", signing_secret="..."),),
),
inner=AnthropicAdapter(),
)

SlackAdapter has no port setting: mount adapter.router into your own ASGI app. Passing port to SlackAdapterConfig raises ValidationError.

Omit every feature keyword and the bridge adopts the inner adapter’s resolved features unchanged. Pass one and it merges over the inner adapter’s features field by field, writes the result onto the inner adapter, and validates against the inner adapter’s supported sets.

SlackApp

Configuration for one Slack app served by SlackAdapter. The required tokens depend on the config’s transport; the wrong combination raises ValidationError at config construction, for example transport='socket' requires app_token and bot_token on every SlackApp; missing for: dev.

ParameterTypeRequiredDescription
slugstrYesIdentifier used as the HTTP route segment /{slug}/events
bot_tokenstrYesSlack bot token (xoxb-...) for outbound API calls
signing_secretstrConditionalSlack signing secret for request verification; required for HTTP transport
app_tokenstrConditionalSlack app-level token (xapp-...) that opens a Socket Mode WebSocket; required for Socket Mode

See Slack for a worked example.