Appearance
Architecture
For AI agents: a documentation index is available at the root level at /llms.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
What You’ll Learn
This chapter covers the foundational concepts you need to build effective voice AI agents:
- Architecture - How AgentBase and its mixins work together
- SWML - The markup language that controls call flows
- SWAIG - The gateway that lets AI call your functions
- Lifecycle - How requests flow through the system
- 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
| Term | Definition |
|---|---|
| AgentBase | The base class all agents inherit from |
| SWML | SignalWire Markup Language - JSON format for call instructions |
| SWAIG | SignalWire AI Gateway - System for AI to call your functions |
| Mixin | A class providing specific functionality to AgentBase |
| POM | Prompt Object Model - Structured prompt building |
| DataMap | Declarative REST API integration |
Chapter Contents
| Section | Description |
|---|---|
| Architecture | AgentBase class and mixin composition |
| SWML | Understanding SWML document structure |
| SWAIG | How AI calls your functions |
| Lifecycle | Request/response flow |
| Security | Authentication 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.
| Language | Auth Configuration |
|---|---|
| Python | AgentBase(name="my-agent"), credentials from env or auto-generated |
| TypeScript | new 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.
# Automatically registers these routes:
<Badge type="tip" text="Fresh" />
# GET / -> Returns SWML document
# POST / -> Returns SWML document
# POST /swaig -> Handles SWAIG function calls
# POST /post_prompt -> Receives call summaries
# 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.
# SWMLService provides:
# - Schema validation against SWML spec
# - Verb handler registry
# - Document rendering pipelineKey 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).
| Language | Prompt Section |
|---|---|
| Python | agent.prompt_add_section("Role", "You are helpful.", bullets=[...]) |
| TypeScript | agent.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.
| Language | Tool Definition |
|---|---|
| Python | agent.define_tool(name="get_balance", description="...", parameters={...}, handler=fn) |
| TypeScript | agent.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.
| Language | Skill Loading |
|---|---|
| Python | agent.add_skill("datetime") |
| TypeScript | await 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.
| Language | Configuration |
|---|---|
| Python | agent.add_language("English", "en-US", "rime.spore") |
| TypeScript | agent.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.
# AWS Lambda
handler = agent.serverless_handler
# Google Cloud Functions
def my_function(request):
return agent.cloud_function_handler(request)
# Azure Functions
def main(req):
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.
# State is passed via global_data in SWML
# and preserved across function callsKey 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
/mcpendpoint - 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:
Python
TypeScript
from signalwire import AgentBase, FunctionResult
class CustomerServiceAgent(AgentBase):
def __init__(self):
super().__init__(name="customer-service")
self.add_language("English", "en-US", "rime.spore")
self.set_params({"end_of_speech_timeout": 500})
self.prompt_add_section("Role", "You are a helpful agent.")
self.define_tool(
name="lookup_order",
description="Look up an order by ID",
parameters={"order_id": {"type": "string", "description": "Order ID"}},
handler=self.lookup_order
)
self.add_skill("datetime")
def lookup_order(self, args, raw_data):
order_id = args.get("order_id")
return FunctionResult(f"Order {order_id}: Shipped, arrives tomorrow")
if __name__ == "__main__":
agent = CustomerServiceAgent()
agent.run()Benefits of This Architecture
| Benefit | Description |
|---|---|
| Separation of Concerns | Each mixin handles one domain |
| Easy to Understand | Look at one mixin for one feature |
| Extensible | Override specific mixin methods |
| Testable | Test mixins independently |
| Type-Safe | Full type hints throughout |
Next Steps
Now that you understand how AgentBase is structured, let’s look at the SWML documents it generates.
SignalWire Agents SDK Architecture.
AgentBase mixin composition.
