Lab L1.4: First Live Call

🎯 Assignment: Accept this lab on GitHub Classroom
You’ll get your own repository with starter code, instructions, and automatic grading.

   
Duration 60 minutes
Prerequisites Previous module completed

Objectives

  • Connect agent to SignalWire
  • Configure ngrok tunnel
  • Make live test calls
  • Debug real-time interactions

How to Complete This Lab

  1. Accept the Assignment — Click the GitHub Classroom link above
  2. Clone Your Repogit clone <your-repo-url>
  3. Read the README — Your repo has detailed requirements and grading criteria
  4. Write Your Code — Implement the solution in solution/agent.py
  5. Test Locally — Use swaig-test to verify your agent works
  6. Push to Submitgit push triggers auto-grading

Key Concepts

The following exercises walk through the concepts you’ll need. Your GitHub Classroom repo README has the specific requirements for grading.

Exercise 1: Prepare Your Agent

Create a production-ready agent:

Create live_agent.py:

#!/usr/bin/env python3
"""Agent ready for live calls."""

import os
from signalwire_agents import AgentBase

agent = AgentBase(
    name="live-agent",
    route="/agent"
)

# Basic authentication
auth_user = os.getenv("AUTH_USER", "signalwire")
auth_pass = os.getenv("AUTH_PASS", "training123")

agent.set_params({
    "swml_basic_auth_user": auth_user,
    "swml_basic_auth_password": auth_pass,
})

# Prompt
agent.prompt_add_section(
    "Role",
    "You are a friendly training assistant for SignalWire. "
    "Greet callers warmly and have a brief conversation. "
    "Ask them what they're learning about today."
)

agent.prompt_add_section(
    "Guidelines",
    bullets=[
        "Keep responses brief - this is a phone call",
        "Be enthusiastic about voice AI",
        "If asked about SignalWire, say you're a demo agent"
    ]
)

# Voice configuration with fillers
# Using both speech_fillers AND function_fillers outputs them as separate fields
agent.add_language(
    name="English",
    code="en-US",
    voice="rime.spore",
    speech_fillers=["Um", "Uh", "Well", "Let me think"],
    function_fillers=["One moment please", "Let me check that for you"]
)

if __name__ == "__main__":
    agent.run()

Note on Fillers: When you provide BOTH speech_fillers AND function_fillers, they appear as separate fields in the SWML output. If you only provide one type, it uses the deprecated fillers field.

Test locally:

swaig-test live_agent.py --dump-swml

Exercise 2: Start Agent Server

Run your agent:

python live_agent.py

Keep this terminal running!

Verify it’s working:

# In another terminal
curl http://localhost:3000/agent

You should see SWML JSON.


Exercise 3: Start ngrok Tunnel

In a new terminal:

# Option A: Random URL
ngrok http 3000

# Option B: Static domain (if you have one)
ngrok http 3000 --domain=your-name.ngrok-free.app

Record your forwarding URL:

Forwarding URL: https://_________________.ngrok.io

Exercise 4: Test Tunnel

Verify the tunnel works:

# Without auth (should fail)
curl https://YOUR-URL.ngrok.io/agent
# Expected: 401 Unauthorized

# With auth (should work)
curl https://signalwire:training123@YOUR-URL.ngrok.io/agent
# Expected: SWML JSON

Checkpoint: Both tests behave as expected.


Exercise 5: Configure SignalWire

  1. Log in to SignalWire dashboard
  2. Navigate to Phone Numbers
  3. Click on your phone number
  4. Find Voice and Fax Settings
  5. Configure:
Setting Value
Handle calls using SWML Script
URL https://signalwire:training123@YOUR-URL.ngrok.io/agent
HTTP Method POST
  1. Click Save

Important: Replace YOUR-URL with your actual ngrok URL!


Exercise 6: Make Your First Call

Preparation Checklist:

  • Agent running in terminal 1
  • ngrok running in terminal 2
  • SignalWire configured with your URL

Make the Call:

  1. Call your SignalWire phone number
  2. Wait for your agent to answer
  3. Have a brief conversation
  4. Hang up when done

What to Try:

  • Say “Hello”
  • Ask “What can you do?”
  • Ask “What am I learning today?”

Exercise 7: Monitor the Call

While calling, watch:

Terminal 1 (Agent):

INFO:     POST /agent HTTP/1.1 200 OK
INFO:     POST /agent/swaig HTTP/1.1 200 OK

Terminal 2 (ngrok): Shows requests coming through the tunnel.

ngrok Inspector: Open http://127.0.0.1:4040 to see:

  • Request details
  • Response bodies
  • Timing information

Exercise 8: Troubleshooting Practice

If your call didn’t work, diagnose:

Step 1: Agent running?

curl http://localhost:3000/agent

Should return SWML.

Step 2: ngrok tunnel working?

curl https://YOUR-URL.ngrok.io/agent

Should return 401 (auth required).

Step 3: Auth correct?

curl https://signalwire:training123@YOUR-URL.ngrok.io/agent

Should return SWML.

Step 4: SignalWire URL correct? Double-check the URL in SignalWire dashboard.

Common Issues:

Problem Cause Fix
No answer Agent not running Start agent
Fast busy ngrok down Restart ngrok
“Cannot connect” Wrong URL Fix SignalWire URL
Silence Auth failed Check credentials

Exercise 9: Make Changes Live

Without stopping anything:

  1. Edit live_agent.py
  2. Change the prompt
  3. Save the file

Hot reload:

  • The agent auto-reloads on file change
  • Call again to hear the new behavior

Try changing:

  • Greeting style
  • Voice (try rime.marsh)
  • Filler phrases

Exercise 10: Clean Shutdown

Proper shutdown sequence:

  1. Press Ctrl+C in agent terminal
  2. Press Ctrl+C in ngrok terminal
  3. Update SignalWire to remove URL (or leave for later)

Deliverables

Record and submit:

  1. Screenshot of ngrok running
  2. Screenshot of SignalWire configuration
  3. Brief notes on your conversation with the agent

Review Questions

  1. Why do we need ngrok for development?
  2. What does the authentication protect against?
  3. What URL format includes credentials?
  4. How do you debug when calls don’t work?
  5. What happens when you change the agent while running?

Summary

You have successfully:

  1. Prepared an agent for live calls
  2. Set up ngrok tunnel
  3. Configured authentication
  4. Connected SignalWire phone number
  5. Made your first live AI call!

Congratulations! You’ve completed the core Day 1 objectives.

Next: Day 2 - Prompt Engineering and Functions


Complete Agent Code

Click to reveal complete solution
#!/usr/bin/env python3
"""Agent ready for live calls with authentication.

Lab 1.4 Deliverable: Production-ready agent configured for live calls
with basic authentication, prompts, and voice settings.

Environment variables:
    SWML_BASIC_AUTH_USER: Basic auth username (auto-detected by SDK)
    SWML_BASIC_AUTH_PASSWORD: Basic auth password (auto-detected by SDK)
"""

from signalwire_agents import AgentBase

agent = AgentBase(
    name="live-agent",
    route="/agent"
)

# Prompt configuration
agent.prompt_add_section(
    "Role",
    "You are a friendly training assistant for SignalWire. "
    "Greet callers warmly and have a brief conversation. "
    "Ask them what they're learning about today."
)

agent.prompt_add_section(
    "Guidelines",
    bullets=[
        "Keep responses brief - this is a phone call",
        "Be enthusiastic about voice AI",
        "If asked about SignalWire, say you're a demo agent"
    ]
)

# Voice configuration with fillers
# Using both speech_fillers AND function_fillers outputs them as separate fields
agent.add_language(
    name="English",
    code="en-US",
    voice="rime.spore",
    speech_fillers=["Um", "Uh", "Well", "Let me think"],
    function_fillers=["One moment please", "Let me check that for you"]
)

if __name__ == "__main__":
    agent.run()

Back to top

SignalWire AI Agents Certification Program