Client capabilities

View as MarkdownOpen in Claude

A browser client such as the SignalWire address widget declares what it can render in the user variables it sends at dial time. The signalwire.core.capabilities module reads those declarations so an agent can decide what to offer: whether to push content to a screen, whether to advertise a text-handoff tool.

{
"vars": {
"userVariables": {
"capabilities": {
"display_content": true,
"transcript": true,
"chat_handoff": false
}
}
}
}
Declarations, not grants

A capability says what the client can render. It is never permission to do anything privileged, because a caller controls its own user variables. Use these values as hints for what to offer.

Absence means no. Every function resolves errors and missing data to “not declared”, because offering a caller something they can’t reach is worse than never mentioning it: a phone caller has no screen. There is no fixed list of capability names; a client can declare a name this SDK has never seen and your application can act on it.

from signalwire.core.capabilities import declared_capabilities, has_capability, user_variables

Functions

Example

Offer a screen-only tool to callers who can render it:

from signalwire import AgentBase
from signalwire.core.capabilities import has_capability
agent = AgentBase(name="dispatch", route="/dispatch")
agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.")
def configure(query_params, body_params, headers, ephemeral_agent):
if has_capability(body_params, "display_content"):
ephemeral_agent.prompt_add_section(
"Screen",
body="The caller can see a screen. Offer to show the fare breakdown there.",
)
agent.add_per_call_config(configure)
agent.serve()

For moving a conversation between chat and a call, see HandoffRouter.