Skip to content
This repository was archived by the owner on Oct 24, 2025. It is now read-only.

Commit 2805c8c

Browse files
committed
Add content
0 parents  commit 2805c8c

File tree

4 files changed

+441
-0
lines changed

4 files changed

+441
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env.local
2+
venv/

README.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# LiveKit Phone Assistant Agent - SIP REFER Example
2+
3+
## Overview
4+
5+
This repository contains an example implementation of a voice-enabled phone assistant using LiveKit and OpenAI. The `agent.py` module demonstrates how to handle voice interactions, DTMF signals, and SIP REFER transfers to different departments based on user input.
6+
7+
The assistant provides options for callers to be transferred to Billing, Technical Support, or Customer Service departments by pressing corresponding digits.
8+
9+
## Features
10+
11+
- **Voice Interaction**: Engages with users through voice using OpenAI's language models.
12+
- **DTMF Handling**: Listens for DTMF signals (keypad inputs) and responds accordingly.
13+
- **SIP REFER Transfer**: Transfers calls to different departments using SIP REFER requests.
14+
- **Multimodal Agent**: Utilizes LiveKit's multimodal capabilities to handle both audio and text modalities.
15+
16+
## Prerequisites
17+
18+
- Python 3.7 or higher
19+
- A LiveKit Cloud account or self-hosted LiveKit server
20+
- OpenAI API key
21+
- Required Python packages listed in `requirements.txt`
22+
- A SIP Trunk with Twilio, connected to your LiveKit account as detailed [here](https://docs.livekit.io/sip/)
23+
24+
## Setup
25+
26+
### Clone the Repository
27+
28+
```bash
29+
git clone https://github.com/ShayneP/phone-assistant.git
30+
cd phone-assistant
31+
```
32+
33+
### Create a Virtual Environment
34+
35+
It's always recommended to use a virtual environment to manage dependencies.
36+
37+
```bash
38+
python -m venv venv
39+
source venv/bin/activate # On Windows use `venv\Scripts\activate`
40+
```
41+
42+
### Install Dependencies
43+
44+
```bash
45+
pip install -r requirements.txt
46+
```
47+
48+
### Environment Variables
49+
50+
Create a `.env.local` file in the root of the project with the following content:
51+
52+
```bash
53+
OPENAI_API_KEY=your-openai-api-key
54+
BILLING_PHONE_NUMBER=+12345678901
55+
TECH_SUPPORT_PHONE_NUMBER=+12345678901
56+
CUSTOMER_SERVICE_PHONE_NUMBER=+12345678901
57+
LIVEKIT_URL=wss://your-livekit-url.livekit.cloud
58+
LIVEKIT_API_KEY=your-livekit-api-key
59+
LIVEKIT_API_SECRET=your-livekit-api-secret
60+
```
61+
62+
Replace the placeholder values with your actual API keys and phone numbers.
63+
64+
## Running the Assistant
65+
66+
To start the phone assistant agent in development mode, run:
67+
68+
```bash
69+
python agent.py dev
70+
```
71+
72+
When callers call the phone number that's attached to your SIP trunk, calls will be routed into LiveKit rooms.
73+
When a room is created, your Agent will join, wait for the caller to finish connecting, and then greet the user.
74+
75+
## How It Works
76+
77+
### Entry Point
78+
79+
The `entrypoint` function serves as the main entry for the assistant. It initializes the `PhoneAssistant` class and manages the connection lifecycle.
80+
81+
### PhoneAssistant Class
82+
83+
The `PhoneAssistant` class encapsulates the logic for:
84+
85+
- Connecting to a LiveKit room.
86+
- Setting up event handlers for DTMF signals.
87+
- Initializing and starting the multimodal agent.
88+
- Handling SIP REFER transfers.
89+
90+
#### Connecting to the Room
91+
92+
The assistant connects to the LiveKit room and waits for a participant to join.
93+
94+
```python
95+
participant = await assistant.connect_to_room()
96+
```
97+
98+
#### Starting the Agent
99+
100+
Once connected, the assistant initializes the OpenAI model with specific instructions and starts the multimodal agent.
101+
102+
```python
103+
assistant.start_agent(participant)
104+
```
105+
106+
#### Greeting the Caller
107+
108+
Upon starting, the assistant greets the caller and provides options.
109+
110+
```python
111+
greeting = (
112+
"Hi, thanks for calling Vandelay Industries!"
113+
"You can press 1 for Billing, 2 for Technical Support, "
114+
"or 3 for Customer Service. You can also just talk to me, since I'm a LiveKit agent."
115+
)
116+
asyncio.create_task(assistant.say(greeting))
117+
```
118+
119+
#### Handling DTMF Signals
120+
121+
The assistant sets up an event handler for DTMF signals to determine if the caller presses any digits.
122+
123+
```python
124+
@room.on("sip_dtmf_received")
125+
def handle_dtmf(dtmf_event: rtc.SipDTMF):
126+
# Logic to handle DTMF digits and initiate transfer
127+
```
128+
129+
#### SIP REFER Transfer
130+
131+
If the caller selects an option, the assistant uses SIP REFER to transfer the call to the appropriate department.
132+
133+
```python
134+
await assistant.transfer_call(identity, transfer_number)
135+
```
136+
137+
### Cleanup
138+
139+
After the call ends or the room is disconnected, the resources used by the agent are cleaned up.
140+
141+
```python
142+
await assistant.cleanup()
143+
```
144+
145+
## Customization
146+
147+
### Updating Department Options
148+
149+
You can customize the department options by modifying the `department_numbers` dictionary in the `_setup_event_handlers` method, and then changing the names of the phone numbers in your `.env.local` config file.
150+
151+
```python
152+
department_numbers = {
153+
"1": ("BILLING_PHONE_NUMBER", "Billing"),
154+
"2": ("TECH_SUPPORT_PHONE_NUMBER", "Tech Support"),
155+
"3": ("CUSTOMER_SERVICE_PHONE_NUMBER", "Customer Service")
156+
}
157+
```
158+
159+
### Changing Greetings and Messages
160+
161+
Update the `greeting` variable and messages within the `say` method calls to change what the assistant says to the caller.
162+
163+
> Note: It's important to relay the application's intent to use *voice* in the `say` method, or OpenAI will occasionally respond with a stream of text.
164+
165+
## Logging
166+
167+
Logging is configured to output information to help with debugging and monitoring.
168+
169+
```python
170+
logger = logging.getLogger("phone-assistant")
171+
logger.setLevel(logging.INFO)
172+
```
173+
174+
## References
175+
176+
- [LiveKit Python SDK](https://docs.livekit.io/guides/python)
177+
- [LiveKit SIP Guide](https://docs.livekit.io/sip/)
178+
- [OpenAI Realtime Integration Guide](https://docs.livekit.io/agents/openai/overview/)

0 commit comments

Comments
 (0)