AI News HubLIVE
In-site rewrite5 min read

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.

SourceHacker News AIAuthor: hkjarral

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

  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!

  1. Start the Admin UI

Start the Admin UI container

docker compose -p asterisk-ai-voice-agent up -d --build --force-recreate admin_ui

  1. 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.

  1. 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

  1. 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]