The Problem
Call centers need AI agents that can make and receive phone calls programmatically. Building this from scratch requires integrating telephony, speech recognition, LLM orchestration, and persistence—weeks of work. This repo packages that integration into a deployable service with a single HTTP endpoint that triggers a call.
What This Does
call-center-ai is a Python/FastAPI service that places outbound calls or receives inbound calls through an AI agent. It uses Azure Communication Services for telephony, OpenAI GPT models for conversation, and supports Azure Cosmos DB, Redis, or in-memory storage. The bot handles multi-turn conversations, real-time streaming, SMS fallback, and can be customized via YAML config files.
The core logic lives in app/main.py (29 functions) with helpers in app/helpers/. The app/models/ directory defines the data structures (call.py, message.py, claim.py). Persistence is abstracted behind interfaces in app/persistence/ with implementations for Cosmos DB, Azure Queue Storage, Redis, and Twilio.
How It Is Wired
Execution starts at app/main.py's lifespan handler, which initializes configuration and resources. The /call POST endpoint (defined in main.py) accepts a JSON payload and triggers call_events.on_new_call. That function routes through call_utils.py (42 functions, the largest helper) which handles media streaming, TTS sentence splitting, and call state transitions.
The critical path is short: HTTP request → on_new_call → call_llm.load_llm_chat → LLM inference → call_events.on_audio_connected → telephony provider. External effects touch Azure Communication Services, OpenAI, Cosmos DB, and Redis—usually within 3-4 function hops from the entry point.
The module graph shows three hub modules with high blast radius: app/helpers/config.py and app/helpers/logging.py (each imported by 20 modules) and app/helpers/cache.py (17 importers). Changes to these ripple widely. There are also 25 modules involved in circular imports, which will make refactoring these hubs painful.
How To Use It
Setup: This is a Python project with pyproject.toml and a uv.lock file. Install with uv sync or pip install -e .. A Makefile provides common targets. Container deployment uses cicd/Dockerfile.
Configuration: Copy .env.example to .env and fill in Azure credentials. The config-local-example.yaml and config-remote-example.yaml files define bot behavior, prompts, and feature flags.
Running it: Start the FastAPI server with uvicorn app.main:app from the repo root. The README documents a curl POST to /call with a JSON payload specifying the phone number, task, and claim schema.
Real-World Use
An IT helpdesk deploys this as an Azure Container App. A ticket system calls the /call endpoint with a customer's phone number and a task description. The AI agent calls the customer, gathers hardware and location details into structured claims, and stores them in Cosmos DB. The agent can escalate to a human if the customer requests it.
Code Health & Issues
Static analysis (measured, not opinion) found 54 issues: 30 high, 21 medium, 3 low.
- High - Circular imports - 25 modules participate in mutually reachable import cycles, including
app/helpers/config.py,app/helpers/logging.py, andapp/models/call.py. Refactoring these requires breaking the cycles. - High - Deep nesting - 12 instances of indentation depth 6+, concentrated in
app/models/call.py,app/models/message.py, andapp/persistence/azure_queue_storage.py. - High - Duplicated code - 40 repeated 6-line blocks across 12 files, notably in
call_events.py,call_utils.py, and the search persistence layer. - Medium - Oversized files -
call_events.py,call_utils.py, andmain.pyeach exceed 670 lines. - Medium - Hub modules -
config.pyandlogging.pyeach have 20 dependents; changes are high-blast-radius. - Medium - Broad exception handling - 5 instances of bare
exceptincall_llm.py,ai_search.py, andcosmos_db.py. - Low - TODO/FIXME markers - 17 across
call_llm.py,call_utils.py, andmain.py.
The repo has tests (8 files), CI via GitHub Actions, a Dockerfile, and a license. No lockfile is present for Python dependencies, so builds are not fully reproducible.
The Bottom Line
This is a production-grade reference implementation for AI call centers, well-structured despite its complexity. The circular imports and hub modules will make significant changes expensive. Teams wanting a working Azure-based AI calling system should start here; teams needing custom telephony or storage backends will find the persistence abstractions useful but will need to break the import cycles first.