# Openai Voice Skill

> Add real-time phone calling to AI agents using OpenAI Realtime API and Twilio Media Streams. Use when you want an AI agent to make or receive phone calls with sub-200ms latency, bidirectional audio streaming, and session continuity across voice, Telegram, and email channels. Requires Python 3.9+, a Twilio phone number, and an OpenAI API key with Realtime API access.

- **Type:** Skill
- **Install:** `agentstack add skill-nia-agent-cyber-openai-voice-skill-openai-voice-skill`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [nia-agent-cyber](https://agentstack.voostack.com/s/nia-agent-cyber)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [nia-agent-cyber](https://github.com/nia-agent-cyber)
- **Source:** https://github.com/nia-agent-cyber/openai-voice-skill
- **Website:** https://github.com/nia-agent-cyber/openai-voice-skill#-get-started-in-5-minutes

## Install

```sh
agentstack add skill-nia-agent-cyber-openai-voice-skill-openai-voice-skill
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# openai-voice-skill

Open-source phone calling for AI agents. Bridges Twilio Media Streams to the OpenAI Realtime WebSocket API so your agent can make and receive phone calls with sub-200ms latency and natural barge-in support.

## Architecture

```
Inbound call:
  Phone → Twilio → POST /voice/incoming
       → TwiML 
       → webhook-server.py (WebSocket bridge)
       → OpenAI Realtime API (wss://api.openai.com/v1/realtime)

Outbound call:
  POST /call → Twilio dials number → on answer → same TwiML flow
```

**Audio bridge** (inside `webhook-server.py`):
- Twilio sends: µ-law 8 kHz (base64)
- OpenAI expects: PCM16 24 kHz (base64)
- Conversion uses `audioop` (stdlib < 3.13) or `audioop-lts` (3.13+)

**No deprecated SIP endpoints.** This skill uses Twilio Media Streams (WebSocket) — not `sip.api.openai.com`, which OpenAI deprecated. All audio flows through `webhook-server.py`.

## Prerequisites

1. **Python 3.9+** with pip
2. **Twilio account** with a voice-capable phone number
3. **OpenAI API key** with `gpt-4o-realtime-preview` model access
4. **Public webhook URL** — ngrok, cloudflared, or a deployed server

## Setup

### 1. Clone and install

```bash
git clone https://github.com/nia-agent-cyber/openai-voice-skill.git
cd openai-voice-skill
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
```

### 2. Configure environment

```bash
cp .env.example .env
```

Edit `.env`:

```bash
OPENAI_API_KEY=sk-...
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
TWILIO_PHONE_NUMBER=+1XXXXXXXXXX   # E.164 format
PUBLIC_URL=https://your-tunnel.example.com
PORT=8080
ALLOW_INBOUND_CALLS=true           # set false to disable inbound
```

### 3. Expose your local server (development)

```bash
# Option A: cloudflared (recommended, no account needed)
cloudflared tunnel --url http://localhost:8080

# Option B: ngrok
ngrok http 8080
```

Set `PUBLIC_URL` in `.env` to the HTTPS URL from your tunnel.

### 4. Start the webhook server

```bash
source venv/bin/activate
python scripts/webhook-server.py
```

The server auto-registers its `/voice/incoming` URL as the Twilio webhook for your phone number on startup.

Verify it's healthy:

```bash
curl http://localhost:8080/health
```

### 5. Make your first call

**Inbound:** Call your Twilio number. The server answers and connects you to the OpenAI Realtime agent.

**Outbound via API:**

```bash
curl -X POST http://localhost:8080/call \
  -H "Content-Type: application/json" \
  -d '{"to": "+1234567890"}'
```

## Customising the Agent

The agent's identity, instructions, and voice are configured in `webhook-server.py` via the `OPENAI_VOICE` constant and the `build_call_prompt()` function. Edit those to change:

- **Voice:** `shimmer`, `alloy`, `echo`, `fable`, `onyx`, `nova`
- **Model:** `gpt-4o-realtime-preview` (default)
- **System prompt:** Anything returned by `build_call_prompt()`

## Session Continuity

After each call, `summarize_and_remember()` writes a transcript summary to `memory/YYYY-MM-DD.md` and emits a wake event to the OpenClaw gateway (if running). This means the same agent that handles phone calls also has full context from Telegram, email, and other channels.

Skip or remove this feature if you don't use OpenClaw — it degrades gracefully.

## Monitoring

```bash
# Active calls
curl http://localhost:8080/calls

# Server health
curl http://localhost:8080/health
```

Logs are written to stdout. For persistent logs, pipe through `tee` or configure `uvicorn` log file output.

## Production Deployment

For production, run behind a process supervisor:

```bash
# systemd (Linux)
ExecStart=/path/to/venv/bin/python scripts/webhook-server.py

# launchd (macOS) — see scripts/org.niavoice.voice-server.plist
launchctl load scripts/org.niavoice.voice-server.plist
```

Ensure `PUBLIC_URL` points to your stable public domain (Cloudflare tunnel, Fly.io, Railway, etc.).

## Troubleshooting

**Call connects but no audio / robotic voice:**
- Verify your tunnel is working: `curl https://your-tunnel.example.com/health`
- Check audio conversion: `audioop` or `audioop-lts` must be installed
- Sample rate mismatch causes robotic audio — do not bypass the µ-law ↔ PCM16 conversion

**Agent doesn't pick up inbound calls:**
- Set `ALLOW_INBOUND_CALLS=true` in `.env`
- Verify Twilio webhook points to `https://your-public-url/voice/incoming`
- The server logs the webhook URL it registers on startup

**Outbound call placed but agent doesn't speak:**
- OpenAI session setup takes ~300ms; speech before `session.updated` is silently dropped
- The server gates audio forwarding until `session.updated` is confirmed (3s timeout)

**Python 3.13+ import error on audioop:**
- Add `audioop-lts` to your virtualenv: `pip install audioop-lts`

## License

AGPL-3.0 — see LICENSE file. Self-hosting for personal or internal use is unrestricted. Distribution of modified versions requires source disclosure.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [nia-agent-cyber](https://github.com/nia-agent-cyber)
- **Source:** [nia-agent-cyber/openai-voice-skill](https://github.com/nia-agent-cyber/openai-voice-skill)
- **License:** MIT
- **Homepage:** https://github.com/nia-agent-cyber/openai-voice-skill#-get-started-in-5-minutes

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-nia-agent-cyber-openai-voice-skill-openai-voice-skill
- Seller: https://agentstack.voostack.com/s/nia-agent-cyber
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
