diff --git a/README.md b/README.md
index ca39341..0d6f9e9 100644
--- a/README.md
+++ b/README.md
@@ -1,108 +1,72 @@
-
-
-
-
# CommandDesk
-**Helpdesk agent** (port 8080):
-
-[](https://github.com/OneByJorah/CommandDesk/releases)
-[](https://pypi.org/project/commanddesk/)
-[](https://www.docker.com/)
-[](https://www.python.org/downloads/)
-[](https://opensource.org/licenses/MIT)
+> Self-hosted AI helpdesk agent that ingests email, chat, WhatsApp, and tickets into one queue, answers from your knowledge base with a local LLM, and tracks the per-ticket AI cost in real time.
-
+[](https://github.com/OneByJorah/CommandDesk)
+[](https://github.com/OneByJorah/CommandDesk)
+[](https://github.com/OneByJorah/CommandDesk/stargazers)
+[](https://github.com/OneByJorah/CommandDesk/commits)
+[](https://github.com/OneByJorah/CommandDesk/actions/workflows/ci.yml)
-
+
## What This Is
-Self-hosted help desk and IT ticketing system — multi-user, knowledge base, SLA tracking, and customer portal with Docker Compose deployment.
-
-Built for operators who want a self-hosted, Docker-deployed solution they control.
+Helpdesk AI is usually a paid SaaS add-on that ships your ticket data off-premises. CommandDesk runs the whole pipeline locally: it ingests email and chat into a unified queue, answers from your own knowledge base using a local llama.cpp model (or the OpenAI API), and tracks the AI cost of every ticket. Humans can take over any conversation at any point, and n8n workflows handle routing, escalation, and satisfaction surveys.
## Quick Start
-### pip
-
-```bash
-pip install commanddesk
-```
-
-### Docker (recommended)
-
```bash
git clone https://github.com/OneByJorah/CommandDesk.git
cd CommandDesk
+cp .env.example .env # configure AI + email settings
docker compose up -d
```
-### From Source
+| Service | URL |
+|---|---|
+| Dashboard (nginx) | http://localhost/dashboard/ |
+| Widget preview | http://localhost:8484 |
+| Agent API | http://localhost:8080 |
+| WhatsApp webhook | http://localhost:9090 |
-```bash
-git clone https://github.com/OneByJorah/CommandDesk.git
-cd CommandDesk
-pip install -r requirements.txt
-python3 app.py
-```
+## Features
-## Install
+- Multi-platform queue: email, web widget, WhatsApp, osTicket, Freshdesk, and Zammad.
+- AI responses via local llama.cpp or OpenAI GPT with context-aware replies.
+- ChromaDB vector-search knowledge base over your own documentation.
+- IMAP email-to-ticket ingestion.
+- SLA definitions with automatic escalation on breach.
+- Real-time AI cost tracking per ticket, per agent, per session.
+- Per-session rate limiting with audit logging.
+- n8n workflow automation for routing, escalation, surveys, and daily digests.
+- Admin dashboard with live queue, metrics, audit log, and service health.
-### pip
+## Architecture
-```bash
-pip install commanddesk
```
-
-### Docker
-
-```bash
-git clone https://github.com/OneByJorah/CommandDesk.git
-cd CommandDesk
-docker compose up -d
-```
-
-### From Source
-
-```bash
-git clone https://github.com/OneByJorah/CommandDesk.git
-cd CommandDesk
-pip install -r requirements.txt
-python3 app.py
+ User (WhatsApp / Web Widget / Email / API / Portal)
+ │
+ Helpdesk Agent (FastAPI :8080)
+ Session Mgmt · Rate Limiting · Routing
+ │ │ │
+ ┌──────┴───┐ ┌───┴──────┐ ┌─────┴────────────┐
+ │ LLM Core │ │ Context │ │ Ticket Platforms │
+ │llama.cpp │ │ChromaDB │ │osTicket·Freshdesk│
+ │ / OpenAI │ │· SearXNG │ │· Zammad · Email │
+ └──────────┘ └──────────┘ └──────────────────┘
+ │ │
+ Admin Dashboard n8n Workflows
+ PostgreSQL·Redis Escalation·Surveys
```
-## Features
-
-- **Self-hosted** — no cloud dependencies, run on your own hardware
-- **Docker Compose** — full stack deployment with one command
-- **pip package** — install via PyPI
-- **Dark theme** — operational, clean UI
-
-- **Help desk ticketing** — submit, track, and resolve tickets
-- **Multi-user support** — agents, admins, customers
-- **Knowledge base** — searchable articles and FAQs
-- **SLA tracking** — response time monitoring
-- **Customer portal** — self-service ticket submission
-- **Docker Compose deployment** — full stack with one command
-- **Dark theme dashboard** — operational, clean UI
-
-## Tech Stack
-
-- **Backend** — Python 3.11+, pydantic, pyyaml
-- **Deployment** — Docker Compose, pip install
-- **Configuration** — environment variables, config files
-
-## Package Badges
+## Stack
-[](https://github.com/OneByJorah/CommandDesk/releases)
-[](https://pypi.org/project/commanddesk/)
-[](https://www.docker.com/)
-[](https://opensource.org/licenses/MIT)
+Python 3.10+ · FastAPI · llama.cpp / OpenAI · ChromaDB · PostgreSQL · Redis · SearXNG · n8n · Docker Compose · HTML/CSS.
## Contributing
-Contributions are welcome. [Open an issue](https://github.com/OneByJorah/CommandDesk/issues) to report a bug or request a feature.
+See [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). [Open an issue](https://github.com/OneByJorah/CommandDesk/issues).
## License
diff --git a/docker-compose.yml b/docker-compose.yml
index a22bcec..8ac5716 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -8,7 +8,7 @@ services:
image: ghcr.io/ggerganov/llama.cpp:server
container_name: helpdesk-llama
ports:
- - ":8081:8081"
+ - "127.0.0.1:8081:8081"
volumes:
- ./models:/models:ro
environment:
@@ -17,7 +17,7 @@ services:
- LLAMA_ARG_CTX_SIZE=65536
- LLAMA_ARG_N_BATCH=512
- LLAMA_ARG_THREADS=6
- - LLAMA_ARG_HOST=
+ - LLAMA_ARG_HOST=127.0.0.1
- LLAMA_ARG_N_GL=0
deploy:
resources:
@@ -25,7 +25,7 @@ services:
memory: 7G
restart: unless-stopped
healthcheck:
- test: ["CMD", "curl", "-f", "http://:8081/health"]
+ test: ["CMD", "curl", "-f", "http://127.0.0.1:8081/health"]
interval: 30s
timeout: 10s
retries: 5
@@ -42,7 +42,7 @@ services:
dockerfile: Dockerfile
container_name: helpdesk-agent
ports:
- - ":8080:8080"
+ - "127.0.0.1:8080:8080"
volumes:
- ./config:/app/config:ro
- ./ticket_platforms:/app/ticket_platforms:ro
@@ -90,7 +90,7 @@ services:
dockerfile: Dockerfile
container_name: helpdesk-admin-agent
ports:
- - ":8082:8082"
+ - "127.0.0.1:8082:8082"
volumes:
- ./config:/app/config:ro
- ./ticket_platforms:/app/ticket_platforms:ro
@@ -132,11 +132,11 @@ services:
image: chromadb/chroma:0.5.23
container_name: helpdesk-chroma
ports:
- - ":8000:8000"
+ - "127.0.0.1:8000:8000"
volumes:
- chroma-data:/chroma/chroma
environment:
- - CHROMA_SERVER_HOST=
+ - CHROMA_SERVER_HOST=127.0.0.1
- CHROMA_SERVER_PORT=8000
- PERSIST_DIRECTORY=/chroma/chroma
- ALLOW_RESET=true
@@ -147,7 +147,7 @@ services:
memory: 2G
restart: unless-stopped
healthcheck:
- test: ["CMD", "curl", "-sf", "http://:8000/api/v1/heartbeat"]
+ test: ["CMD", "curl", "-sf", "http://127.0.0.1:8000/api/v1/heartbeat"]
interval: 30s
timeout: 10s
retries: 3
@@ -161,20 +161,20 @@ services:
image: searxng/searxng:latest
container_name: helpdesk-searxng
ports:
- - ":8888:8080"
+ - "127.0.0.1:8888:8080"
volumes:
- searxng-data:/etc/searxng
- ./config/searxng-settings.yml:/etc/searxng/settings.yml:ro
environment:
- SEARXNG_BASE_URL=http://localhost:8888/
- - SEARXNG_BIND_ADDRESS=
+ - SEARXNG_BIND_ADDRESS=127.0.0.1
deploy:
resources:
limits:
memory: 1G
restart: unless-stopped
healthcheck:
- test: ["CMD", "curl", "-sf", "http://:8888/search?q=test&format=json"]
+ test: ["CMD", "curl", "-sf", "http://127.0.0.1:8888/search?q=test&format=json"]
interval: 60s
timeout: 10s
retries: 3
@@ -188,7 +188,7 @@ services:
image: n8nio/n8n:latest
container_name: helpdesk-n8n
ports:
- - ":5678:5678"
+ - "127.0.0.1:5678:5678"
volumes:
- n8n-data:/home/node/.n8n
- ./workflows:/home/node/.n8n/workflows:ro
@@ -207,7 +207,7 @@ services:
memory: 1G
restart: unless-stopped
healthcheck:
- test: ["CMD", "curl", "-sf", "http://:5678/healthz"]
+ test: ["CMD", "curl", "-sf", "http://127.0.0.1:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
@@ -221,7 +221,7 @@ services:
image: postgres:16-alpine
container_name: helpdesk-postgres
ports:
- - ":5432:5432"
+ - "127.0.0.1:5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql:ro
@@ -250,7 +250,7 @@ services:
image: redis:7-alpine
container_name: helpdesk-redis
ports:
- - ":6379:6379"
+ - "127.0.0.1:6379:6379"
volumes:
- redis-data:/data
command: >
@@ -339,82 +339,82 @@ services:
# ═══════════════════════════════════════════════════
# WhatsApp Webhook Receiver
# ═══════════════════════════════════════════════════
-whatsapp-webhook:
- build:
- context: .
- dockerfile: Dockerfile.whatsapp
- container_name: helpdesk-whatsapp
- ports:
- - ":9090:9090"
- - ":8383:8383"
- volumes:
- - ./config:/app/config:ro
- - ./scripts:/app/scripts:ro
- environment:
- - WHATSAPP_TOKEN=${WHATSAPP_TOKEN}
- - WHATSAPP_PHONE_NUMBER_ID=${WHATSAPP_PHONE_NUMBER_ID}
- - WHATSAPP_WEBHOOK_SECRET=${WHATSAPP_WEBHOOK_SECRET:-change_me}
- - ADMIN_PHONE_NUMBER=${ADMIN_PHONE_NUMBER}
- - HELPDESK_AGENT_URL=http://helpdesk-agent:8080
- - REDIS_URL=redis://:${REDIS_PASSWORD:-redis_pass}@redis:6379/0
- - WHATSAPP_RATE_LIMIT_PER_MINUTE=${WHATSAPP_RATE_LIMIT_PER_MINUTE:-10}
- depends_on:
- helpdesk-agent:
- condition: service_started
- redis:
- condition: service_healthy
- deploy:
- resources:
- limits:
- memory: 500M
- restart: unless-stopped
- networks:
- - helpdesk-net
+ whatsapp-webhook:
+ build:
+ context: .
+ dockerfile: Dockerfile.whatsapp
+ container_name: helpdesk-whatsapp
+ ports:
+ - "127.0.0.1:9090:9090"
+ - "127.0.0.1:8383:8383"
+ volumes:
+ - ./config:/app/config:ro
+ - ./scripts:/app/scripts:ro
+ environment:
+ - WHATSAPP_TOKEN=${WHATSAPP_TOKEN}
+ - WHATSAPP_PHONE_NUMBER_ID=${WHATSAPP_PHONE_NUMBER_ID}
+ - WHATSAPP_WEBHOOK_SECRET=${WHATSAPP_WEBHOOK_SECRET:-change_me}
+ - ADMIN_PHONE_NUMBER=${ADMIN_PHONE_NUMBER}
+ - HELPDESK_AGENT_URL=http://helpdesk-agent:8080
+ - REDIS_URL=redis://:${REDIS_PASSWORD:-redis_pass}@redis:6379/0
+ - WHATSAPP_RATE_LIMIT_PER_MINUTE=${WHATSAPP_RATE_LIMIT_PER_MINUTE:-10}
+ depends_on:
+ helpdesk-agent:
+ condition: service_started
+ redis:
+ condition: service_healthy
+ deploy:
+ resources:
+ limits:
+ memory: 500M
+ restart: unless-stopped
+ networks:
+ - helpdesk-net
# ═══════════════════════════════════════════════════
# Health Monitor
# ═══════════════════════════════════════════════════
-health-monitor:
- build:
- context: .
- dockerfile: Dockerfile
- container_name: helpdesk-health
- volumes:
- - ./scripts:/app/scripts:ro
- - ./config:/app/config:ro
- environment:
- - REDIS_URL=redis://:${REDIS_PASSWORD:-redis_pass}@redis:6379/0
- depends_on:
- redis:
- condition: service_healthy
- deploy:
- resources:
- limits:
- memory: 200M
- restart: unless-stopped
- networks:
- - helpdesk-net
+ health-monitor:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ container_name: helpdesk-health
+ volumes:
+ - ./scripts:/app/scripts:ro
+ - ./config:/app/config:ro
+ environment:
+ - REDIS_URL=redis://:${REDIS_PASSWORD:-redis_pass}@redis:6379/0
+ depends_on:
+ redis:
+ condition: service_healthy
+ deploy:
+ resources:
+ limits:
+ memory: 200M
+ restart: unless-stopped
+ networks:
+ - helpdesk-net
# ═══════════════════════════════════════════════════
# Tools UI (Widget + Admin Panel)
# ═══════════════════════════════════════════════════
-tools-ui:
- build:
- context: tools-ui
- dockerfile: Dockerfile
- container_name: helpdesk-tools-ui
- ports:
- - ":8484:8484"
- depends_on:
- - helpdesk-agent
- - admin-agent
- deploy:
- resources:
- limits:
- memory: 200M
- restart: unless-stopped
- networks:
- - helpdesk-net
+ tools-ui:
+ build:
+ context: tools-ui
+ dockerfile: Dockerfile
+ container_name: helpdesk-tools-ui
+ ports:
+ - "127.0.0.1:8484:8484"
+ depends_on:
+ - helpdesk-agent
+ - admin-agent
+ deploy:
+ resources:
+ limits:
+ memory: 200M
+ restart: unless-stopped
+ networks:
+ - helpdesk-net
# ═══════════════════════════════════════════════════
# Networks
@@ -424,7 +424,7 @@ networks:
driver: bridge
ipam:
config:
- - subnet: /16
+ - subnet: 127.0.0.1/16
# ═══════════════════════════════════════════════════
# Volumes