# sorrowsfr/spx-voice architecture

> Architecture diagram of the GitHub repository sorrowsfr/spx-voice, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/sorrowsfr/spx-voice
- Repository: https://github.com/sorrowsfr/spx-voice

## Overview

SPX Voice lets an operator build and publish a voice-agent workflow, configure models and telephony, then test it in-browser or deploy it to calls. The dashboard edits workflows and calls the FastAPI backend; backend execution creates an audio pipeline that runs workflow nodes and connects to realtime or traditional speech services. Telephony, campaigns, knowledge bases, recordings, and reporting extend that core. Paths and links for runtime components reflect the tree, README, and sampled excerpts; unsampled subsystem wiring is shown only where documented at a high level.

Main entry points: [`api/services/pipecat/run_pipeline.py`](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/run_pipeline.py) (Run orchestration), [`api/routes/workflow.py`](https://github.com/sorrowsfr/spx-voice/blob/main/api/routes/workflow.py) (FastAPI routes), [`api/services/workflow/pipecat_engine.py`](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/pipecat_engine.py) (Workflow engine), [`ui/src/app/workflow/[workflowId]/page.tsx`](https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/page.tsx) (Dashboard)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_authoring["Agent authoring"]
  node_dashboard["Dashboard<br/>[page.tsx]"]
  node_workflow_editor["Workflow editor<br/>[RenderWorkflow.tsx]"]
  node_workflow_store["Workflow state<br/>[workflowStore.ts]"]
end

subgraph group_backend["Backend services"]
  node_api["FastAPI routes<br/>[workflow.py]"]
  node_auth["Authentication<br/>[depends.py]"]
  node_workflow_graph["Workflow graph<br/>[workflow_graph.py]"]
  node_configuration["Model configuration<br/>[resolve.py]"]
  node_campaigns["Campaign dispatch"]
  node_knowledge["Knowledge retrieval<br/>[knowledge_base.py]"]
end

subgraph group_runtime["Conversation runtime"]
  node_run_pipeline["Run orchestration<br/>[run_pipeline.py]"]
  node_engine["Workflow engine<br/>[pipecat_engine.py]"]
  node_pipeline["Audio pipeline"]
end

subgraph group_integrations["External integrations"]
  node_telephony["Telephony providers<br/>[registry.py]"]
  node_livekit["LiveKit runtime<br/>[worker.py]"]
  node_model_services["Speech and model services<br/>[service_factory.py]"]
end

subgraph group_state["Persistence and jobs"]
  node_db[("Database clients<br/>[db_client.py]")]
  node_filesystem[("Object storage<br/>[storage.py]")]
  node_worker["Background tasks<br/>[arq.py]"]
end

node_operator(("Operator"))
node_caller(("Caller / browser tester"))
node_providers{{"Model providers"}}
node_phone_network{{"Telephony network"}}

node_operator -->|"uses"| node_dashboard
node_dashboard -->|"opens editor"| node_workflow_editor
node_workflow_editor -->|"updates state"| node_workflow_store
node_dashboard -->|"API requests"| node_api
node_api -->|"checks access"| node_auth
node_api -->|"reads and writes"| node_db
node_api -->|"loads workflow"| node_workflow_graph
node_api -->|"starts run"| node_run_pipeline
node_campaigns -->|"dispatches run"| node_run_pipeline
node_run_pipeline -->|"loads run data"| node_db
node_run_pipeline -->|"resolves config"| node_configuration
node_run_pipeline -->|"uses graph"| node_workflow_graph
node_run_pipeline -->|"builds pipeline"| node_pipeline
node_run_pipeline -->|"creates engine"| node_engine
node_pipeline -->|"dispatches frames"| node_engine
node_engine -->|"retrieves chunks"| node_knowledge
node_engine -->|"updates run state"| node_db
node_configuration -->|"selects services"| node_model_services
node_model_services -->|"calls models"| node_providers
node_run_pipeline -->|"starts runtime"| node_livekit
node_telephony -->|"handles calls"| node_phone_network
node_phone_network -->|"sends callbacks"| node_telephony
node_caller -->|"places call"| node_telephony
node_caller -->|"starts browser test"| node_run_pipeline
node_api -.->|"stores media"| node_filesystem
node_api -.->|"queues tasks"| node_worker

click node_dashboard "https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/page.tsx"
click node_workflow_editor "https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/RenderWorkflow.tsx"
click node_workflow_store "https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/stores/workflowStore.ts"
click node_api "https://github.com/sorrowsfr/spx-voice/blob/main/api/routes/workflow.py"
click node_auth "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/auth/depends.py"
click node_workflow_graph "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/workflow_graph.py"
click node_db "https://github.com/sorrowsfr/spx-voice/blob/main/api/db/db_client.py"
click node_run_pipeline "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/run_pipeline.py"
click node_engine "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/pipecat_engine.py"
click node_pipeline "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/pipeline_builder.py"
click node_configuration "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/configuration/resolve.py"
click node_telephony "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/telephony/registry.py"
click node_livekit "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/livekit/worker.py"
click node_model_services "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/service_factory.py"
click node_campaigns "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/campaign/campaign_orchestrator.py"
click node_knowledge "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/tools/knowledge_base.py"
click node_filesystem "https://github.com/sorrowsfr/spx-voice/blob/main/api/services/storage.py"
click node_worker "https://github.com/sorrowsfr/spx-voice/blob/main/api/tasks/arq.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_dashboard,node_workflow_editor,node_workflow_store,node_caller toneBlue
class node_api,node_auth,node_workflow_graph,node_configuration,node_campaigns,node_knowledge toneAmber
class node_run_pipeline,node_engine,node_pipeline toneMint
class node_telephony,node_livekit,node_model_services toneRose
class node_db,node_filesystem,node_worker,node_operator,node_providers,node_phone_network toneIndigo
```

## Components

### Agent authoring

- [Dashboard](https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/page.tsx): `ui/src/app/workflow/[workflowId]/page.tsx`
- [Workflow editor](https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/RenderWorkflow.tsx): `ui/src/app/workflow/[workflowId]/RenderWorkflow.tsx`
- [Workflow state](https://github.com/sorrowsfr/spx-voice/blob/main/ui/src/app/workflow/%5BworkflowId%5D/stores/workflowStore.ts): `ui/src/app/workflow/[workflowId]/stores/workflowStore.ts`

### Backend services

- [FastAPI routes](https://github.com/sorrowsfr/spx-voice/blob/main/api/routes/workflow.py): `api/routes/workflow.py`
- [Authentication](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/auth/depends.py): `api/services/auth/depends.py`
- [Workflow graph](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/workflow_graph.py): `api/services/workflow/workflow_graph.py`
- [Model configuration](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/configuration/resolve.py): `api/services/configuration/resolve.py`
- [Campaign dispatch](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/campaign/campaign_orchestrator.py): `api/services/campaign/campaign_orchestrator.py`
- [Knowledge retrieval](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/tools/knowledge_base.py): `api/services/workflow/tools/knowledge_base.py`

### Conversation runtime

- [Run orchestration](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/run_pipeline.py): `api/services/pipecat/run_pipeline.py`
- [Workflow engine](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/workflow/pipecat_engine.py): `api/services/workflow/pipecat_engine.py`
- [Audio pipeline](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/pipeline_builder.py): `api/services/pipecat/pipeline_builder.py`

### External integrations

- [Telephony providers](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/telephony/registry.py): `api/services/telephony/registry.py`
- [LiveKit runtime](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/livekit/worker.py): `api/services/livekit/worker.py`
- [Speech and model services](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/pipecat/service_factory.py): `api/services/pipecat/service_factory.py`

### Persistence and jobs

- [Database clients](https://github.com/sorrowsfr/spx-voice/blob/main/api/db/db_client.py): `api/db/db_client.py`
- [Object storage](https://github.com/sorrowsfr/spx-voice/blob/main/api/services/storage.py): `api/services/storage.py`
- [Background tasks](https://github.com/sorrowsfr/spx-voice/blob/main/api/tasks/arq.py): `api/tasks/arq.py`

### Other components

- **Operator**
- **Caller / browser tester**
- **Model providers**
- **Telephony network**

## Connections

- Operator → Dashboard: uses
- Dashboard → Workflow editor: opens editor
- Workflow editor → Workflow state: updates state
- Dashboard → FastAPI routes: API requests
- FastAPI routes → Authentication: checks access
- FastAPI routes → Database clients: reads and writes
- FastAPI routes → Workflow graph: loads workflow
- FastAPI routes → Run orchestration: starts run
- Campaign dispatch → Run orchestration: dispatches run
- Run orchestration → Database clients: loads run data
- Run orchestration → Model configuration: resolves config
- Run orchestration → Workflow graph: uses graph
- Run orchestration → Audio pipeline: builds pipeline
- Run orchestration → Workflow engine: creates engine
- Audio pipeline → Workflow engine: dispatches frames
- Workflow engine → Knowledge retrieval: retrieves chunks
- Workflow engine → Database clients: updates run state
- Model configuration → Speech and model services: selects services
- Speech and model services → Model providers: calls models
- Run orchestration → LiveKit runtime: starts runtime
- Telephony providers → Telephony network: handles calls
- Telephony network → Telephony providers: sends callbacks
- Caller / browser tester → Telephony providers: places call
- Caller / browser tester → Run orchestration: starts browser test
- FastAPI routes → Object storage: stores media
- FastAPI routes → Background tasks: queues tasks
