By Feature
Examples
Practical examples organized by feature and complexity to help you build voice AI agents.
How to Use This Chapter
This chapter provides examples organized two ways:
- By Feature - Find examples demonstrating specific SDK features
- By Complexity - Start simple and progressively add features
Example Categories
By Feature
- Basic agent setup
- SWAIG functions
- DataMap integration
- Skills usage
- Call transfers
- Context workflows
- Multi-agent servers
By Complexity
- Beginner - Simple agents with basic prompts
- Intermediate - Functions, skills, and state management
- Advanced - Multi-context workflows, multi-agent systems
Quick Start Examples
Minimal Agent
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="hello", route="/hello") 4 agent.prompt_add_section("Role", "You are a friendly assistant.") 5 agent.add_language("English", "en-US", "rime.spore") 6 7 if __name__ == "__main__": 8 agent.run()
Agent with Function
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="helper", route="/helper") 5 agent.prompt_add_section("Role", "You help users look up information.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Look up information by ID") 9 def lookup(id: str) -> SwaigFunctionResult: 10 # Your lookup logic here 11 return SwaigFunctionResult(f"Found record {id}") 12 13 if __name__ == "__main__": 14 agent.run()
Agent with Transfer
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="receptionist", route="/reception") 5 agent.prompt_add_section("Role", "You are a receptionist. Help callers reach the right department.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Transfer caller to support") 9 def transfer_to_support() -> SwaigFunctionResult: 10 return ( 11 SwaigFunctionResult("Transferring you to support now.") 12 .connect("+15551234567", final=True) 13 ) 14 15 if __name__ == "__main__": 16 agent.run()
Running Examples
$ # Run directly $ python agent.py $ $ # Test with swaig-test $ swaig-test agent.py --dump-swml $ swaig-test agent.py --list-tools $ swaig-test agent.py --exec lookup --id "12345"
Example Structure
Most examples follow this pattern:
1 # 1. Imports 2 from signalwire_agents import AgentBase 3 from signalwire_agents.core.function_result import SwaigFunctionResult 4 5 # 2. Create Agent 6 agent = AgentBase(name="my-agent", route="/agent") 7 8 # 3. Configure 9 agent.prompt_add_section("Role", "You are a helpful assistant.") 10 agent.add_language("English", "en-US", "rime.spore") 11 12 # 4. Define Functions 13 @agent.tool(description="Look up information by ID") 14 def lookup(id: str) -> SwaigFunctionResult: 15 return SwaigFunctionResult(f"Found record for {id}") 16 17 # 5. Run 18 if __name__ == "__main__": 19 agent.run()
Chapter Contents
| Section | Description |
|---|---|
| By Feature | Examples organized by SDK feature |
| By Complexity | Examples from beginner to advanced |
Basic Agent Setup
Minimal Agent
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="basic", route="/basic") 4 agent.prompt_add_section("Role", "You are a helpful assistant.") 5 agent.add_language("English", "en-US", "rime.spore") 6 7 if __name__ == "__main__": 8 agent.run()
Class-Based Agent
1 from signalwire_agents import AgentBase 2 3 4 class MyAgent(AgentBase): 5 def __init__(self): 6 super().__init__(name="my-agent", route="/my-agent") 7 self.prompt_add_section("Role", "You are a customer service agent.") 8 self.prompt_add_section("Guidelines", "Be helpful and professional.") 9 self.add_language("English", "en-US", "rime.spore") 10 11 12 if __name__ == "__main__": 13 agent = MyAgent() 14 agent.run()
SWAIG Functions
Simple Function
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="functions", route="/functions") 5 agent.prompt_add_section("Role", "You help users with account lookups.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Look up account information") 9 def get_account(account_id: str) -> SwaigFunctionResult: 10 # Simulated lookup 11 return SwaigFunctionResult(f"Account {account_id}: Active, balance $150.00") 12 13 if __name__ == "__main__": 14 agent.run()
Function with Multiple Parameters
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="booking", route="/booking") 5 agent.prompt_add_section("Role", "You help users book appointments.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Book an appointment") 9 def book_appointment( 10 name: str, 11 date: str, 12 time: str = "10:00 AM", 13 service: str = "consultation" 14 ) -> SwaigFunctionResult: 15 return SwaigFunctionResult( 16 f"Booked {service} for {name} on {date} at {time}. " 17 "You will receive a confirmation." 18 ) 19 20 if __name__ == "__main__": 21 agent.run()
Secure Function
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="secure", route="/secure") 5 agent.prompt_add_section("Role", "You handle sensitive account operations.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool( 9 description="Update account password", 10 secure=True, 11 fillers=["Processing your request securely..."] 12 ) 13 def update_password( 14 account_id: str, 15 new_password: str 16 ) -> SwaigFunctionResult: 17 # Password update logic here 18 return SwaigFunctionResult("Password has been updated successfully.") 19 20 if __name__ == "__main__": 21 agent.run()
DataMap Integration
Weather Lookup
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.data_map import DataMap 3 from signalwire_agents.core.function_result import SwaigFunctionResult 4 5 agent = AgentBase(name="weather", route="/weather") 6 agent.prompt_add_section("Role", "You provide weather information.") 7 agent.add_language("English", "en-US", "rime.spore") 8 9 weather_map = ( 10 DataMap("get_weather") 11 .purpose("Get current weather for a city") 12 .parameter("city", "string", "City name", required=True) 13 .webhook("GET", "https://api.weather.com/current?q=${enc:args.city}&key=YOUR_API_KEY") 14 .output(SwaigFunctionResult( 15 "Current weather in ${args.city}: ${response.condition}, ${response.temp} degrees F" 16 )) 17 .fallback_output(SwaigFunctionResult("Weather service unavailable.")) 18 ) 19 20 agent.register_swaig_function(weather_map.to_swaig_function()) 21 22 if __name__ == "__main__": 23 agent.run()
Expression-Based Control
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.data_map import DataMap 3 from signalwire_agents.core.function_result import SwaigFunctionResult 4 5 agent = AgentBase(name="control", route="/control") 6 agent.prompt_add_section("Role", "You control media playback.") 7 agent.add_language("English", "en-US", "rime.spore") 8 9 playback_map = ( 10 DataMap("media_control") 11 .purpose("Control media playback") 12 .parameter("command", "string", "Command: play, pause, stop", required=True) 13 .expression("${args.command}", r"play|start", 14 SwaigFunctionResult("Starting playback.") 15 .play_background_file("https://example.com/music.mp3")) 16 .expression("${args.command}", r"pause|stop", 17 SwaigFunctionResult("Stopping playback.") 18 .stop_background_file()) 19 ) 20 21 agent.register_swaig_function(playback_map.to_swaig_function()) 22 23 if __name__ == "__main__": 24 agent.run()
Call Transfers
Simple Transfer
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="transfer", route="/transfer") 5 agent.prompt_add_section("Role", "You route callers to the right department.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Transfer to sales department") 9 def transfer_sales() -> SwaigFunctionResult: 10 return ( 11 SwaigFunctionResult("Connecting you to our sales team.") 12 .connect("+15551234567", final=True) 13 ) 14 15 @agent.tool(description="Transfer to support department") 16 def transfer_support() -> SwaigFunctionResult: 17 return ( 18 SwaigFunctionResult("Transferring you to technical support.") 19 .connect("+15559876543", final=True) 20 ) 21 22 if __name__ == "__main__": 23 agent.run()
Temporary Transfer
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="consult", route="/consult") 5 agent.prompt_add_section("Role", "You help with consultations.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Connect to specialist for consultation") 9 def consult_specialist() -> SwaigFunctionResult: 10 return ( 11 SwaigFunctionResult("Connecting you to a specialist. I'll be here when you're done.") 12 .connect("+15551234567", final=False) # Returns to agent after 13 ) 14 15 if __name__ == "__main__": 16 agent.run()
Skills Usage
DateTime Skill
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="datetime", route="/datetime") 4 agent.prompt_add_section("Role", "You provide time and date information.") 5 agent.add_language("English", "en-US", "rime.spore") 6 agent.add_skill("datetime") 7 8 if __name__ == "__main__": 9 agent.run()
Search Skill
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="search", route="/search") 4 agent.prompt_add_section("Role", "You search documentation for answers.") 5 agent.add_language("English", "en-US", "rime.spore") 6 agent.add_skill("native_vector_search", { 7 "index_path": "./docs.swsearch", 8 "tool_name": "search_docs", 9 "tool_description": "Search the documentation" 10 }) 11 12 if __name__ == "__main__": 13 agent.run()
Global Data
Setting Initial State
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="state", route="/state") 5 agent.prompt_add_section("Role", "You track user preferences.") 6 agent.add_language("English", "en-US", "rime.spore") 7 agent.set_global_data({ 8 "user_tier": "standard", 9 "preferences": {} 10 }) 11 12 @agent.tool(description="Update user preference") 13 def set_preference(key: str, value: str) -> SwaigFunctionResult: 14 return SwaigFunctionResult(f"Set {key} to {value}").update_global_data({ 15 f"preferences.{key}": value 16 }) 17 18 if __name__ == "__main__": 19 agent.run()
Recording
Enable Call Recording
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase( 5 name="recording", 6 route="/recording", 7 record_call=True, 8 record_format="mp3", 9 record_stereo=True 10 ) 11 agent.prompt_add_section("Role", "You handle recorded conversations.") 12 agent.add_language("English", "en-US", "rime.spore") 13 14 @agent.tool(description="Start call recording") 15 def start_recording() -> SwaigFunctionResult: 16 return ( 17 SwaigFunctionResult("Starting recording now.") 18 .record_call(control_id="main", stereo=True, format="mp3") 19 ) 20 21 @agent.tool(description="Stop call recording") 22 def stop_recording() -> SwaigFunctionResult: 23 return ( 24 SwaigFunctionResult("Recording stopped.") 25 .stop_record_call(control_id="main") 26 ) 27 28 if __name__ == "__main__": 29 agent.run()
SMS Notifications
Send Confirmation SMS
1 from signalwire_agents import AgentBase 2 from signalwire_agents.core.function_result import SwaigFunctionResult 3 4 agent = AgentBase(name="sms", route="/sms") 5 agent.prompt_add_section("Role", "You help with appointments and send confirmations.") 6 agent.add_language("English", "en-US", "rime.spore") 7 8 @agent.tool(description="Send appointment confirmation via SMS") 9 def send_confirmation( 10 phone: str, 11 date: str, 12 time: str 13 ) -> SwaigFunctionResult: 14 return ( 15 SwaigFunctionResult("Sending confirmation to your phone.") 16 .send_sms( 17 to_number=phone, 18 from_number="+15559876543", 19 body=f"Appointment confirmed for {date} at {time}." 20 ) 21 ) 22 23 if __name__ == "__main__": 24 agent.run()
Static Files with AgentServer
Serving Static Files Alongside Agents
1 #!/usr/bin/env python3 2 # static_files_server.py - Serve static files alongside agents 3 # 4 # Static files directory layout: 5 # This script expects a "web/" directory in the same folder: 6 # 7 # code/11_examples/ 8 # ├── static_files_server.py 9 # └── web/ 10 # ├── index.html -> served at / 11 # ├── styles.css -> served at /styles.css 12 # └── app.js -> served at /app.js 13 # 14 # Route priority: 15 # /support/* -> SupportAgent 16 # /sales/* -> SalesAgent 17 # /health -> AgentServer health check 18 # /* -> Static files (fallback) 19 20 from signalwire_agents import AgentBase, AgentServer 21 from pathlib import Path 22 23 HOST = "0.0.0.0" 24 PORT = 3000 25 26 27 class SupportAgent(AgentBase): 28 def __init__(self): 29 super().__init__(name="support", route="/support") 30 self.add_language("English", "en-US", "rime.spore") 31 self.prompt_add_section("Role", "You are a support agent.") 32 33 34 class SalesAgent(AgentBase): 35 def __init__(self): 36 super().__init__(name="sales", route="/sales") 37 self.add_language("English", "en-US", "rime.spore") 38 self.prompt_add_section("Role", "You are a sales agent.") 39 40 41 def create_server(): 42 """Create AgentServer with static file mounting.""" 43 server = AgentServer(host=HOST, port=PORT) 44 server.register(SupportAgent(), "/support") 45 server.register(SalesAgent(), "/sales") 46 47 # Serve static files using SDK's built-in method 48 web_dir = Path(__file__).parent / "web" 49 if web_dir.exists(): 50 server.serve_static_files(str(web_dir)) 51 52 return server 53 54 55 if __name__ == "__main__": 56 server = create_server() 57 server.run()
Hints and Pronunciation
Speech Recognition Hints
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="hints", route="/hints") 4 agent.prompt_add_section("Role", "You help with technical products.") 5 agent.add_language("English", "en-US", "rime.spore") 6 agent.add_hints([ 7 "SignalWire", 8 "SWML", 9 "SWAIG", 10 "API", 11 "SDK" 12 ]) 13 14 if __name__ == "__main__": 15 agent.run()
Pronunciation Rules
1 from signalwire_agents import AgentBase 2 3 agent = AgentBase(name="pronounce", route="/pronounce") 4 agent.prompt_add_section("Role", "You discuss technical topics.") 5 agent.add_language("English", "en-US", "rime.spore") 6 agent.add_pronounce([ 7 {"replace": "API", "with": "A P I"}, 8 {"replace": "SQL", "with": "sequel"}, 9 {"replace": "JSON", "with": "jason"} 10 ]) 11 12 if __name__ == "__main__": 13 agent.run()
Copy-Paste Recipes
Quick templates for common scenarios. Copy, customize the placeholders, and run.
Recipe: Basic IVR Menu
1 #!/usr/bin/env python3 2 # ivr_menu.py - Basic interactive voice menu 3 from signalwire_agents import AgentBase 4 from signalwire_agents.core.function_result import SwaigFunctionResult 5 6 # Configure these 7 SALES_NUMBER = "+15551001001" 8 SUPPORT_NUMBER = "+15551001002" 9 BILLING_NUMBER = "+15551001003" 10 11 agent = AgentBase(name="ivr", route="/ivr") 12 agent.prompt_add_section("Role", """ 13 You are an automated phone system for [COMPANY NAME]. 14 Ask callers what they need help with and route them to the appropriate department. 15 """) 16 agent.prompt_add_section("Options", """ 17 Available departments: 18 - Sales: for product inquiries, pricing, and purchases 19 - Support: for technical help and troubleshooting 20 - Billing: for payments, invoices, and account questions 21 """) 22 agent.add_language("English", "en-US", "rime.spore") 23 24 @agent.tool(description="Transfer caller to sales department") 25 def transfer_sales() -> SwaigFunctionResult: 26 return SwaigFunctionResult("Connecting you to sales.").connect(SALES_NUMBER, final=True) 27 28 @agent.tool(description="Transfer caller to technical support") 29 def transfer_support() -> SwaigFunctionResult: 30 return SwaigFunctionResult("Connecting you to support.").connect(SUPPORT_NUMBER, final=True) 31 32 @agent.tool(description="Transfer caller to billing department") 33 def transfer_billing() -> SwaigFunctionResult: 34 return SwaigFunctionResult("Connecting you to billing.").connect(BILLING_NUMBER, final=True) 35 36 if __name__ == "__main__": 37 agent.run()
Recipe: Appointment Reminder
1 #!/usr/bin/env python3 2 # appointment_reminder.py - Outbound appointment reminder with confirmation 3 from signalwire_agents import AgentBase 4 from signalwire_agents.core.function_result import SwaigFunctionResult 5 6 agent = AgentBase(name="reminder", route="/reminder") 7 agent.prompt_add_section("Role", """ 8 You are calling to remind the customer about their upcoming appointment. 9 State the appointment details and ask if they can confirm their attendance. 10 """) 11 agent.prompt_add_section("Appointment", """ 12 - Date: [APPOINTMENT_DATE] 13 - Time: [APPOINTMENT_TIME] 14 - Location: [APPOINTMENT_LOCATION] 15 - Provider: [PROVIDER_NAME] 16 """) 17 agent.add_language("English", "en-US", "rime.spore") 18 agent.set_global_data({"confirmed": False, "needs_reschedule": False}) 19 20 @agent.tool(description="Mark appointment as confirmed") 21 def confirm_appointment() -> SwaigFunctionResult: 22 return ( 23 SwaigFunctionResult("Thank you for confirming. We'll see you then!") 24 .update_global_data({"confirmed": True}) 25 .hangup() 26 ) 27 28 @agent.tool(description="Mark that customer needs to reschedule") 29 def request_reschedule() -> SwaigFunctionResult: 30 return ( 31 SwaigFunctionResult("I'll have someone call you to reschedule. Thank you!") 32 .update_global_data({"needs_reschedule": True}) 33 .hangup() 34 ) 35 36 if __name__ == "__main__": 37 agent.run()
Recipe: Survey Bot
1 #!/usr/bin/env python3 2 # survey_bot.py - Collect survey responses with rating scale 3 from signalwire_agents import AgentBase 4 from signalwire_agents.core.function_result import SwaigFunctionResult 5 6 agent = AgentBase(name="survey", route="/survey") 7 agent.prompt_add_section("Role", """ 8 You are conducting a brief customer satisfaction survey. 9 Ask each question, wait for a response, then move to the next. 10 Be friendly and thank them for their feedback. 11 """) 12 agent.prompt_add_section("Questions", """ 13 1. On a scale of 1-5, how satisfied are you with our service? 14 2. What could we do better? 15 3. Would you recommend us to others? (yes/no) 16 """) 17 agent.add_language("English", "en-US", "rime.spore") 18 agent.set_global_data({"responses": {}}) 19 20 @agent.tool( 21 description="Record a survey response", 22 parameters={ 23 "type": "object", 24 "properties": { 25 "question_number": {"type": "integer", "description": "Question number (1-3)"}, 26 "response": {"type": "string", "description": "The customer's response"} 27 }, 28 "required": ["question_number", "response"] 29 } 30 ) 31 def record_response(question_number: int, response: str) -> SwaigFunctionResult: 32 return SwaigFunctionResult(f"Got it, thank you.").update_global_data({ 33 f"responses.q{question_number}": response 34 }) 35 36 @agent.tool(description="Complete the survey") 37 def complete_survey() -> SwaigFunctionResult: 38 return ( 39 SwaigFunctionResult("Thank you for completing our survey! Your feedback helps us improve.") 40 .hangup() 41 ) 42 43 if __name__ == "__main__": 44 agent.run()
Recipe: Order Status Lookup
1 #!/usr/bin/env python3 2 # order_status.py - Look up order status from API 3 from signalwire_agents import AgentBase 4 from signalwire_agents.core.data_map import DataMap 5 from signalwire_agents.core.function_result import SwaigFunctionResult 6 7 # Configure your API 8 API_BASE_URL = "https://api.yourstore.com" 9 API_KEY = "your-api-key" 10 11 agent = AgentBase(name="orders", route="/orders") 12 agent.prompt_add_section("Role", """ 13 You help customers check their order status. 14 Ask for their order number and look it up. 15 """) 16 agent.add_language("English", "en-US", "rime.spore") 17 18 # Use DataMap for serverless API integration 19 order_lookup = ( 20 DataMap("check_order") 21 .purpose("Look up order status by order number") 22 .parameter("order_number", "string", "The order number to look up", required=True) 23 .webhook("GET", f"{API_BASE_URL}/orders/${{enc:args.order_number}}", 24 headers={"Authorization": f"Bearer {API_KEY}"}) 25 .output(SwaigFunctionResult( 26 "Order ${args.order_number}: Status is ${response.status}. " 27 "Expected delivery: ${response.estimated_delivery}." 28 )) 29 .fallback_output(SwaigFunctionResult( 30 "I couldn't find order ${args.order_number}. Please check the number and try again." 31 )) 32 ) 33 34 agent.register_swaig_function(order_lookup.to_swaig_function()) 35 36 if __name__ == "__main__": 37 agent.run()
Recipe: After-Hours Handler
1 #!/usr/bin/env python3 2 # after_hours.py - Handle calls outside business hours 3 from signalwire_agents import AgentBase 4 from signalwire_agents.core.function_result import SwaigFunctionResult 5 6 agent = AgentBase(name="afterhours", route="/afterhours") 7 agent.prompt_add_section("Role", """ 8 You are answering calls outside of business hours. 9 Inform callers of the business hours and offer to take a message or transfer to emergency line. 10 """) 11 agent.prompt_add_section("Hours", """ 12 Business hours: Monday-Friday, 9 AM to 5 PM Eastern Time 13 Emergency line: Available 24/7 for urgent matters only 14 """) 15 agent.add_language("English", "en-US", "rime.spore") 16 agent.add_skill("datetime") # So agent knows current time 17 agent.set_global_data({"message_left": False}) 18 19 EMERGENCY_NUMBER = "+15551234567" 20 MAIN_NUMBER = "+15559876543" 21 22 @agent.tool( 23 description="Take a message from the caller", 24 parameters={ 25 "type": "object", 26 "properties": { 27 "name": {"type": "string", "description": "Caller's name"}, 28 "phone": {"type": "string", "description": "Callback phone number"}, 29 "message": {"type": "string", "description": "Message to leave"} 30 }, 31 "required": ["name", "phone", "message"] 32 } 33 ) 34 def take_message( 35 name: str, 36 phone: str, 37 message: str 38 ) -> SwaigFunctionResult: 39 return ( 40 SwaigFunctionResult("I've recorded your message. Someone will call you back during business hours.") 41 .update_global_data({"message_left": True, "caller_name": name, "callback_number": phone, "message": message}) 42 .send_sms( 43 to_number=MAIN_NUMBER, 44 from_number=phone, 45 body=f"After-hours message from {name} ({phone}): {message}" 46 ) 47 ) 48 49 @agent.tool(description="Transfer to emergency line for urgent matters") 50 def transfer_emergency() -> SwaigFunctionResult: 51 return ( 52 SwaigFunctionResult("Connecting you to our emergency line.") 53 .connect(EMERGENCY_NUMBER, final=True) 54 ) 55 56 if __name__ == "__main__": 57 agent.run()