CLI tool
hkjarral/AVA-AI-Voice-Agent-for-Asterisk avatar
hkjarral/AVA-AI-Voice-Agent-for-Asterisk

AVA AI Voice Agent for Asterisk: wiring STT, LLM and TTS into FreePBX over AudioSocket

An open-source AI Voice Agent that integrates with Asterisk/FreePBX using Audiosocket/RTP technology.

1,232 stars276 forksPythonMIT

At a glance

What is it?
AVA Core is an MIT-licensed Python agent that answers Asterisk and FreePBX calls through ARI and a modular STT/LLM/TTS pipeline. It installs with a preflight script and Docker Compose, but the Admin UI ships open on port 3003 and the README leaves the transport matrix in a separate document.
Who is it for?
Adopt AVA Core if you already run Asterisk or FreePBX and want to choose your own STT, LLM and TTS vendors instead of accepting one platform's bundle; the MIT licence and the preflight script keep the entry cost low. Do not adopt it if you have no Asterisk deployment, no Python or Docker skills, or no appetite for reading docs/Transport-Mode-Compatibility.md before you pick a transport.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What AVA Core actually replaces in a FreePBX setup

Asterisk is good at routing calls and bad at holding a conversation. The usual workaround is an IVR tree or a queue, and both are rigid: a caller who phrases a request differently gets lost. AVA Core sits between the two ends of that problem. It registers with Asterisk through ARI, joins the call as a Stasis application, and streams audio to and from a pipeline of speech-to-text, a language model, and text-to-speech. The caller talks; the agent answers.

The intended user is an operator who already has a PBX. The README's dialplan snippet sends calls into Stasis with a single extension line, and the quick start assumes Docker and a shell. Nothing here is aimed at someone who wants a hosted voice bot with no telephony underneath. If you do not run Asterisk or FreePBX, the project has no surface to attach to.

The interesting design decision is that the pipeline is modular. The README describes a modular pipeline architecture where STT, LLM and TTS providers are mixed and matched, and it refers to six golden baselines validated for enterprise deployment. That framing matters more than any single provider integration: you are not buying a voice model, you are buying the plumbing that lets you swap one.

ARI, Stasis and the audio path into ai_engine

The architecture visible in the repository is a two-container split. The ai_engine container holds the Python application: main.py, src/, config/ and models/ are mounted from the host in docker-compose.yml, so the running code is the code in your working tree. The admin_ui container is the control plane, exposing a dashboard on port 3003 and managing the engine. The compose file sets network_mode: host for the engine, which the comments justify as telephony and low-latency: 127.0.0.1 inside the container reaches Asterisk on the host, and no port mapping is needed.

Call flow starts in the dialplan. The extension sets AI_AGENT to a slug, optionally sets AI_PROVIDER as a per-call override, then hands the channel to Stasis(asterisk-ai-voice-agent). From there the engine talks to Asterisk over ARI, using ari==0.1.3 and websockets==16.1.1 according to requirements.txt. Audio moves over AudioSocket or RTP depending on configuration; the README states that transport selection is configuration-dependent and points at docs/Transport-Mode-Compatibility.md rather than listing the rules inline. That is a real gap for a first-time reader: the single most consequential setting for call quality is documented somewhere other than the quick start.

Speech detection uses webrtcvad==2.0.10, and numpy handles resampling for streaming audio. Metrics are exposed in Prometheus format at http://<host>:15000/metrics, and the health endpoint answers on port 15000 with {"status":"healthy"}, or "degraded" when a subsystem is unhealthy. Per-call debugging goes through the Admin UI Call History rather than log grepping.

Install AVA Core: preflight, Admin UI, and a health check

The README marks the preflight step as required, and it is the step that creates your .env and generates a JWT_SECRET. Skipping it means no environment file and no signing key for the dashboard.

bash
# 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

Next, bring up the Admin UI container. The compose project name is passed explicitly with -p, matching the COMPOSE_PROJECT_NAME value in .env.example.

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

Open http://localhost:3003, or http://<server-ip>:3003 on a remote host. The first admin password is printed once to the container log, and the README gives the command to retrieve it.

bash
docker compose -p asterisk-ai-voice-agent logs admin_ui | grep -i password

You must change that password at first login. The README repeats a security warning: the Admin UI is reachable on the network, so restrict port 3003 with a firewall, a VPN or a reverse proxy in production. Then start the engine, which the README says is required for health checks, and confirm it responds.

bash
docker compose -p asterisk-ai-voice-agent up -d --build ai_engine
curl http://localhost:15000/health

Expect {"status":"healthy"}. A "degraded" answer is also possible when a subsystem is unhealthy, so treat it as a signal to read the logs rather than as a pass. On the Asterisk side, the README shows a dialplan context for extensions_custom.conf that sets AI_AGENT to a slug and enters Stasis; a current snippet can be generated with agent dialplan --agent <slug>. If you prefer the command line over the wizard, ./install.sh followed by agent setup runs an interactive setup, and agent check performs a health check.

Where AVA Core fails closed, and where it is the wrong tool

The v7.5.6 release notes describe outbound lead context as fail-closed: ARI origination uses its documented variables object, and nonempty lead custom_vars is bounded, confirmed before provider startup, recovered after an engine restart, and redacted from diagnostics. That is the right instinct for telephony, because a call that starts without routing metadata is worse than a call that does not start. It also means a misconfigured variable does not degrade quietly; the call fails. Engineers who expect a soft fallback will read that as brittleness.

The same release adds hangup intent markers scoped per Agent, where each Agent can inherit, extend or replace global end-of-call phrases, new calls capture an immutable policy, and older servers or malformed overrides fail closed. Again: strict, and unforgiving of half-migrated deployments.

Two constraints are structural rather than optional. The engine runs with network_mode: host, so it shares the host network stack; that is what makes 127.0.0.1 reach Asterisk, and it is also why the health endpoint is exposed on 0.0.0.0 and why the compose file points readers at SECURITY.md for lockdown instructions. If your policy forbids host networking, this deployment shape is a poor fit. Second, file permissions: the Dockerfile creates an asterisk group with GID 995 by default and adds appuser to it, and the compose comments tell you to export ASTERISK_GID=$(id -g asterisk) and rebuild when your Asterisk uses a different GID. Get that wrong and the engine cannot read /mnt/asterisk_media.

Finally, the README does not document rollback. The v7.5.6 notes say the release does not migrate databases, reassign Agents or change Audio Profiles, which makes an in-place upgrade plausible, but a documented downgrade path is absent. Plan a snapshot before you upgrade.

AVA Core compared with building directly on Asterisk ARI

The honest alternative is not another voice-agent product; it is writing the ARI application yourself. Asterisk already exposes the control channel, and a small Python service using the ari library can answer a call, fork audio, and call any STT or TTS HTTP API. The difference is everything above that layer. AVA Core supplies the audio resampling path, WebRTC VAD for speech detection, barge-in handling, provider configuration, an Admin UI with Call History, Prometheus metrics on port 15000, and a CLI with setup, dialplan, check and troubleshoot commands. Writing that yourself is weeks of work, and most of it is the unglamorous part.

The trade is control and surface area. A bespoke ARI service contains only the providers you wired in; AVA Core carries Google, Microsoft and OpenAI dependencies in requirements.txt, including the Azure speech SDK and google-auth for Vertex AI, and it ships six baselines you did not choose. If your only requirement is a single hardcoded provider and a narrow call flow, the framework is more machinery than the job needs.

There is also a commercial boundary to note. The README describes AVA Operator as a commercial multi-installation management layer built around AVA Core, currently an early-access preview, aimed at operators managing multiple PBXs or customer installations. AVA Core itself remains MIT-licensed, free and fully functional on its own. If you manage one PBX, the core is the whole product; the operator layer only becomes relevant at fleet scale.

Licence, upgrade cost and what the release notes commit to

The repository is MIT-licensed, and the LICENSE file sits at the top level. For most commercial deployments that is permissive: you can run it, modify it and ship it inside a product. The qualification is the dependency set, not the project licence. requirements.txt pulls in azure-cognitiveservices-speech, google-api-python-client, msal, resend and openai, each under its own terms, and the provider you configure determines which of those terms apply to your service. That is a question for your own review, not something the README settles.

Upgrade cost looks low by design. Releases arrive frequently: v7.5.4 on 2026-07-31, v7.5.5 on 2026-08-08, and v7.5.6 on 2026-08-26, the same date as the last push to main. The v7.5.6 notes explicitly state it is an in-place feature and reliability release that does not migrate databases, reassign Agents or change Audio Profiles. An updater/ directory exists at the top level, though the README does not document its workflow. Because src/, config/ and main.py are bind-mounted from the host, a git pull changes the running code on the next container restart, which makes upgrades fast and makes an unreviewed pull risky. Read the release notes before you pull, and keep a copy of config/ and .env outside the repository.

Editorial conclusion

Adopt AVA Core if you already run Asterisk or FreePBX and want to choose your own STT, LLM and TTS vendors instead of accepting one platform's bundle; the MIT licence and the preflight script keep the entry cost low. Do not adopt it if you have no Asterisk deployment, no Python or Docker skills, or no appetite for reading docs/Transport-Mode-Compatibility.md before you pick a transport. Before committing, verify three things on your own hardware: that your Asterisk GID matches the ASTERISK_GID build argument so the container can read /mnt/asterisk_media, that port 3003 is firewalled or behind a reverse proxy, and that your chosen transport mode is listed as validated for your pipeline in the compatibility document.

Frequently asked questions

What is AVA AI Voice Agent for Asterisk?

It is an open-source AI voice agent that integrates with Asterisk and FreePBX using AudioSocket or RTP, built around a modular pipeline where STT, LLM and TTS providers can be mixed and matched. The core is MIT-licensed Python and runs as an ai_engine container alongside an Admin UI.

How do I install AVA AI Voice Agent for Asterisk?

Clone the repository, run sudo ./preflight.sh --apply-fixes to create .env and generate a JWT_SECRET, then start the admin_ui container with docker compose -p asterisk-ai-voice-agent up -d --build --force-recreate admin_ui. The dashboard is then reachable on port 3003.

Which port does the AVA AI Voice Agent Admin UI use?

The README gives http://localhost:3003 for local access and http://<server-ip>:3003 for a remote server. It also warns that the UI is reachable on the network and should be restricted with a firewall, VPN or reverse proxy in production.

How do I check that the AVA ai_engine is healthy?

Start the ai_engine container and request http://localhost:15000/health, which the README says returns {"status":"healthy"}. A "degraded" response is also possible when a subsystem is unhealthy.

Does AVA AI Voice Agent for Asterisk work with FreePBX dialplans?

Yes. The README shows a context for extensions_custom.conf that sets AI_AGENT to an operator-managed agent slug and then calls Stasis(asterisk-ai-voice-agent). A current snippet can be generated with agent dialplan --agent <slug>.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hkjarral-ava-ai-voice-agent-for-asterisk.svg)](https://hysenlabs.com/projects/hkjarral-ava-ai-voice-agent-for-asterisk)