pelocal-techservice Bitbucket workspace; the fourth, the
Dialler, is deployed and operated for Pelocal but its source is managed with the
platform rather than as a separate Pelocal repo. This page maps every service to its
repo (where it has one), shows which plane it sits on, and spells out the handful of
contracts that let the four pieces work as one system.
In prose we call the services Console, Backend / Backend API, Voice fleet, and Dialler. Those friendly names are what you use day to day. Three of the services have their own canonical Bitbucket repo names —
vb-dashboard, vb-core, vb-agents — and those are what you clone, branch, and deploy. The Dialler is deployed and operated for Pelocal (it runs on the SIP/LiveKit host), but its source is managed with the platform rather than as a separate Pelocal Bitbucket repo, so it has no clone of its own. The table below is the one place the namings meet; everywhere else, the friendly names win.The repositories
The three repos live atbitbucket-pelocal:pelocal-techservice/<repo>.git.
| Repository | Service | Plane | Language / runtime | Package manager | What it owns |
|---|---|---|---|---|---|
vb-core | Backend API | Control | Python 3.12 · FastAPI | uv | Auth, bots, campaigns, system settings, per-call runtime config, durable call records, CRM push, API keys, recordings access, fleet selection |
vb-dashboard | Console | Operator surface | React 19 · Vite 8 (SPA) | npm | The operator dashboard: bot builder, campaign builder, call logs, reports, settings, knowledge bases |
vb-agents | Voice fleet | Runtime / media | Python 3.12 · FastAPI · Pipecat 1.3.0 | uv | Live call workers, transport adapters, the speech pipeline, recording upload, post-call packaging, result delivery |
| (no separate Pelocal repo) | Dialler | Runtime / execution | Python 3.12 · asyncio worker | uv | Campaign leases, predictive pacing, retry scheduling, outbound SIP dialing, answering-machine screening, attaching answered calls to the fleet |
The Dialler is deployed and run for Pelocal — it lives on the SIP/LiveKit host as the
voxdialler service — but its source is not a separate Pelocal Bitbucket repo; it is managed with the platform. There is therefore no Dialler clone URL. Everything operational about it (the systemd unit, its run command, the one-instance-per-database rule, its health port) is documented on the relevant DevOps pages.Repo → service → plane
Control plane vs runtime plane
The defining rule of the platform is a clean split between the control plane, which owns durable business state, and the runtime plane, which runs the actual calls and holds no long-lived state.Control plane — the source of truth
vb-core (Backend API) plus its data layer — MongoDB, Redis, the vector database, and object storage — hold everything durable: bots, campaigns, system settings, and every call record. vb-dashboard (Console) is the operator’s window onto that truth. If a piece of state must survive a restart, it lives here.Runtime plane — disposable muscle
vb-agents (Voice fleet) and the Dialler do the heavy real-time work but keep no durable state. They re-fetch everything they need from the control plane at the start of each call, which is why you can scale them out, restart them, or replace a host freely — and why a crashed fleet worker costs you exactly one call.The contracts between services
Four narrow contracts connect the services. Everything else is internal. If you understand these four, you understand how a call gets configured, run, recorded, and recorded back.Backend serves per-call runtime config — the fleet fetches it
At the start of every call, the Voice fleet calls the Backend’s config endpoint and gets back the complete picture for that bot: prompts, voice settings, tools, and any CRM data for this contact. The fleet stores nothing between calls — this fetch is how a stateless worker becomes “the right bot” for the next 90 seconds.The endpoint is
GET /api/v1/config on the Backend. The fleet (vb-agents) knows where to find it via VOXBRIDGE_CONFIG_URL in its environment (for example http://localhost:8080/api/v1/config when the Backend is co-located).The fleet posts results back to the Backend
When the call ends, the fleet hands the Backend a complete record — transcript, post-call analysis, quality-control findings, a disposition, and the recording reference. The Backend stores it as the durable call record and can push it onward to a CRM. The fleet’s job is finished the moment the result is delivered.
The Dialler shares the SAME MongoDB database as the Backend
The Dialler and the Backend point at the same MongoDB database (
MONGODB_DB=voxbridge in both). The Dialler reads running campaigns and leases call records directly from that shared database — there is no separate dialler API. The campaign records the Console writes through the Backend are the same records the Dialler paces and dials.The Dialler attaches answered calls to the fleet via POST /attach
The Dialler places outbound SIP calls through LiveKit and, on answer, hands the live call to a free fleet worker with
POST /attach. From that point the worker drives the conversation exactly as it would an inbound call — same pipeline, same config fetch, same post-call path. The Dialler authenticates the attach with a shared secret (VOXCORE_SECRET) and finds workers from its configured fleet list (FLEET_URLS).The Console (
vb-dashboard) has only one upstream: the Backend. It talks to nothing else — not the fleet, not the dialler, not the database. The Backend’s base URL is baked into the build at build time via VITE_API_URL. Every operator action, every list, every save goes through that one address.Contract summary
| Contract | From → To | Mechanism | Notes |
|---|---|---|---|
| Runtime config | Voice fleet → Backend | GET /api/v1/config (fleet fetches per call) | Located via VOXBRIDGE_CONFIG_URL |
| Call results | Voice fleet → Backend | Fleet posts the finished record back | Backend stores it and may push to a CRM |
| Shared campaign state | Dialler ↔ Backend | Same MongoDB database (MONGODB_DB=voxbridge) | No dialler API; one dialler per database |
| Attach answered call | Dialler → Voice fleet | POST /attach (authenticated with VOXCORE_SECRET) | Fleet workers found via FLEET_URLS |
| Operator actions | Console → Backend | HTTPS to VITE_API_URL | Console’s only upstream |
Where each repo runs
The repository boundaries line up with the deployment topology. A small deployment co-locates roles; a larger one spreads them across hosts.- API / App host
- Fleet host(s)
- SIP / LiveKit host
vb-core (Backend, uvicorn on :8080) and the built static output of vb-dashboard (Console, served by nginx). Small deployments also co-locate MongoDB and Redis here.Package managers at a glance
The three Python repos all useuv — never pip. The Console uses npm.
Where to go next
System architecture
The end-to-end picture: the four services, the data layer, the telephony plane, and the life of a single call.
Run it locally
Prerequisites, cloning the repos, and running the whole stack on your own machine.
Deploy it
The Bitbucket → Jenkins pipeline, host deployment, configuration, and the operations runbook.
