SignalWire's developer platform is built around two complementary layers that provide flexibility for different use cases and developer preferences:
Pre-built, configurable resources that can be combined to create custom communication solutions: - Rooms: Audio/video conferencing spaces - Scripts: SWML and cXML workflow definitions - Subscribers: Authenticated user accounts for call routing and permissions - Gateways: Connections to remote networks (FreeSWITCH servers, SIP trunks) - Call Flows: Low-code visual voice menus - AI Agents: Higher-level interface to AI capabilities
Direct API access for building custom applications and integrations with full control over communication workflows.
SignalWire Markup Language provides declarative workflow definition: - Purpose: Ties pre-composed resources together - Capabilities: Call flows, voice menus, AI agents, complex routing - Format: JSON/YAML documents - Integration: Real-time event handling and dynamic updates
Comprehensive API for building conversational AI systems: - Function: Full control over AI digital employees - Features: Multi-role agents, context switching, tool integration - Integration: SWAIG functions for external system connectivity - Customization: Brand-specific behavior and personality
Retrieval-Augmented Generation (RAG) specifically designed for AI agents: - Purpose: Knowledge integration for conversational AI - Capabilities: Document ingestion, semantic search, real-time retrieval - Integration: Native SWAIG function connectivity - Formats: Support for multiple document types and formats
Complete voice communication capabilities: - Features: Voice-driven applications, instant SIP connections - Integration: SWML and cXML for advanced call control - Capabilities: Call queues, auto attendants, AI agents, conferencing - Protocols: PSTN, SIP, WebRTC support
Text communication integration: - Functions: Send and receive text messages - Integration: Application logic connectivity - Features: Two-way messaging, automation, workflow triggers - Channels: SMS, MMS, and modern messaging platforms
Enterprise telephony integration: - Scope: Subset of programmable voice focused on SIP - Features: Registrations, trunks to remote sites - Note: Not to be confused with SIP trunking services - Use Cases: Enterprise PBX integration, remote site connectivity
On-demand video communication: - Purpose: Building video-enabled products and services - Features: Dynamic conference creation, participant management - Integration: APIs for custom video applications - Scalability: From one-on-one to large-scale conferences
Ready-to-use video conferencing widgets: - Implementation: UI widgets for website integration - Features: Embed video conferences directly in web applications - Customization: Theming and branding capabilities - Use Cases: Customer support, consultation, collaboration
Security and identity verification: - Features: Challenge/response authentication logic - Integration: User authentication workflows - Methods: SMS, voice, email verification - Security: Enterprise-grade authentication protocols
Legacy document transmission automation: - Capabilities: Send and receive faxes via APIs - Integration: Business logic automation - Protocols: PSTN and SIP-based fax transmission - Use Cases: Healthcare, legal, compliance-required industries
Python framework for building AI voice agents with minimal boilerplate: - Philosophy: Self-contained agents that are both web apps and AI personas - Architecture: Built on AgentBase class with modular skills system - Deployment: Servers, serverless functions, or CGI scripts
The latest version of the SDK introduces three groundbreaking capabilities:
Add complex capabilities to your agents with simple one-liner calls:
agent.add_skill("web_search")
agent.add_skill("datetime")
agent.add_skill("math")
agent.add_skill("native_vector_search", {"index_file": "knowledge.swsearch"})
No more manual function implementation for common tasks. Skills include:
Create API integrations that run on SignalWire's servers without building webhook endpoints:
from signalwire_agents.core.data_map import DataMap
from signalwire_agents.core.function_result import SwaigFunctionResult
weather_tool = (DataMap('get_weather')
.parameter('location', 'string', 'City name', required=True)
.webhook('GET', 'https://api.weather.com/v1/current?key=API_KEY&q=${args.location}')
.output(SwaigFunctionResult('Weather: ${response.current.temp_f}°F'))
)
${args.field}
, ${response.field}
, ${env.VAR}
Enable agents to search through document collections offline:
# Build searchable index from documents
sw-search docs/ --output knowledge.swsearch
Pre-built capabilities that can be added with single-line calls with configurable parameters:
# Global web search configuration
default_web_config = {
"max_results": 5,
"safe_search": "strict",
"timeout": 10
}
# Specific instance with overrides
agent.add_skill("web_search", {
**default_web_config,
"domain_filter": "documentation.signalwire.com",
"max_results": 3
})
Skills support: - Hierarchical configuration: Global settings with instance-specific overrides - Multiple instances: Same skill with different configurations - Dynamic discovery: Automatic function schema generation for AI - Managed execution: Skills execute within secure, managed contexts
Tools that AI can call during conversations: - Definition: Use AgentBase tool decorator - Parameters: Specify name, description, and argument types - Returns: SwaigFunctionResult objects with response data - Capabilities: External API calls, database operations, business logic
Direct REST API integration without custom webhooks: - Execution: Runs on SignalWire servers for simplified deployment - Features: GET/POST requests, authentication, response processing - Patterns: Expression-based tools for pattern matching - Variables: Dollar sign syntax for dynamic data expansion
Optional persistent data across conversations: - Design: Stateless-first for serverless compatibility - Features: JSON-serializable state data when needed - Methods: get_state() and set_state() for data persistence - Use Cases: User preferences, conversation history, application data
The SDK is built on a sophisticated three-layer architecture:
SWMLService Layer: Core web service infrastructure handling HTTP requests, SWML document creation, and schema validation.
AgentBase Layer: AI-specific functionality including prompt management, SWAIG function handling, and state management.
Custom Agent Layer: Business-specific implementations with personality, capabilities, and specialized behaviors.
Structured approach to prompt construction:
# Traditional approach
agent.set_prompt_text("You are a helpful assistant...")
# POM approach (advanced)
from signalwire_agents.core.prompt import PromptSection
agent.prompt.add_section(PromptSection.PERSONALITY,
"You are a professional customer service representative")
agent.prompt.add_section(PromptSection.GOAL,
"Help customers resolve their issues efficiently")
agent.prompt.add_section(PromptSection.INSTRUCTIONS,
"Always ask clarifying questions before taking action")
Sophisticated hybrid search implementation:
Index Structure:
.swsearch file format:
├── Metadata Layer (document count, statistics, version info)
├── Vector Layer (sentence, paragraph, document embeddings)
├── Keyword Layer (inverted index, n-grams, stemmed words)
└── Document Store (original content, processed segments, metadata)
Query Processing Pipeline: 1. Query Analysis: Parse intent, extract keywords and entities 2. Vector Search: Generate embeddings and perform similarity search 3. Keyword Search: Execute full-text search for exact matches 4. Hybrid Ranking: Combine scores using configurable algorithms 5. Result Assembly: Format with highlights and source attribution
Route SIP calls to agents based on usernames: - Mapping: Automatic SIP username to agent routing - Configuration: Simple setup for enterprise integration - Compatibility: Works with existing SIP infrastructure
Handle multiple agents and complex routing:
# Multi-agent server
from signalwire_agents import Agent
class CustomerServiceAgent(Agent):
def __init__(self):
super().__init__(name="CustomerService", route="/customer")
class TechnicalSupportAgent(Agent):
def __init__(self):
super().__init__(name="TechnicalSupport", route="/technical")
# Single server hosting multiple agents
if __name__ == "__main__":
agents = [CustomerServiceAgent(), TechnicalSupportAgent()]
# Centralized routing and management
Enterprise-grade security capabilities: - Function-Specific Tokens: Security tokens for specific functions - Session Management: Built-in user session handling - Basic Authentication: Username/password protection - Custom Authentication: Integration with existing auth systems - Input Validation: Automatic sanitization and validation - Access Control: Role-based permissions and restrictions
Stateless-First Design: Optimized for horizontal scaling
# Stateless operation (preferred)
@Agent.tool(name="process_order")
def process_order(self, args, raw_data):
order_id = args.get("order_id")
# Process without storing state
return SwaigFunctionResult(f"Order {order_id} processed")
# Stateful operation (when needed)
@Agent.tool(name="start_workflow")
def start_workflow(self, args, raw_data):
workflow_data = {"step": 1, "user_id": args.get("user_id")}
result = SwaigFunctionResult("Workflow started")
# Store state for AI access
result.add_action("set_global_data", {"workflow": workflow_data})
return result
Multi-tenant and per-request customization:
class ConfigurableAgent(Agent):
def config_callback(self, request_data):
# Customize agent behavior per request
tenant_id = request_data.get("tenant_id")
if tenant_id == "enterprise":
return {
"ai_model": "gpt-4",
"max_tokens": 2000,
"skills": ["web_search", "crm_integration"]
}
else:
return {
"ai_model": "gpt-3.5-turbo",
"max_tokens": 1000,
"skills": ["web_search"]
}
Ready-to-use agent implementations: - InfoGathererAgent: Structured data collection workflows - FAQBotAgent: Knowledge base question answering - ConciergeAgent: Customer routing and assistance - SurveyAgent: Automated survey and feedback collection
Each prefab includes optimized prompts, pre-configured skills, and domain-specific workflows that can be customized for specific use cases.
from signalwire_agents import Agent
from signalwire_agents.core.data_map import DataMap
from signalwire_agents.core.function_result import SwaigFunctionResult
class MyAdvancedAgent(Agent):
def __init__(self):
super().__init__(
name="MyAdvancedAgent",
route="/agent",
port=8080
)
# Add skills with simple one-liners
self.add_skill("web_search", {"num_results": 3})
self.add_skill("datetime")
self.add_skill("math")
self.add_skill("native_vector_search", {
"index_file": "knowledge.swsearch"
})
# Add DataMap tools for API integration
self.add_datamap_tool(self.create_weather_tool())
# Set structured prompt
self.set_prompt_text("""
You are an intelligent assistant with access to web search,
mathematical calculations, document search, and weather data.
Help users with their questions using these capabilities.
""")
def create_weather_tool(self):
return (DataMap('get_weather')
.parameter('location', 'string', 'City name', required=True)
.webhook('GET', 'https://api.weather.com/v1/current?key=${env.WEATHER_API_KEY}&q=${args.location}')
.header('User-Agent', 'SignalWire Agent')
.transform('weather_data', {
'temperature': '${response.current.temp_f}',
'condition': '${response.current.condition.text}',
'humidity': '${response.current.humidity}'
})
.output(SwaigFunctionResult("""
Weather in ${args.location}:
Temperature: ${transformed.temperature}°F
Condition: ${transformed.condition}
Humidity: ${transformed.humidity}%
"""))
.on_error(404, SwaigFunctionResult("Weather data not found for that location."))
.on_error('default', SwaigFunctionResult("Unable to retrieve weather information."))
)
@Agent.tool(name="custom_business_logic", description="Custom business logic")
def my_custom_tool(self, args, raw_data):
# Custom tool implementation with full SWAIG integration
result_data = {"processed": True, "value": args.get("input_value", 0) * 2}
return SwaigFunctionResult(
success=True,
data=result_data,
response="Processed your request successfully."
)
# Start the agent
if __name__ == "__main__":
agent = MyAdvancedAgent()
agent.run()
# Add multiple skills with custom configurations
agent.add_skill("web_search", {
"api_key": "google_api_key",
"search_engine_id": "engine_id",
"num_results": 5
})
agent.add_skill("datasphere", {
"auth_token": "datasphere_token",
"max_results": 3
})
from signalwire_agent import DataMap
# Simple API integration
weather_tool = DataMap.api_tool(
name="get_weather",
description="Get current weather",
url="https://api.weather.com/v1/current?q=${location}",
headers={"Authorization": "Bearer ${api_token}"},
output_template="The weather in ${location} is ${response.current.condition}"
)
External server integration for complex logic: - HTTP POST: Receive function calls from SWAIG - Processing: Custom business logic on external servers - Response: Return SWML instructions or data - Use Cases: Complex workflows, proprietary systems, database integration
Local processing without external servers: - Configuration: JSON templates define processing logic - Execution: Runs within SignalWire infrastructure - Performance: Lower latency than webhook calls - Use Cases: API integration, data transformation, pattern matching
REST API connectivity for real-time data: - Protocols: HTTP/HTTPS with various authentication methods - Data Formats: JSON, XML, form data support - Error Handling: Graceful degradation for failed calls - Caching: Optimize performance with data caching
The SignalWire Agents SDK supports multiple deployment models with automatic environment detection:
Standard web server deployment for production use:
# Production deployment
class ProductionAgent(Agent):
def __init__(self):
super().__init__(
name="ProductionAgent",
route="/agent",
host="0.0.0.0", # Accept connections from all interfaces
port=8080
)
if __name__ == "__main__":
agent = ProductionAgent()
agent.run() # Starts FastAPI server
Integration with Apache, Nginx, or other web servers:
# CGI deployment (auto-detected)
class CGIAgent(Agent):
def __init__(self):
super().__init__(name="CGIAgent")
# No host/port needed - CGI mode auto-detected
# Environment auto-detection handles CGI setup
agent = CGIAgent()
Deploy to AWS Lambda, Google Cloud Functions, or Azure Functions:
# AWS Lambda deployment
import json
from signalwire_agents import Agent
class LambdaAgent(Agent):
def __init__(self):
super().__init__(name="LambdaAgent")
agent = LambdaAgent()
def lambda_handler(event, context):
# Convert Lambda event to agent request
response = agent.handle_request(event)
return {
'statusCode': 200,
'body': json.dumps(response)
}
Flexible configuration for different deployment environments:
import os
class EnvironmentAwareAgent(Agent):
def __init__(self):
# Environment-specific configuration
config = {
"development": {
"host": "localhost",
"port": 8080,
"debug": True
},
"staging": {
"host": "0.0.0.0",
"port": 8080,
"debug": False
},
"production": {
"host": "0.0.0.0",
"port": int(os.getenv("PORT", 8080)),
"debug": False
}
}
env = os.getenv("ENVIRONMENT", "development")
env_config = config[env]
super().__init__(
name="EnvironmentAgent",
**env_config
)