For the runtime relationship between these directories — which process talks to which — read Architecture first. This page is about the tree on disk.
Top level
apps
Four packages under one namespace.apps/__init__.py is empty and exists so apps.providers and apps.telephony are importable from the repository root.
apps/api
api, arq-worker, and campaign-orchestrator all build from apps/api/Dockerfile and differ only in their command:. See Workers and orchestrator.
apps/runtime
apps/providers
catalog.py (with *_CAPABILITIES), config.py, service.py. LLM-only vendors may keep an empty stub languages.py. See Adding an AI provider.
apps/telephony
xml.py, calls.py, and serializers.py are dispatch facades. They contain no provider if/elif chains and must not grow any. See Adding a telephony provider.
apps/telephony/README.md documents the package’s public API and is current.model-server
A separate Docker Compose stack with its own.env, run only if you want to host models yourself.
STT_MODEL, TTS_MODEL, or LLM_MODEL. See Model server overview.
scripts
Four shell scripts, all meant to be run from the repository root.Where tests live
Tests sit inside the package they cover. There is no top-leveltests/ directory.
Full instructions in Testing.
Files that are intentionally empty
Several files exist so tooling and GitHub find them, but hold no content yet. Do not infer a workflow from their presence.
There is also no
.github/ directory, and therefore no CI, no workflows, no issue templates, and no pull-request template. Nothing runs automatically on a push. Every check is something you run locally before opening a pull request.
Because there is no CI, a green local run is the only signal a change has. Run the relevant test suites and
ruff check . in model-server/ yourself.