Skip to navigation

Adapter Features

How adapters are constructed, the emit and capabilities keywords, tool filters, and what each adapter supports

Every built-in adapter is built from one typed config object plus keyword-only live objects, and every one accepts the same five feature keywords. This page owns those shared rules; the per-adapter pages list only adapter-specific settings.

Adapter Construction

XAdapter(
config: XAdapterConfig | None = None,
*,
history_converter=..., # adapters that take one
additional_tools=..., # adapters that take them
..., # live objects: clients, graphs, factories, callbacks
**features: Unpack[FeatureKwargs],
)

config holds plain settings: model names, prompts, timeouts, and modes. Live objects stay keyword-only constructor arguments, so a config can always be loaded from YAML or JSON with XAdapterConfig.model_validate(data). config is required only when no usable default exists: A2AAdapter needs remote_url, ACPClientAdapter needs command, and SlackAdapter needs apps.

Every XAdapterConfig is a frozen pydantic model. An unknown field raises ValidationError (Extra inputs are not permitted), so a removed field name fails at construction instead of being ignored.

Adapter constructors take no flat settings. AnthropicAdapter(model="claude-sonnet-5-5") raises TypeError: SimpleAdapter._resolve_features() got an unexpected keyword argument 'model'. Pass AnthropicAdapter(AnthropicAdapterConfig(model="claude-sonnet-5-5")).

Common Adapter Options

The prompt options custom_section and system_prompt are fields on the adapter’s config object. history_converter and additional_tools are constructor arguments, and the **features keywords are constructor keywords.

The **features keywords are accepted by A2A, A2A gateway, ACPClient, Agno, Anthropic, ClaudeSDK, Codex, CopilotACP, CopilotSDK, CrewAI, CrewAI Flow, CursorACP, Gemini, GoogleADK, LangGraph, Letta, NOOA, OmpACP, OpenCode, Parlant, PydanticAI, Slack, and Strands. BandACPServerAdapter accepts the keywords but declares no emit kinds or capabilities, so a nonempty emit or capabilities raises BandConfigError.

OptionApplies toDescription
custom_section (config)ACPClient, Anthropic, ClaudeSDK, Codex, CopilotACP, CopilotSDK, CrewAI, CursorACP, Gemini, GoogleADK, LangGraph, Letta, NOOA, OmpACP, OpenCode, Parlant, PydanticAI, StrandsAdditional instructions added to the adapter prompt
system_prompt (config)Anthropic, Codex, Gemini, GoogleADK, Parlant, PydanticAI, StrandsFull prompt override where supported
emitAny adapter taking **featuresNarrow which event kinds the adapter reports into the room; see Adapter Features
capabilitiesAny adapter taking **featuresAdd platform tool groups to the schemas the model sees; see Adapter Features
include_toolsAny adapter taking **featuresKeep only these platform tools by name
exclude_toolsAny adapter taking **featuresDrop these platform tools by name
include_categoriesAny adapter taking **featuresKeep only platform tools in these categories: chat, contacts, memory, files
history_converter (argument)Agno, Anthropic, ClaudeSDK, Codex, CopilotSDK, CrewAI, CrewAI Flow, Gemini, GoogleADK, LangGraph, Letta, NOOA, OpenCode, Parlant, PydanticAI, StrandsConvert Band room history into the framework-specific format
additional_tools (argument)ACPClient, Anthropic, ClaudeSDK, Codex, CopilotACP, CopilotSDK, CrewAI, CrewAI Flow, CursorACP, Gemini, GoogleADK, LangGraph, NOOA, OmpACP, OpenCode, Parlant, PydanticAI, StrandsAdd framework-compatible custom tools

additional_tools takes CustomToolDef pairs, (InputModel, handler), where InputModel is a pydantic model describing the arguments; LangGraph also accepts LangChain tools, and Pydantic AI and Strands also accept plain callables. A custom tool declares what a successful call does to the turn with declares_turn_effect; see Custom Tools and Turn Effects.

Adapter Features

Adapters take their Band feature settings as direct keyword arguments, typed as **features: Unpack[FeatureKwargs]. There are five keys, all optional:

KeyTypeDefaultEffect
emitEmit | Iterable[Emit]Everything the adapter supportsEvent kinds reported into the room timeline
capabilitiesCapability | Iterable[Capability]NonePlatform tool groups added to the schemas the model sees
include_toolsIterable[str]AllKeep only platform tools with these names
exclude_toolsIterable[str]None droppedDrop platform tools with these names
include_categoriesIterable[str]AllKeep only platform tools in these categories: chat, contacts, memory, files
from band import Capability, Emit
from band.adapters import AnthropicAdapter, AnthropicAdapterConfig
config = AnthropicAdapterConfig(model="claude-sonnet-5-5")
# Report only token usage, and add the contact tools
adapter = AnthropicAdapter(
config,
emit={Emit.USAGE},
capabilities={Capability.CONTACTS},
)
# Emit is flag-capable, so a union, a set, or a list all work
adapter = AnthropicAdapter(config, emit=Emit.TOOL_CALLS | Emit.USAGE)
# Silence the adapter completely
adapter = AnthropicAdapter(config, emit=())

Emit and Capability members:

ValueEffect
Emit.TOOL_CALLSEmit tool_call and tool_result events into the room timeline
Emit.TASK_EVENTSEmit task lifecycle events
Emit.THOUGHTSEmit the agent’s intermediate reasoning as thought events
Emit.USAGEEmit turn token-usage events
Capability.CONTACTSAdd the contact tools
Capability.MEMORYAdd the memory tools
Capability.TASKSAdd the seven task board tools
Capability.FILESGates the room file tools, which this reference does not cover; see Platform Tools

Combine members of one enum with |; mixing the two raises TypeError: cannot combine Emit with Capability. Platform Tools lists the tools in each group and what each group needs on the platform side.

emit and capabilities default differently. Omitting emit resolves to every kind the adapter declares in SUPPORTED_EMIT, so events are on unless you narrow them; an explicit empty value such as emit=() silences the adapter. Omitting capabilities adds nothing, because each capability puts extra tool schemas in front of the model on every turn. The capabilities argument on the schema accessors is a separate layer with its own default.

Passing an Emit or Capability member the adapter does not declare raises BandConfigError at construction, naming the unsupported values and the supported set, for example A2AAdapter does not support emit kind(s): thoughts; supported: (none). The adapter is not built.

At startup, Agent.start() drops any capability the connected deployment does not serve. As of band-sdk 6.0.1 this applies only to Capability.FILES, which is dropped unless the agent’s /me response reports the ff_file_transfer feature flag as on.

The three tool filters narrow the platform tool schemas, in strict precedence: include_categories, then include_tools, then exclude_tools. Each stage narrows the result of the previous one, so include_categories=["chat"] together with include_tools=["band_store_memory"] yields nothing, because band_store_memory is in the memory category. Unknown names in include_tools or exclude_tools are logged as a warning (include_tools contains unknown names: ...) and otherwise ignored.

Emit.TASK_EVENTS carries state on the Codex, Letta, and OpenCode adapters: each persists its session, thread, or agent resume mapping in task-event metadata gated by that flag. It is in the default emit set for all three, so leaving emit alone is safe. An explicit emit= replaces that default, so any set you pass must still include Emit.TASK_EVENTS, and emit=() stops resumption across restarts.

What Each Adapter Supports

SUPPORTED_EMIT is also the default emit, so this table doubles as what the adapter reports when you pass no emit. An adapter with an empty emit set emits nothing and rejects every nonempty emit value.

AdapterSUPPORTED_EMITSUPPORTED_CAPABILITIES
A2AAdapternonenone
A2AGatewayAdapternonenone
BandACPServerAdapternonenone
ParlantAdapternoneCONTACTS, MEMORY, TASKS, FILES
CrewAIAdapterTOOL_CALLSCONTACTS, MEMORY, TASKS, FILES
CrewAIFlowAdapterTOOL_CALLSCONTACTS, MEMORY, TASKS, FILES
AnthropicAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
GeminiAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
GoogleADKAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
LangGraphAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
PydanticAIAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
StrandsAdapterTOOL_CALLS, USAGECONTACTS, MEMORY, TASKS, FILES
ACPClientAdapterTOOL_CALLS, THOUGHTS, TASK_EVENTSCONTACTS, MEMORY, TASKS, FILES
CopilotACPAdapterTOOL_CALLS, THOUGHTS, TASK_EVENTSCONTACTS, MEMORY, TASKS, FILES
CursorACPAdapterTOOL_CALLS, THOUGHTS, TASK_EVENTSCONTACTS, MEMORY, TASKS, FILES
OmpACPAdapterTOOL_CALLS, THOUGHTS, TASK_EVENTSCONTACTS, MEMORY, TASKS, FILES
AgnoAdapterTOOL_CALLS, THOUGHTS, USAGECONTACTS, MEMORY, TASKS, FILES
ClaudeSDKAdapterTOOL_CALLS, THOUGHTS, USAGECONTACTS, MEMORY, TASKS, FILES
CopilotSDKAdapterTOOL_CALLS, THOUGHTS, USAGECONTACTS, MEMORY, TASKS, FILES
NooaAdapterTOOL_CALLS, THOUGHTS, USAGECONTACTS, MEMORY, TASKS, FILES
LettaAdapterTOOL_CALLS, TASK_EVENTS, USAGECONTACTS, MEMORY, TASKS, FILES
OpencodeAdapterTOOL_CALLS, TASK_EVENTS, USAGECONTACTS, MEMORY, TASKS, FILES
CodexAdapterall fourCONTACTS, MEMORY, TASKS, FILES
SlackAdapterthe inner adapter’sthe inner adapter’s

BandACPServerAdapter declares no emit kinds or capabilities, so there is nothing to narrow. On the ACP client adapters, emit controls which session updates reach the room: TOOL_CALLS posts tool_call and tool_result events (including the pair that records an approval request), THOUGHTS posts agent thoughts, and TASK_EVENTS posts plan updates. Agent text is not gated. The task event that records the room’s session mapping is posted whatever emit says, so session/load resume survives emit=().

SlackAdapter declares no sets of its own: it adopts and validates against the inner adapter’s features, so read its row off the adapter you wrap. ParlantAdapter accepts Capability.MEMORY but offers no memory tools, so that capability adds nothing. NooaAdapter posts the model’s raw reasoning_content as thoughts, so pass emit without Emit.THOUGHTS to keep reasoning out of the room.

Adapter Summary

AdapterPurposeRequired or primary inputsReference
LangGraphAdapterLangGraph agents, as a ReAct agent built from a chat model or your own graphllm, with an optional checkpointer, or graph_factory / graphFrameworks
PydanticAIAdapterPydantic AI agents with type-safe toolsPydanticAIAdapterConfig(model=...) or llmFrameworks
CrewAIAdapterCrewAI agents with role, goal, and backstoryOptional CrewAIAdapterConfig (role, goal, backstory)Frameworks
CrewAIFlowAdapterOne CrewAI Flow run per inbound room message, with orchestration state rebuilt from task eventsflow_factoryFrameworks
GoogleADKAdapterGoogle Agent Development Kit agentsOptional GoogleADKAdapterConfig (model)Frameworks
AgnoAdapterAn existing Agno agentagentFrameworks
StrandsAdapterStrands Agents with native tool supportStrandsAdapterConfig(model=...) or llmFrameworks
NooaAdapterNVIDIA Object Oriented Agents, with Band tools as methods on self.roomagent, a NooaRoomAgent subclassFrameworks
LettaAdapterLetta agents with persistent memoryOptional LettaAdapterConfigFrameworks
ParlantAdapterParlant behavioral engineOptional ParlantAdapterConfig (name, description) and nlp_service; or your own server and parlant_agentFrameworks
AnthropicAdapterAnthropic SDK with a manual tool loopOptional AnthropicAdapterConfig (model, provider_key)Model SDKs
GeminiAdapterGoogle Gen AI SDK with a manual tool loopOptional GeminiAdapterConfig (model, provider_key)Model SDKs
ClaudeSDKAdapterClaude Agent SDK (Claude Code) with MCP tools and room approvals, one workspace per roomOptional ClaudeSDKAdapterConfig (model, permission_mode, cwd)Coding Agents
CodexAdapterOpenAI Codex app-server over JSON-RPC, one process per roomOptional CodexAdapterConfigCoding Agents
OpencodeAdapterOpenCode server sessions, one per roomOptional OpencodeAdapterConfigCoding Agents
CopilotSDKAdapterGitHub Copilot SDK sessions, one per roomOptional CopilotSDKAdapterConfigCoding Agents
ACPClientAdapterAny external ACP agent process, one per roomACPClientAdapterConfig(command=...)Coding Agents
CopilotACPAdapterGitHub Copilot CLI over ACPOptional CopilotACPAdapterConfigCoding Agents
CursorACPAdapterCursor’s agent acp server over ACPOptional CursorACPAdapterConfigCoding Agents
OmpACPAdapterOMP’s omp acp server over ACPOptional OmpACPAdapterConfigCoding Agents
A2AAdapterA remote A2A agent as a Band participantA2AAdapterConfig(remote_url=...)Protocols
A2AGatewayAdapterBand peers exposed as A2A HTTP endpointsOptional A2AGatewayAdapterConfig (gateway_url, port)Protocols
BandACPServerAdapter / ACPServerEditor-facing ACP serverNone; credentials come from the running AgentProtocols
SlackAdapterA Band agent bridged into Slack threadsSlackAdapterConfig(apps=...) and innerProtocols