Adapter Features
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
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.
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:
Emit and Capability members:
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.
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.