Show HN: Self-hosted voice AI agent for Asterisk/FreePBX
AVA is an open-source, self-hosted voice AI agent for Asterisk/FreePBX, offering quick deployment, multi-agent management, real-time dashboard, and support for multiple AI engines. Recent updates include stability fixes, silence watchdog, and per-agent voice selection.
Notifications You must be signed in to change notification settings
Fork 243
Star 1.1k
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
3,440 Commits
3,440 Commits
.github
.github
admin_ui
admin_ui
assets
assets
cli
cli
config
config
data
data
docs
docs
examples
examples
local_ai_server
local_ai_server
models
models
scripts
scripts
secrets
secrets
src
src
tests
tests
tools
tools
updater
updater
.coveragerc
.coveragerc
.dockerignore
.dockerignore
.env.example
.env.example
.gitignore
.gitignore
AVA-Admin-UI.jpg
AVA-Admin-UI.jpg
AVA.mdc
AVA.mdc
CHANGELOG.md
CHANGELOG.md
CODE_OF_CONDUCT.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
CONTRIBUTING.md
CONTRIBUTORS.md
CONTRIBUTORS.md
Dockerfile
Dockerfile
GOVERNANCE.md
GOVERNANCE.md
LICENSE
LICENSE
Makefile
Makefile
README.md
README.md
SECURITY.md
SECURITY.md
docker-compose.admin-ui-host-binaries.yml
docker-compose.admin-ui-host-binaries.yml
docker-compose.gpu.yml
docker-compose.gpu.yml
docker-compose.host.yml
docker-compose.host.yml
docker-compose.local-core.yml
docker-compose.local-core.yml
docker-compose.yml
docker-compose.yml
install.sh
install.sh
main.py
main.py
preflight.sh
preflight.sh
pytest.ini
pytest.ini
requirements-dev.txt
requirements-dev.txt
requirements.txt
requirements.txt
Repository files navigation
📖 Table of Contents
🚀 Quick Start
🎉 What's New
🌟 Why Asterisk AI Voice Agent?
✨ Features
🎥 Demo
🛠️ AI-Powered Actions
🩺 Agent CLI Tools
⚙️ Configuration
🏗️ Project Architecture
📊 Requirements
🗺️ Documentation
🤝 Contributing
💬 Community
📝 License
🚀 Quick Start
Get the Admin UI running in 2 minutes.
For a complete first successful call walkthrough (dialplan + transport selection + verification), see:
Installation Guide
Transport Compatibility
- Run Pre-flight Check (Required)
Clone repository
git clone https://github.com/hkjarral/AVA-AI-Voice-Agent-for-Asterisk.git cd AVA-AI-Voice-Agent-for-Asterisk
Run preflight with auto-fix (creates .env, generates JWT_SECRET)
sudo ./preflight.sh --apply-fixes
Important: Preflight creates your .env file and generates a secure JWT_SECRET. Always run this first!
- Start the Admin UI
Start the Admin UI container
docker compose -p asterisk-ai-voice-agent up -d --build --force-recreate admin_ui
- Access the Dashboard
Open in your browser:
Local: http://localhost:3003
Remote server: http://:3003
Default Login: On first start, a one-time admin password is printed to the container logs. Retrieve it with:
docker compose -p asterisk-ai-voice-agent logs admin_ui | grep -i password
You must change it at first login. Restrict port 3003 via firewall, VPN, or reverse proxy for production use.
Follow the Setup Wizard to configure your providers and make a test call.
⚠️ Security: The Admin UI is accessible on the network. Restrict port 3003 via firewall, VPN, or reverse proxy for production use.
- Verify Installation
GPU users: If you have an NVIDIA GPU for local AI inference, see docs/LOCAL_ONLY_SETUP.md for the GPU compose overlay (docker-compose.gpu.yml) before building.
Start ai_engine (required for health checks)
docker compose -p asterisk-ai-voice-agent up -d --build ai_engine
Check ai_engine health
curl http://localhost:15000/health
Expected: {"status":"healthy"} ("degraded" is also possible if a subsystem is unhealthy)
View logs for any errors
docker compose -p asterisk-ai-voice-agent logs ai_engine | tail -20
- Connect Asterisk
The wizard will generate the necessary dialplan configuration for your Asterisk server.
Transport selection is configuration-dependent (not strictly “pipelines vs full agents”). Use the validated matrix in:
docs/Transport-Mode-Compatibility.md
🔧 Advanced Setup (CLI)
For users who prefer the command line or need headless setup.
Option A: Interactive CLI
./install.sh agent setup
Note: Legacy commands agent init, agent quickstart, agent doctor, agent troubleshoot, and agent demo remain as hidden compatibility aliases. New workflows should use the visible commands documented in docs/CLI_TOOLS_GUIDE.md.
Option B: Manual Setup
Configure environment
cp .env.example .env
Edit .env with your API keys
Start services
docker compose -p asterisk-ai-voice-agent up -d
Configure Asterisk Dialplan
Add this to your FreePBX (extensions_custom.conf):
[from-ai-agent] exten => s,1,NoOp(Asterisk AI Voice Agent) ; AI_AGENT selects an operator-managed agent by slug. same => n,Set(AI_AGENT=sales-agent) ; Optional: override that agent's configured provider/pipeline for this call. ; same => n,Set(AI_PROVIDER=google_live) same => n,Stasis(asterisk-ai-voice-agent) same => n,Hangup()
Notes:
Use AI_AGENT to select an operator-managed agent. Its configured target is authoritative unless AI_PROVIDER is intentionally set as a per-call override.
Generate a current snippet with agent dialplan --agent .
See docs/FreePBX-Integration-Guide.md for channel variable precedence and examples.
Test Your Agent
Health check:
agent check
View logs:
docker compose -p asterisk-ai-voice-agent logs -f ai_engine
🎉 What's New
v7.3.2 — stabilization release 🛡️
v7.3.2 is a stabilization-only patch release built from the supervised AudioSocket and ExternalMedia validation cycle.
No new providers — scope is limited to reliability, deployment safety, documentation, and contributor-facing CI.
Grok ExternalMedia repaired — clean barge-in, cancelled-output quarantine, named-instance runtime inheritance, complete replacement turns, and exact inactivity announcements through xAI force_message.
AudioSocket and modular pipelines hardened — terminal playback, pipeline producer ownership, talk-detect echo, and inactivity-grace regressions are covered by focused tests and supervised calls.
Updater and provider-failure recovery hardened — safer ownership, rollback/stash handling, readiness validation, and an opt-in dialplan redirect.
PR quality gates expanded — Admin backend/frontend checks and CLI cross-compilation now run before merge.
Release evidence and remaining gates are tracked in the v7.3.2 validation matrix.
v7.3.1 — Silence watchdog & safe call endings ☎️
AVA now protects silent calls and finishes every terminal message before disconnecting.
30-second inbound inactivity protection by default — AVA asks “Are you still there?”, waits 15 seconds for a reply, then speaks a configurable final warning and ends the call. Outbound agents remain opt-in.
The agent keeps its configured voice — check-ins and final warnings are synthesized by the active Google Live, OpenAI Realtime, Grok, Deepgram, ElevenLabs, local full-agent, or pipeline voice.
Transport-safe hangup — watchdog and hangup_call farewells drain AudioSocket or ExternalMedia/RTP streaming buffers and ARI file playback before ARI disconnects the caller. Fixed sleeps no longer clip long final sentences.
Deepgram and ElevenLabs lifecycle fixes — Deepgram control frames no longer split greetings, and ElevenLabs response-completion plus hosted-silence handling keeps AVA's watchdog authoritative.
Global and per-agent controls — configure defaults under Advanced Settings → Voice Activity Detection → Caller Inactivity, then optionally override them per agent. Call History labels watchdog endings as No input timeout.
See Caller inactivity configuration, ElevenLabs setup, and the full v7.3.1 changelog.
v7.3.0 — Per-agent voices 🎙️
Voice now belongs to agents. Configure one provider, create multiple agents that share it — each with its own voice.
Provider-aware voice picker in the Agent form: a dropdown of OpenAI's 10 GA voices, suggestions + custom clone IDs for Grok, Google Live's 30 prebuilt voices, Deepgram's Aura models — the control adapts to the agent's selected AI Engine.
Safe by default — the provider-level voice becomes the default voice; agents without one behave exactly as before. Unrecognized values (OpenAI/Google/Deepgram catalogs are validated) log a warning and fall back — a bad voice value never fails a call.
Observable — every call logs the resolved voice and its source, and Call History shows "Voice: marin (from agent)" per call.
Agent voice changes apply instantly — no engine restart.
Thanks @foytech for seeding this feature (#497). Full guide: docs/VOICE_SELECTION.md.
v7.2.0 — Live-status dashboard 📡
Real-time system status for the Admin UI — pushed, not polled.
Live-status hub — a single /api/live-status snapshot endpoint plus an SSE stream (/api/live-status/stream) aggregates AI Engine health, Local AI connectivity, active sessions, audio directories, platform checks, and Asterisk ARI into one normalized status feed.
Push-first — ai_engine and local_ai_server push their own readiness to the Admin UI (POST /api/live-status/publish, authenticated with LIVE_STATUS_PUSH_TOKEN), so the dashboard converges in sub-second time after a restart instead of waiting on staggered polls. Legacy /api/system/* probes remain as fallback/enrichment.
Configurable — LIVE_STATUS_POLL_INTERVAL_SECONDS (default 30 s, min 2 s) and LIVE_STATUS_INITIAL_PROBE_TIMEOUT_SECONDS (default 2 s), read live from .env.
Full notes in CHANGELOG.md.
v7.1.1 — Dashboard reliability & Admin UI polish 🛠️
A focused quality release across the Admin UI — no call-path changes.
Dashboard reliability — the Asterisk status pill no longer flaps on a transient ARI blip: it reads the engine's authoritative, reconnect-supervised ARI state and applies hysteresis. The system endpoints the Dashboard polls every 5s no longer block the admin event loop, the heaviest is TTL-cached, polling backs off on errors, failed polls surface in the error banner, and a single bad poll no longer flashes cards to "Loading…".
No more "Loading configuration…" flash — ~11 config pages now seed from a shared stale-while-revalidate cache of the config document, so revisiting a settings page is instant.
Accessibility (WCAG AA) — form labels programmatically associated with inputs, a focus-trapping modal, a navigation landmark + "skip to content" link, accessible names on icon-only buttons, non-colour status cues on the topology, a visible dark-mode toggle on-state, and light-mode contrast fixes. Debug console.logs (including one that leaked the auth token to the browser console) were removed.
Prompt editor — configured tool names are colour-coded by their in-call status (enabled / global / not-enabled) as you type.
Fix (#436) — a canonical google_live: { type: full } provider can be edited and saved again.
Full notes in CHANGELOG.md.
v7.0.0 — the Agents release 🎯
The biggest release yet: manage your AI agents from the Admin UI, not a config file.
🤖 Agents tab — create, edit, and manage agents in the UI. Start from a template (receptionist, after-hours, appointment booker, and more), set the prompt and provider, and copy a ready-to-paste dialplan snippet. (Voice is configured on the provider, not per agent.)
📊 Multi-agent dashboard — live KPIs (active agents, active calls, calls routed, transfers), per-agent stats, and routing breakdowns at a glance.
☎️ New AI_AGENT dialplan variable — route a call to an agent by name. Your existing AI_CONTEXT dialplans keep working unchanged.
🔄 Automatic migration — your existing contexts move into a local agents database on first start. Nothing to do, and rollback is one command.
🔒 Security hardening — no more admin/admin: a one-time admin password is generated and must be changed at first login. Config exports no longer bundle your .env by default.
⚠️ Major release — please read the Upgrade Notes befo
[truncated for AI cost control]