GitHub - hkjarral/AVA-AI-Voice-Agent-for-Asterisk: An open-source AI Voice Agent that integrates with Asterisk/FreePBX using Audiosocket/RTP technology
Pangram verdict · v3.3
We believe that this document is mainly AI-generated, with some AI-assisted content.
AI likelihood · overall
AIArticle text · 1,413 words · 5 segments analyzed
📖 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
1. 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!
2. Start the Admin UI # Start the Admin UI container docker compose -p asterisk-ai-voice-agent up -d --build --force-recreate admin_ui 3. Access the Dashboard Open in your browser:
Local: http://localhost:3003 Remote server: http://<server-ip>: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.
4. 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 5. 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 <slug>. 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.3 — Local AI stabilization 🧠 v7.3.3 is a Local-AI-only stabilization release. It adds no providers and keeps the cloud-provider call paths unchanged.
Calls are isolated by session — agent prompts and conversation state no longer mutate shared Local AI Server configuration or leak across reused WebSocket connections. AI Engine and Local AI Server should be upgraded together; the legacy unscoped switch remains temporarily compatible. Barge-in abandons interrupted output — late LLM/TTS work is quarantined, the interrupted exchange is removed from weak-model history, and the replacement turn stays focused on what the caller just said. Farewells finish exactly once — Local hangup_call speaks the selected Kokoro/Piper/etc. farewell without a second LLM rewrite, drains partial AudioSocket or RTP tails, records agent_hangup, and then disconnects. CPU/GPU deployment is safer — dependency pins, CUDA/cuDNN validation, optional llama.cpp architecture targeting, and idempotent preflight checks reduce first-build and rerun failures. Community GPU evidence — Tesla V100S testing passed Faster-Whisper CUDA float16, Llama 3.1 8B Q4_K_M, Kokoro, AudioSocket, ExternalMedia, barge-in, terminal hangup, concurrent session isolation, and restart recovery.
See the Local AI community test matrix and the Unreleased changelog for the complete scope.
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.