An enterprise AI workspace for model routing, multimodal chat, files, tools, billing, identity, and operations.
English | 简体中文
DEEIX Chat gives teams a unified workspace for working with multiple AI models and providers. It combines multimodal chat, model routing, file and RAG workflows, MCP tools, usage billing, identity, audit logs, and operational controls in one product.
The architecture is designed for simple deployment, efficient static delivery, and a predictable Go runtime footprint. The admin console centralizes upstream channels, platform model names, routing priority, pricing, subscriptions, users, and security policies, while the conversation workspace keeps the user experience stable and focused.
| Area | Capabilities |
|---|---|
| Conversations | Multi-branch chat, streaming, retries, edits, feedback, sharing, cloned shared conversations, rich markdown rendering, file cards, model metadata, usage details, and execution traces. |
| Media generation | Dedicated image generation and image edit flow with task-aware routing, OpenAI Images-compatible protocols, generated file storage, preview, download, and run history separated from text chat. |
| Model control plane | Platform model catalog, upstream channels, real upstream models, route bindings, priority and weight routing, model capability JSON, display ordering, vendor mapping, automatic icons, and circuit breaker state. |
| Provider protocols | OpenAI Responses and Chat Completions, OpenAI Images, Anthropic Messages, Google/Gemini Generate Content, xAI Responses, OpenRouter defaults, and custom OpenAI-compatible routes. |
| Request governance | Protocol-aware request assembly, user option allowlists and denylists, system-protected fields, previous-response continuation where supported, and context snapshots for review. |
| Files and RAG | File upload, preview, download, deletion, quota control, MIME detection, text extraction, OCR, full-context injection, image context, chunking, embeddings, and semantic retrieval. |
| Memory and context | Message-window truncation, token-budget truncation, context compression, conversation memory, long-term user memory, RAG evidence records, and prompt trace inspection. |
| Tools | Admin-managed MCP servers, tool discovery, per-tool enablement, user-side tool selection, execution limits, retries, trace rendering, and tool result handling. |
| Billing and payments | Subscription plans, top-ups, balances, token/call/duration/tiered model pricing, free models, prepaid thresholds, usage ledgers, billing snapshots, Stripe Checkout, EPay, and webhook validation. |
| Identity and security | Local login, registration, session management, HttpOnly refresh cookies, 2FA/TOTP, recovery codes, trusted devices, SSO/OIDC/OAuth providers, contact verification, timezone, and locale. |
| Administration | Users, roles, auth providers, upstreams, platform models, route bindings, model pricing, subscriptions, balances, usage logs, audit logs, auth events, system events, and runtime settings. |
| Operations | Efficient static delivery, predictable Go runtime footprint, Docker builds, single-runtime frontend/API serving, Swagger docs, structured logs, request IDs, Redis caching, PostgreSQL pgvector, optional GeoIP, optional OpenTelemetry, and S3-compatible storage. |
frontend/ Next.js App Router web application
backend/ Go API service, domain/application layers, infra adapters, Swagger docs
docker/ Optional document extraction and OCR services
Backend code follows a layered structure:
cmd -> internal/cli -> internal/app
transport/http -> application -> repository interfaces -> infra implementations
domain -> shared domain types and constants
pkg -> dependency-free technical helpers
The database uses domain-prefixed tables for identity, LLM routing, billing, conversations, files, RAG, settings, tools, audit logs, and system events. Financial records, audit trails, system events, and high-growth vector data are kept as separate sources of truth.
- Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS, shadcn/ui-style components, Radix/Base UI, Streamdown, KaTeX, Mermaid, Recharts, Motion
- Backend: Go 1.25, Gin, Gorm, PostgreSQL, pgvector, Redis, Swagger, OpenTelemetry, Zap
- Storage: local filesystem or S3-compatible object storage
- File processing: built-in extractors, Apache Tika, Docling, RapidOCR, Tesseract OCR, Paddle OCR, cloud OCR adapters, MinerU, and LLM OCR fallback
- Tooling: MCP Streamable HTTP JSON-RPC
- Runtime: Docker, Docker Compose, PostgreSQL, Redis
cp config.example.yaml config.yaml
cd backend
make runcd frontend
pnpm install
cp .env.example .env.local
pnpm devURLs: frontend http://localhost:3000, API http://localhost:8080, Swagger http://localhost:8080/swagger/index.html.
The frontend uses NEXT_PUBLIC_API_BASE_URL for API requests. For local development, set it in frontend/.env.local:
NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8080If omitted, local development defaults to localhost:8080; same-origin deployments use the current origin.
Priority: environment variables > config.yaml > built-in defaults.
APP_ENV accepts dev/development and prod/production, normalizes them to dev or prod, and defaults to prod when omitted. Use dev only for local development. Public production deployments should keep APP_ENV=prod or APP_ENV=production and use production secrets.
Starts only the app container. PostgreSQL and Redis must be provided externally. Use this when database and cache services already exist.
cp config.docker.example.yaml config.yaml
# Edit database.postgres.dsn and database.redis.*.
docker compose up -dStarts app, postgres, and redis. Use this for local evaluation, development smoke tests, or single-machine deployments without external services.
cp config.docker.example.yaml config.yaml
docker compose -f docker-compose.full.yml up -dThe default application image is ghcr.io/deeix-ai/deeix-chat:latest. Override it with DEEIX_CHAT_IMAGE when testing a custom build:
DEEIX_CHAT_IMAGE=deeix-chat:local docker compose up -d --buildDocker URL: http://localhost:8080. Keep the Docker server section unchanged unless changing ports or public domains; then update compose ports, public URLs, and CORS together.
Use this mode when the frontend and backend are served from different public origins, for example https://chat.example.com and https://api.example.com.
-
Configure public URLs.
- Frontend build variable:
NEXT_PUBLIC_API_BASE_URL=https://api.example.com - Backend config:
server.public_api_base_url=https://api.example.com - Backend config:
server.public_web_base_url=https://chat.example.com - Backend config:
server.cors_allow_origin=https://chat.example.com
For Docker image builds, pass the frontend API URL at build time:
docker build --build-arg NEXT_PUBLIC_API_BASE_URL=https://api.example.com -t deeix-chat . - Frontend build variable:
-
Build and publish the frontend.
cd frontend pnpm install NEXT_PUBLIC_API_BASE_URL=https://api.example.com pnpm buildThe static output is
frontend/out. Serve it with Nginx, CDN, object storage, or any static web server. To let the Go backend serve the frontend, placefrontend/outunderserver.frontend_dist_dir; the Docker image defaults to/app/frontend/out. -
Apply CDN rules.
Path Rule /_next/static/*Cache for 1 year with immutable assets enabled. /logo*.svg,/*.ico,/*.png,/*.jpg,/*.webp,/*.woff2Cache for 1 day to 30 days. /,/*.html,/chat*,/recent*,/files*,/setting*,/admin*,/share*Do not long-cache. Use no-cacheor a short TTL./api/*,/healthz,/readyz,/swagger/*Bypass CDN cache and forward all request headers, methods, query strings, and request bodies. If the CDN serves
frontend/outfrom object storage, enable route fallback so clean URLs resolve to their exportedindex.htmlfiles, for example/chat->/chat/index.html. -
Configure Stripe Webhook if Stripe is enabled.
Add this endpoint in Stripe Dashboard:
https://api.example.com/api/v1/billing/payments/stripe/webhookEnable the
checkout.session.completedevent and paste the generatedwhsec_...signing secret into Admin -> Billing -> Payment settings -> Stripe Webhook Secret. This endpoint must bypass CDN cache and preserve the raw request body plus theStripe-Signatureheader.
/chat- conversation workspace/share- public conversation snapshot page/recent- recent conversations, share status, starred and archived states/files- file manager/setting- user account, subscription, preferences, security settings, and product information/admin- administration console
Backend:
cd backend
go build ./cmd/server
go test ./...
go vet ./...
make swaggerFrontend:
cd frontend
pnpm lint
pnpm buildStatic infrastructure configuration is loaded from the repository-level config.yaml and can be overridden by environment variables. Runtime business settings are stored in system_settings and managed from the admin console.
Frontend build-time variables:
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_API_BASE_URL |
Browser API base URL; set in frontend/.env.local for local dev or at build time for separated deployment. |
Common backend environment variables:
| Variable | Purpose |
|---|---|
APP_ENV |
Runtime environment. Accepts dev/development and prod/production; omitted values default to prod. |
HTTP_PORT |
API/runtime port. |
JWT_SECRET |
JWT signing secret. Must be strong in production. |
DATA_ENCRYPTION_KEY |
Key material for encrypted secrets such as upstream API keys, SSO client secrets, MCP tokens, and TOTP secrets. |
POSTGRES_DSN |
PostgreSQL DSN. |
REDIS_ADDR, REDIS_PASSWORD, REDIS_DB |
Redis connection settings. |
STORAGE_BACKEND |
local or s3. |
STORAGE_ROOT_DIR |
Local storage root. |
STORAGE_S3_ENDPOINT, STORAGE_S3_REGION, STORAGE_S3_BUCKET, STORAGE_S3_PREFIX, STORAGE_S3_ACCESS_KEY_ID, STORAGE_S3_SECRET_ACCESS_KEY |
S3-compatible storage settings. |
PUBLIC_API_BASE_URL, PUBLIC_WEB_BASE_URL |
Public URLs used for links and callbacks. |
GEOIP_PROVIDER |
GeoIP provider. The default ipwhois uses the built-in public endpoint. |
OTEL_ENABLED, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_INSECURE, OTEL_TRACES_SAMPLER_ARG, OTEL_SAMPLING_RATE |
OpenTelemetry tracing settings. |
Production mode rejects unsafe default secrets, weak encryption keys, wildcard CORS, and non-HTTPS public URLs.
The initial superadmin bootstrap credentials are built in as deeix-chat / deeix-chat-2026 / System Admin. They are used only when the database has no superadmin account. The first login forces changing the username and password; later changes are managed from the account flow, not from config.yaml.
- User passwords are hashed with bcrypt.
- Refresh tokens and recovery-style secrets are stored as hashes.
- Upstream API keys, SSO client secrets, MCP auth tokens, sensitive settings, and TOTP secrets are encrypted with AES-GCM using
DATA_ENCRYPTION_KEY. - Access tokens are short-lived and held client-side in memory; refresh tokens are issued through HttpOnly cookies.
- User-supplied model options are filtered before provider requests. System-generated fields such as model, messages, tools, system prompts, headers, and previous-response identifiers are not user-overridable.
The compose files below attach to deeix-chat-network. Create it with docker network create deeix-chat-network, or start the root compose stack once before launching these services.
Apache Tika:
docker compose -f docker/tika/docker-compose.yml up -dTesseract OCR:
docker compose -f docker/tesseract/docker-compose.yml up -d --buildDocling:
docker compose -f docker/docling/docker-compose.yml up -d --buildRapidOCR:
docker build -t deeix-chat-rapidocr ./docker/rapidocrThese services are optional. The admin file settings decide which extraction or OCR engine is active.
- Backend guide: backend/README.md
- Backend standards: backend/docs/README.md
- Frontend guide: frontend/README.md
- Contributing: CONTRIBUTING.md
- Security policy: SECURITY.md
- Swagger UI:
http://localhost:8080/swagger/index.html
DEEIX Chat is built on the open-source ecosystem. Thanks to all maintainers and communities in the AI tooling ecosystem.
- Email: support@deeix.com
- Telegram: t.me/deeix_chat
DEEIX Chat is licensed under the Apache License 2.0.



