# LiveKit Telephony Configuration Guide

## What's Missing?

Your code is **ready to handle phone calls**, but LiveKit doesn't know how to accept calls from Twilio yet. You need to configure **two things in LiveKit**:

1. **Inbound SIP Trunk** - Tells LiveKit to accept calls from Twilio
2. **Dispatch Rule** - Routes incoming calls to your agent

---

## Quick Setup (3 Steps)

### Step 1: Create Inbound SIP Trunk

This tells LiveKit to accept calls to your Twilio phone number.

#### Option A: Using Python Script (Recommended)

```bash
cd /var/www/html/vikas/2025-Nov-21-Voicebot/BackEnd/agent-starter-python
python3 setup_sip_trunk.py
```

#### Option B: Using LiveKit Dashboard

1. Go to https://cloud.livekit.io/
2. Navigate to **Telephony** → **SIP trunks**
3. Click **Create new trunk**
4. Select **JSON editor** tab
5. Select **Inbound** direction
6. Paste this JSON:

```json
{
  "name": "Twilio Inbound",
  "numbers": ["+14632175613"],
  "krispEnabled": true
}
```

7. Click **Create**

---

### Step 2: Create Dispatch Rule

This routes incoming calls to your agent.

#### Option A: Using Python Script (Recommended)

```bash
cd /var/www/html/vikas/2025-Nov-21-Voicebot/BackEnd/agent-starter-python
python3 setup_dispatch_rule.py
```

#### Option B: Using LiveKit Dashboard

1. Go to **Telephony** → **Dispatch rules**
2. Click **Create new rule**
3. Configure:
   - **Name**: "Twilio to Agent"
   - **Trunk**: Select the trunk you created in Step 1
   - **Room name**: Leave empty (auto-generate)
   - **Agent name**: `default` (must match your agent code)
4. Click **Create**

---

### Step 3: Test Your Setup

1. **Start your agent:**
   ```bash
   cd /var/www/html/vikas/2025-Nov-21-Voicebot/BackEnd/agent-starter-python
   python3 -m src.agent
   ```

2. **Call your Twilio number:**
   ```
   +14632175613
   ```

3. **What should happen:**
   - Twilio receives your call
   - Twilio dials LiveKit's SIP endpoint
   - LiveKit accepts the call (via inbound trunk)
   - LiveKit creates a room and dispatches your agent (via dispatch rule)
   - Your agent joins the room and starts talking!

---

## How It Works

### The Call Flow

```
[Your Phone] 
    ↓ (calls)
[Twilio: +14632175613]
    ↓ (fetches TwiML from TWILIO_TWIML_URL)
[TwiML: <Dial><Sip>sip:inbound@1k21pbdbx60.sip.livekit.cloud</Sip></Dial>]
    ↓ (dials SIP endpoint)
[LiveKit SIP Endpoint: 1k21pbdbx60.sip.livekit.cloud]
    ↓ (matches inbound trunk)
[Inbound Trunk: numbers=["+14632175613"]]
    ↓ (applies dispatch rule)
[Dispatch Rule: trunk_ids=[...], agent_name="default"]
    ↓ (creates room & dispatches agent)
[Your Agent: @server.rtc_session(agent_name="default")]
    ↓ (joins room & starts voice session)
[Voice Conversation! 🎉]
```

### What Each Component Does

1. **Twilio Phone Number** (`+14632175613`)
   - Your public phone number that people call
   - Configured in Twilio console

2. **TwiML URL** (`TWILIO_TWIML_URL`)
   - Tells Twilio what to do with incoming calls
   - Currently: dial LiveKit's SIP endpoint

3. **LiveKit SIP Endpoint** (`1k21pbdbx60.sip.livekit.cloud`)
   - Your LiveKit project's SIP domain
   - Receives SIP calls from Twilio

4. **Inbound Trunk** (needs to be created)
   - Accepts calls to specific phone numbers
   - Filters by phone number and/or caller IP
   - Enables noise cancellation (Krisp)

5. **Dispatch Rule** (needs to be created)
   - Routes calls from trunk to agent
   - Creates room for each call
   - Specifies which agent to dispatch

6. **Your Agent** (`agent.py`)
   - Handles the voice conversation
   - Uses STT (speech-to-text), LLM, and TTS (text-to-speech)
   - Already configured to handle SIP participants!

---

## Troubleshooting

### "Agent did not join within 10 seconds"

**Cause**: Your agent isn't running or took too long to join.

**Fix**:
1. Make sure agent is running: `python3 -m src.agent`
2. Check agent logs for errors
3. Verify `LIVEKIT_URL`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET` in `.env.local`

### "Call failed immediately"

**Cause**: Inbound trunk not configured or wrong phone number.

**Fix**:
1. Verify trunk exists: `python3 setup_sip_trunk.py` (will show existing trunks)
2. Check phone number matches: `+14632175613`
3. Check LiveKit dashboard → Telephony → SIP trunks

### "Call connects but no agent responds"

**Cause**: Dispatch rule not configured or wrong agent name.

**Fix**:
1. Verify dispatch rule exists: `python3 setup_dispatch_rule.py`
2. Check agent name in dispatch rule matches `@server.rtc_session(agent_name="default")`
3. Check agent logs for "Job received" message

### "Agent joins but no audio"

**Cause**: API keys for STT/TTS not configured.

**Fix**:
1. Verify `ELEVENLABS_API_KEY` or `CARTESIA_API_KEY` in `.env.local`
2. Check agent logs for STT/TTS errors
3. Test API keys with a simple request

---

## Advanced Configuration

### Custom Agent Behavior Per Call

You can pass metadata to customize agent behavior:

```python
# In dispatch rule
rule = api.SIPDispatchRuleInfo(
    name="Twilio to Agent",
    trunk_ids=[trunk_id],
    rule=api.SIPDispatchRule(
        dispatch_rule_direct=api.SIPDispatchRuleDirect(
            room_name="",
            pin="",
        )
    ),
    attributes={
        "agent_name": "default",
        "agent_instructions": "You are a helpful assistant for customer support.",
        "agent_first_message": "Hello! How can I help you today?",
        "agent_tts_provider": "elevenlabs",
        "agent_voice": "EXAVITQu4vr4xnSDxMaL",
    }
)
```

Your agent already reads these from metadata (see `agent.py` lines 181-193).

### Multiple Phone Numbers

To handle multiple phone numbers:

1. Add all numbers to the inbound trunk:
   ```json
   {
     "numbers": ["+14632175613", "+14155551234", "+13105555678"]
   }
   ```

2. Create different dispatch rules for different behaviors:
   - Sales line → agent with sales instructions
   - Support line → agent with support instructions
   - General line → agent with general instructions

### Filtering by Caller Number

To only accept calls from specific numbers:

```json
{
  "name": "Twilio Inbound",
  "numbers": ["+14632175613"],
  "allowedNumbers": ["+13105551234", "+14155555678"],
  "krispEnabled": true
}
```

---

## Next Steps

1. ✅ Run `setup_sip_trunk.py` to create inbound trunk
2. ✅ Run `setup_dispatch_rule.py` to create dispatch rule
3. ✅ Start your agent: `python3 -m src.agent`
4. ✅ Test by calling: `+14632175613`
5. 🎉 Enjoy your working voice AI!

---

## Resources

- [LiveKit SIP Documentation](https://docs.livekit.io/sip/)
- [Inbound Trunk API](https://docs.livekit.io/sip/trunk-inbound)
- [Dispatch Rules API](https://docs.livekit.io/sip/accepting-calls/dispatch-rule/)
- [Twilio SIP Configuration](https://docs.livekit.io/sip/quickstarts/configuring-twilio-trunk)
