diff --git a/README.md b/README.md index ca39341..0d6f9e9 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,72 @@ -
- -![CommandDesk banner](docs/assets/banner.svg) - # CommandDesk -**Helpdesk agent** (port 8080): - -[![GitHub release](https://img.shields.io/github/v/release/OneByJorah/CommandDesk?color=4ade80&label=release&logo=github)](https://github.com/OneByJorah/CommandDesk/releases) -[![PyPI version](https://img.shields.io/pypi/v/commanddesk?color=4ade80&label=pip&logo=pypi)](https://pypi.org/project/commanddesk/) -[![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat-square&logo=docker&logoColor=white)](https://www.docker.com/) -[![Python 3.11+](https://img.shields.io/badge/Python-3.11+-3776AB?style=flat-square&logo=python&logoColor=white)](https://www.python.org/downloads/) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?color=FFB300&logo=open-source-initiative&logoColor=FFB300)](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. -
+[![License](https://img.shields.io/github/license/OneByJorah/CommandDesk?style=for-the-badge&color=FFB300&labelColor=0a0a09)](https://github.com/OneByJorah/CommandDesk) +[![Top Language](https://img.shields.io/github/languages/top/OneByJorah/CommandDesk?style=for-the-badge&color=FFB300&labelColor=0a0a09)](https://github.com/OneByJorah/CommandDesk) +[![Stars](https://img.shields.io/github/stars/OneByJorah/CommandDesk?style=for-the-badge&color=FFB300&labelColor=0a0a09)](https://github.com/OneByJorah/CommandDesk/stargazers) +[![Last Commit](https://img.shields.io/github/last-commit/OneByJorah/CommandDesk?style=for-the-badge&color=FFB300&labelColor=0a0a09)](https://github.com/OneByJorah/CommandDesk/commits) +[![CI](https://img.shields.io/github/actions/workflow/status/OneByJorah/CommandDesk/ci.yml?style=for-the-badge&color=FFB300&labelColor=0a0a09&label=ci)](https://github.com/OneByJorah/CommandDesk/actions/workflows/ci.yml) -![CommandDesk screenshot](docs/assets/screenshot.png) +![CommandDesk admin dashboard](dashboard-realistic.png) ## 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 -[![GitHub release](https://img.shields.io/github/v/release/OneByJorah/CommandDesk?color=4ade80&label=release&logo=github)](https://github.com/OneByJorah/CommandDesk/releases) -[![PyPI version](https://img.shields.io/pypi/v/commanddesk?color=4ade80&label=pip&logo=pypi)](https://pypi.org/project/commanddesk/) -[![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat-square&logo=docker&logoColor=white)](https://www.docker.com/) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?color=FFB300&logo=open-source-initiative&logoColor=FFB300)](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