T
Telephony SOPKnowledge Base
Search
← All topics

SWML Context Switch — Multi-Persona AI in One Call

runnable

The `context_switch` verb (and FunctionResult.switch_context) lets a live AI agent change persona mid-call. Use cases: triage agent → specialist agent, language change, escalation. Covers consolidate semantics and prompt overrides.

signalwireswmlcontext-switchmulti-personaai-routing
Agent trigger phrases: context switch SWML · switch AI persona mid-call · consolidate context · triage to specialist agent · FunctionResult.switch_context · swml_change_context

SWML context_switch — Mid-Call Persona Change

context_switch swaps the active AI persona without dropping the call. Common pattern: a generic triage agent answers, identifies what the caller needs, and hands off to a specialist persona (sales, support, billing) that has its own prompt and SWAIG tools — all in the same call session.

The two ways to switch contexts

1. From SWML (declarative)

Use when contexts are predefined and selection happens via SWAIG or cond.

version: 1.0.0
sections:
  main:
    - answer: {}
    - ai:
        prompt: { text: "You are a triage agent. Identify if the caller needs sales, support, or billing." }
        SWAIG:
          defaults: { web_hook_url: "https://your.api/swaig" }
          functions:
            - function: route_to_sales
              description: Caller needs sales.
            - function: route_to_support
              description: Caller needs technical support.
            - function: route_to_billing
              description: Caller has a billing question.

The SWAIG handler returns a FunctionResult that switches the context.

2. From a SWAIG handler (programmatic)

In the handler:

from signalwire import FunctionResult

def route_to_sales(args, raw_data=None):
    return FunctionResult("Connecting you to a sales specialist.").switch_context(
        "sales",
        system_prompt="""You are a senior sales rep for Acme Corp.
        Focus on pricing, demos, and closing.
        Use the lookup_pricing and book_demo tools as needed.""",
        consolidate=True,
    )

def route_to_support(args, raw_data=None):
    return FunctionResult("Connecting you to support.").switch_context(
        "support",
        system_prompt="You are a tier-2 support engineer. Triage and create a ticket.",
        consolidate=True,
    )

switch_context parameters

| Parameter | Notes | |---|---| | context_name | Required. Name of the context to enter. | | system_prompt | Override the new context's prompt at runtime. Optional. | | consolidate | If true, replaces the entire conversation history with a one-paragraph summary before the new context starts. If false, the new persona inherits the full prior conversation. Defaults to false. | | user_prompt | Optional opening turn the AI will respond to inside the new context. |

consolidate=True is the default in any handoff scenario — you don't want the specialist agent re-reading every word the caller said to the triage agent.

ContextBuilder (Python SDK) — defining the contexts up front

Use Context Builder to define multiple contexts inside one agent.

contexts = self.define_contexts()

main = contexts.add_context("default")
main.add_step("menu") \
    .set_text("Ask whether the caller needs sales, support, or billing.") \
    .set_functions("none") \
    .set_valid_contexts(["sales", "support", "billing"])

sales = contexts.add_context("sales")
sales.set_system_prompt("You are a friendly sales representative for Acme Corp.")
sales.add_step("qualify") \
    .set_text("Understand what product the caller is interested in.") \
    .set_functions(["check_inventory", "get_pricing"]) \
    .set_valid_steps(["close"])
sales.add_step("close") \
    .set_text("Close the sale or schedule a follow-up.") \
    .set_valid_contexts(["default"])

support = contexts.add_context("support")
support.set_system_prompt("You are a tier-2 support engineer.")
support.add_step("triage").set_text("Get problem details, system info, urgency.")

When the triage agent calls switch_context("sales"), the SDK loads the sales context's system prompt, allowed functions, and entry step.

Mid-call language switch

switch_context is the canonical way to change language mid-call. Define a Spanish context with its own voice, then switch:

spanish = contexts.add_context("spanish")
spanish.set_system_prompt("Eres un agente bilingüe. Responde solo en español.")
# Languages are set at the agent level, but the prompt forces Spanish output.
def switch_to_spanish(args, raw_data=None):
    return FunctionResult("Cambiando al español.").switch_context(
        "spanish",
        consolidate=True,
    )

For TTS voice changes per language, use the agent's languages config — the AI picks the voice based on detected output language.

consolidate — when to set it false

consolidate=False keeps the prior conversation in context. Use cases:

  • "Hold while I check" → backend lookup → resume same persona with new data.
  • Side-quest into a specialist that returns to the original persona.

consolidate=True (recommended for handoffs):

  • Triage → specialist agent that should not see the triage chatter.
  • Compliance reset before billing questions.
  • Persona reset after extracting structured data.

goto vs execute vs switch_context — which one to use

| Verb | Effect | |---|---| | goto | Jump to a different SWML section (no AI context implied). | | execute | Fetch and run a sub-SWML, return when done. The active AI session pauses during execution. | | switch_context (SWAIG return) | Keep the AI session alive, change its persona/tools/prompt. |

If the call has an active ai verb, prefer switch_context — it keeps the speech recognition, hints, and language settings warm.

Anti-patterns

  • Switching contexts without consolidate=True when the new persona shouldn't know the prior chat — leaks context, confuses the specialist agent.
  • Defining 10+ contexts on one agent — split into multiple agents on an AgentServer instead.
  • Switching contexts inside a confirm SWML — confirm scripts run on the callee leg, not the AI session.
  • Forgetting to set_valid_contexts on the source context — the SDK will refuse to transition.

See also