Architecture

View as MarkdownOpen in Claude

What You’ll Learn

This chapter covers the foundational concepts you need to build effective voice AI agents:

  1. Architecture - How AgentBase and its mixins work together
  2. SWML - The markup language that controls call flows
  3. SWAIG - The gateway that lets AI call your functions
  4. Lifecycle - How requests flow through the system
  5. Security - Authentication and token-based function security

Prerequisites

Before diving into these concepts, you should have:

  • Completed the Getting Started chapter
  • A working agent running locally
  • Basic understanding of HTTP request/response patterns

The Big Picture

SignalWire Agents SDK Architecture.
SignalWire Agents SDK Architecture

Key Terminology

TermDefinition
AgentBaseThe base class all agents inherit from
SWMLSignalWire Markup Language - JSON format for call instructions
SWAIGSignalWire AI Gateway - System for AI to call your functions
MixinA class providing specific functionality to AgentBase
POMPrompt Object Model - Structured prompt building
DataMapDeclarative REST API integration

Chapter Contents

SectionDescription
ArchitectureAgentBase class and mixin composition
SWMLUnderstanding SWML document structure
SWAIGHow AI calls your functions
LifecycleRequest/response flow
SecurityAuthentication and token security

Why These Concepts Matter

Understanding these core concepts helps you:

  • Debug effectively - Know where to look when things go wrong
  • Build efficiently - Use the right tool for each task
  • Scale confidently - Understand how the system handles load
  • Extend properly - Add custom functionality the right way

The Mixin Composition Pattern

AgentBase doesn’t inherit from a single monolithic class. Instead, it combines nine specialized mixins plus the SWMLService base class:

AgentBase mixin composition.
AgentBase mixin composition

Each Mixin’s Role

AuthMixin - Authentication & Security

Handles basic HTTP authentication for webhook endpoints.

LanguageAuth Configuration
PythonAgentBase(name="my-agent") — credentials from env or auto-generated
TypeScriptnew AgentBase({ name: 'my-agent', basicAuth: ['user', 'pass'] })

Key methods:

  • Validates incoming requests against stored credentials
  • Generates credentials if not provided via environment
  • Protects SWAIG function endpoints

WebMixin - HTTP Server & Routing

Manages the FastAPI application and HTTP endpoints.

1# Automatically registers these routes:
2# GET / -> Returns SWML document
3# POST / -> Returns SWML document
4# POST /swaig -> Handles SWAIG function calls
5# POST /post_prompt -> Receives call summaries
6# GET /debug -> Debug information (dev only)

Key features:

  • Runs uvicorn server via agent.run()
  • Handles proxy detection (ngrok, load balancers)
  • Manages request/response lifecycle

SWMLService - SWML Document Generation

The foundation for building SWML documents.

1# SWMLService provides:
2# - Schema validation against SWML spec
3# - Verb handler registry
4# - Document rendering pipeline

Key responsibilities:

  • Validates SWML structure against JSON schema
  • Registers verb handlers (answer, ai, connect, etc.)
  • Renders final SWML JSON

PromptMixin - Prompt Management

Manages AI system prompts using POM (Prompt Object Model).

LanguagePrompt Section
Pythonagent.prompt_add_section("Role", "You are helpful.", bullets=[...])
TypeScriptagent.promptAddSection('Role', { body: 'You are helpful.', bullets: [...] })

Key features:

  • Structured prompt building with sections
  • Support for bullets, subsections
  • Post-prompt for call summaries

ToolMixin - SWAIG Function Management

Handles registration and execution of SWAIG functions.

LanguageTool Definition
Pythonagent.define_tool(name="get_balance", description="...", parameters={...}, handler=fn)
TypeScriptagent.defineTool({ name: 'get_balance', description: '...', parameters: {...}, handler: fn })

Key features:

  • Multiple registration methods (define_tool, decorators, DataMap)
  • Parameter validation
  • Security token generation

SkillMixin - Skill Plugin Management

Loads and manages reusable skill plugins.

LanguageSkill Loading
Pythonagent.add_skill("datetime")
TypeScriptawait agent.addSkill(new DateTimeSkill())

Key features:

  • Auto-discovery of skill modules
  • Dependency checking
  • Configuration validation

AIConfigMixin - AI Behavior Configuration

Configures the AI’s voice, language, and behavior parameters.

LanguageConfiguration
Pythonagent.add_language("English", "en-US", "rime.spore")
TypeScriptagent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' })

Key features:

  • Voice and language settings
  • Speech recognition hints
  • AI behavior parameters

ServerlessMixin - Deployment Adapters

Provides handlers for serverless deployments.

1# AWS Lambda
2handler = agent.serverless_handler
3
4# Google Cloud Functions
5def my_function(request):
6 return agent.cloud_function_handler(request)
7
8# Azure Functions
9def main(req):
10 return agent.azure_function_handler(req)

Key features:

  • Environment auto-detection
  • Request/response adaptation
  • URL generation for each platform

StateMixin - State Management

Manages session and call state.

1# State is passed via global_data in SWML
2# and preserved across function calls

Key features:

  • Session tracking
  • State persistence patterns
  • Call context management

MCPServerMixin - MCP Protocol Support

Exposes agent tools as an MCP (Model Context Protocol) server endpoint.

Key features:

  • MCP JSON-RPC 2.0 protocol support
  • Automatic tool exposure at /mcp endpoint
  • Converts SWAIG functions to MCP tool format

Key Internal Components

Beyond the mixins, AgentBase uses several internal managers:

ToolRegistry

  • Stores SWAIG functions
  • Handles function lookup
  • Generates webhook URLs

PromptManager

  • Manages prompt sections
  • Builds POM structure
  • Handles post-prompts

SessionManager

  • Token generation
  • Token validation
  • Security enforcement

SkillManager

  • Skill discovery
  • Skill loading
  • Configuration validation

SchemaUtils

  • SWML schema loading
  • Document validation
  • Schema-driven help

VerbHandlerRegistry

  • Verb registration
  • Handler dispatch
  • Custom verb support

Creating Your Own Agent

When you create an agent, you get all functionality automatically:

1from signalwire import AgentBase, FunctionResult
2
3class CustomerServiceAgent(AgentBase):
4 def __init__(self):
5 super().__init__(name="customer-service")
6 self.add_language("English", "en-US", "rime.spore")
7 self.set_params({"end_of_speech_timeout": 500})
8 self.prompt_add_section("Role", "You are a helpful agent.")
9 self.define_tool(
10 name="lookup_order",
11 description="Look up an order by ID",
12 parameters={"order_id": {"type": "string", "description": "Order ID"}},
13 handler=self.lookup_order
14 )
15 self.add_skill("datetime")
16
17 def lookup_order(self, args, raw_data):
18 order_id = args.get("order_id")
19 return FunctionResult(f"Order {order_id}: Shipped, arrives tomorrow")
20
21if __name__ == "__main__":
22 agent = CustomerServiceAgent()
23 agent.run()

Benefits of This Architecture

BenefitDescription
Separation of ConcernsEach mixin handles one domain
Easy to UnderstandLook at one mixin for one feature
ExtensibleOverride specific mixin methods
TestableTest mixins independently
Type-SafeFull type hints throughout

Next Steps

Now that you understand how AgentBase is structured, let’s look at the SWML documents it generates.