# armistice-ml/agent24 architecture

> Architecture diagram of the GitHub repository armistice-ml/agent24, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-15). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/armistice-ml/agent24
- Repository: https://github.com/armistice-ml/agent24

## Overview

Agent24 is a multi-tenant Messenger support backend. Signed webhook events are normalized and stored with idempotency; incoming messages enqueue work for a worker, which runs an LLM agent and tools, records its reply, then sends it. A dashboard supports authenticated human handling, statistics, and SSE change signals; escalations also enqueue email notifications. The README documents these capabilities and the tenant/RLS model; links for unsampled dashboard and notification internals rely on its statements or the source index.

Main entry points: [`app/agent/orchestrator.py`](https://github.com/armistice-ml/agent24/blob/main/app/agent/orchestrator.py) (Agent orchestration), [`app/db.py`](https://github.com/armistice-ml/agent24/blob/main/app/db.py) (PostgreSQL), [`app/services/handoff.py`](https://github.com/armistice-ml/agent24/blob/main/app/services/handoff.py) (Human handoff), [`app/routers/webhooks.py`](https://github.com/armistice-ml/agent24/blob/main/app/routers/webhooks.py) (Webhook routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingress["Message ingress"]
  node_webhook["Webhook routes<br/>[webhooks.py]"]
  node_normalize["Messenger parser<br/>[messenger.py]"]
  node_ingest["Message ingestion<br/>[ingest.py]"]
end

subgraph group_agent["Agent processing"]
  node_orchestrator["Agent orchestration<br/>[orchestrator.py]"]
  node_llm["LLM client<br/>[llm.py]"]
  node_tools["Agent tools<br/>[tools.py]"]
  node_prompt["Agent prompt<br/>[prompt.py]"]
  node_messenger_sender["Messenger sender<br/>[sender.py]"]
end

subgraph group_human["Dashboard and handoff"]
  node_handoff["Human handoff<br/>[handoff.py]"]
  node_dashboard["Dashboard API<br/>[dashboard.py]"]
  node_auth["Session authentication<br/>[auth.py]"]
  node_events_api["SSE endpoint<br/>[events.py]"]
end

subgraph group_platform["Runtime platform"]
  node_jobs["Job queue<br/>[jobs.py]"]
  node_worker["Worker<br/>[worker.py]"]
  node_event_service["Event hub<br/>[events.py]"]
  node_email_jobs["Escalation email<br/>[notifications.py]"]
  node_email_sender["Email transport<br/>[email.py]"]
  node_database[("PostgreSQL<br/>[db.py]")]
  node_api["FastAPI app<br/>[main.py]"]
end

node_meta(("Messenger"))
node_dashboard_user(("Dashboard user"))

node_meta -->|"posts events"| node_webhook
node_webhook -->|"parses payload"| node_normalize
node_webhook -->|"records messages"| node_ingest
node_webhook -->|"registers echoes"| node_handoff
node_ingest -->|"stores messages"| node_database
node_ingest -->|"enqueues replies"| node_jobs
node_ingest -->|"emits change"| node_event_service
node_worker -->|"claims jobs"| node_jobs
node_worker -->|"handles replies"| node_orchestrator
node_worker -->|"handles notices"| node_email_jobs
node_orchestrator -->|"requests completion"| node_llm
node_orchestrator -->|"executes tool calls"| node_tools
node_orchestrator -->|"builds prompt"| node_prompt
node_orchestrator -->|"sends reply"| node_messenger_sender
node_orchestrator -->|"loads and records"| node_database
node_tools -->|"requests escalation"| node_handoff
node_handoff -->|"queues email"| node_jobs
node_handoff -->|"emits changes"| node_event_service
node_dashboard_user -->|"uses API"| node_api
node_api -->|"routes requests"| node_dashboard
node_api -->|"routes sessions"| node_auth
node_api -->|"routes SSE"| node_events_api
node_dashboard -->|"checks permissions"| node_auth
node_dashboard -->|"performs human actions"| node_handoff
node_dashboard -->|"reads dashboard data"| node_database
node_auth -->|"reads sessions"| node_database
node_events_api -->|"subscribes to events"| node_event_service
node_event_service -->|"stores and listens"| node_database
node_email_jobs -->|"sends escalation email"| node_email_sender
node_email_jobs -->|"loads recipients"| node_database

click node_webhook "https://github.com/armistice-ml/agent24/blob/main/app/routers/webhooks.py"
click node_normalize "https://github.com/armistice-ml/agent24/blob/main/app/channels/messenger.py"
click node_ingest "https://github.com/armistice-ml/agent24/blob/main/app/services/ingest.py"
click node_jobs "https://github.com/armistice-ml/agent24/blob/main/app/services/jobs.py"
click node_worker "https://github.com/armistice-ml/agent24/blob/main/app/worker.py"
click node_orchestrator "https://github.com/armistice-ml/agent24/blob/main/app/agent/orchestrator.py"
click node_llm "https://github.com/armistice-ml/agent24/blob/main/app/agent/llm.py"
click node_tools "https://github.com/armistice-ml/agent24/blob/main/app/agent/tools.py"
click node_prompt "https://github.com/armistice-ml/agent24/blob/main/app/agent/prompt.py"
click node_messenger_sender "https://github.com/armistice-ml/agent24/blob/main/app/channels/sender.py"
click node_handoff "https://github.com/armistice-ml/agent24/blob/main/app/services/handoff.py"
click node_dashboard "https://github.com/armistice-ml/agent24/blob/main/app/routers/dashboard.py"
click node_auth "https://github.com/armistice-ml/agent24/blob/main/app/auth.py"
click node_events_api "https://github.com/armistice-ml/agent24/blob/main/app/routers/events.py"
click node_event_service "https://github.com/armistice-ml/agent24/blob/main/app/services/events.py"
click node_email_jobs "https://github.com/armistice-ml/agent24/blob/main/app/services/notifications.py"
click node_email_sender "https://github.com/armistice-ml/agent24/blob/main/app/notify/email.py"
click node_database "https://github.com/armistice-ml/agent24/blob/main/app/db.py"
click node_api "https://github.com/armistice-ml/agent24/blob/main/app/main.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_webhook,node_normalize,node_ingest,node_dashboard_user toneBlue
class node_orchestrator,node_llm,node_tools,node_prompt,node_messenger_sender toneAmber
class node_handoff,node_dashboard,node_auth,node_events_api toneMint
class node_jobs,node_worker,node_event_service,node_email_jobs,node_email_sender,node_database,node_api toneRose
class node_meta toneIndigo
```

## Components

### Message ingress

- [Webhook routes](https://github.com/armistice-ml/agent24/blob/main/app/routers/webhooks.py): `app/routers/webhooks.py`
- [Messenger parser](https://github.com/armistice-ml/agent24/blob/main/app/channels/messenger.py): `app/channels/messenger.py`
- [Message ingestion](https://github.com/armistice-ml/agent24/blob/main/app/services/ingest.py): `app/services/ingest.py`

### Agent processing

- [Agent orchestration](https://github.com/armistice-ml/agent24/blob/main/app/agent/orchestrator.py): `app/agent/orchestrator.py`
- [LLM client](https://github.com/armistice-ml/agent24/blob/main/app/agent/llm.py): `app/agent/llm.py`
- [Agent tools](https://github.com/armistice-ml/agent24/blob/main/app/agent/tools.py): `app/agent/tools.py`
- [Agent prompt](https://github.com/armistice-ml/agent24/blob/main/app/agent/prompt.py): `app/agent/prompt.py`
- [Messenger sender](https://github.com/armistice-ml/agent24/blob/main/app/channels/sender.py): `app/channels/sender.py`

### Dashboard and handoff

- [Human handoff](https://github.com/armistice-ml/agent24/blob/main/app/services/handoff.py): `app/services/handoff.py`
- [Dashboard API](https://github.com/armistice-ml/agent24/blob/main/app/routers/dashboard.py): `app/routers/dashboard.py`
- [Session authentication](https://github.com/armistice-ml/agent24/blob/main/app/auth.py): `app/auth.py`
- [SSE endpoint](https://github.com/armistice-ml/agent24/blob/main/app/routers/events.py): `app/routers/events.py`

### Runtime platform

- [Job queue](https://github.com/armistice-ml/agent24/blob/main/app/services/jobs.py): `app/services/jobs.py`
- [Worker](https://github.com/armistice-ml/agent24/blob/main/app/worker.py): `app/worker.py`
- [Event hub](https://github.com/armistice-ml/agent24/blob/main/app/services/events.py): `app/services/events.py`
- [Escalation email](https://github.com/armistice-ml/agent24/blob/main/app/services/notifications.py): `app/services/notifications.py`
- [Email transport](https://github.com/armistice-ml/agent24/blob/main/app/notify/email.py): `app/notify/email.py`
- [PostgreSQL](https://github.com/armistice-ml/agent24/blob/main/app/db.py): `app/db.py`
- [FastAPI app](https://github.com/armistice-ml/agent24/blob/main/app/main.py): `app/main.py`

### Other components

- **Messenger**
- **Dashboard user**

## Connections

- Messenger → Webhook routes: posts events (evidence: `README.md`)
- Webhook routes → Messenger parser: parses payload (evidence: `app/routers/webhooks.py`)
- Webhook routes → Message ingestion: records messages (evidence: `app/routers/webhooks.py`)
- Webhook routes → Human handoff: registers echoes (evidence: `app/routers/webhooks.py`)
- Message ingestion → PostgreSQL: stores messages (evidence: `app/services/ingest.py`)
- Message ingestion → Job queue: enqueues replies (evidence: `app/services/ingest.py`)
- Message ingestion → Event hub: emits change (evidence: `app/services/ingest.py`)
- Worker → Job queue: claims jobs (evidence: `app/worker.py`)
- Worker → Agent orchestration: handles replies (evidence: `app/worker.py`)
- Worker → Escalation email: handles notices (evidence: `app/worker.py`)
- Agent orchestration → LLM client: requests completion (evidence: `app/agent/orchestrator.py`)
- Agent orchestration → Agent tools: executes tool calls (evidence: `app/agent/orchestrator.py`)
- Agent orchestration → Agent prompt: builds prompt (evidence: `app/agent/orchestrator.py`)
- Agent orchestration → Messenger sender: sends reply (evidence: `app/agent/orchestrator.py`)
- Agent orchestration → PostgreSQL: loads and records (evidence: `app/agent/orchestrator.py`)
- Agent tools → Human handoff: requests escalation (evidence: `app/agent/tools.py`)
- Human handoff → Job queue: queues email (evidence: `README.md`)
- Human handoff → Event hub: emits changes (evidence: `app/services/handoff.py`)
- Dashboard user → FastAPI app: uses API (evidence: `README.md`)
- FastAPI app → Dashboard API: routes requests (evidence: `app/main.py`)
- FastAPI app → Session authentication: routes sessions (evidence: `app/main.py`)
- FastAPI app → SSE endpoint: routes SSE (evidence: `app/main.py`)
- Dashboard API → Session authentication: checks permissions (evidence: `app/routers/dashboard.py`)
- Dashboard API → Human handoff: performs human actions (evidence: `app/routers/dashboard.py`)
- Dashboard API → PostgreSQL: reads dashboard data (evidence: `app/routers/dashboard.py`)
- Session authentication → PostgreSQL: reads sessions (evidence: `app/auth.py`)
- SSE endpoint → Event hub: subscribes to events (evidence: `app/routers/events.py`)
- Event hub → PostgreSQL: stores and listens (evidence: `app/services/events.py`)
- Escalation email → Email transport: sends escalation email (evidence: `app/services/notifications.py`)
- Escalation email → PostgreSQL: loads recipients (evidence: `app/services/notifications.py`)
