Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,733 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔮 Prism

stars forks license Go React Docker

Languages: English · 简体中文

A unified, self-hosted AI gateway & chat platform

Aggregate ChatGPT, Claude, Gemini and other leading models in a single interface, with a built-in OpenAI-compatible gateway, user management, subscription billing and admin dashboard. Add your API keys to spin up a private AI site with an experience on par with the official products — fully self-hosted, ready for team use or public services. One Docker command to launch, no assembly required.


Docker GitHub Docs


💡 Tip: On first launch with an empty database, an admin root account is created automatically. If ROOT_INITIAL_PASSWORD is not set, a random password is generated and written to the startup logs. Image: qunqin45/prism:latest. Development and releases use the main branch.


Table of Contents


Screenshots

👉 Click to expand screenshots

Web Search — Native search for leading models; Tavily-powered retrieval for the rest.

Web Search

Universal Web Search — Non-native-search models use the Tavily API, with smart keyword extraction via a task model.

Universal Web Search

Persistent Memory — Saves user preferences across sessions so the model keeps learning about each user.

Persistent Memory

Model Market Performance — Shows TPS, latency, success rate and availability trends to guide model selection.

Model Market Performance

Model Market Details

Dual-Window Quota — Short-cycle (5h) and weekly limits are computed and reset independently.

Dual-Window Quota

Admin Dashboard — Users, channels, subscriptions, model market and announcements in one place.

Admin Dashboard

Admin Dashboard Details

Usage Tracking — Request logs, token consumption and cost breakdowns at a glance.

Usage Tracking

Object Storage — Compatible with S3, Cloudflare R2, MinIO and more.

Object Storage


Quick Start

Note

Running Prism requires Docker (with Compose). On first launch with an empty database, an admin root account is created; if ROOT_INITIAL_PASSWORD is unset, a random password is written to the startup logs.

git clone --depth=1 --branch=main --single-branch https://github.com/qwq202/prism.git
cd prism
docker compose up -d

After launch, open http://localhost:8000. To customize the database password, SECRET, initial root password and more, copy .env.example to .env and edit it (.env is git-ignored — never commit real secrets).

docker compose ps                 # check container status
curl http://localhost:8000/health # health check; status: ok means healthy

Upgrade:

docker compose down && docker compose pull && docker compose up -d

Tip

If Watchtower is enabled, images update automatically and manual upgrade can be skipped.


AI-Powered Deployment

Prefer not to do it manually? Copy the prompt below into Claude, Cursor, ChatGPT or another AI assistant and let it deploy for you (use the copy button at the top-right of the code block).

Deploy Prism — a self-hosted AI gateway & chat platform — for me.

Project info:
- Repo: https://github.com/qwq202/prism
- Docker image: qunqin45/prism:latest
- Access URL: http://localhost:8000

Steps (report the result after each one):
1. Ensure Docker (with Compose) is installed; if not, install via the official script: curl -fsSL https://get.docker.com | sh
2. Clone the repo: git clone --depth=1 --branch=main --single-branch https://github.com/qwq202/prism.git
3. Start the stack: cd prism && docker compose up -d (includes MySQL, Redis and Prism)
4. Health check: curl http://localhost:8000/health — expect status: ok

When done:
- The admin username is root; the password comes from the ROOT_INITIAL_PASSWORD env var, or a random one printed in docker compose logs if unset
- Tell me the access URL and the root password

Resolve any issues (port conflicts, container failures, etc.) before continuing.

Note

Requires an AI assistant with terminal access (e.g. Cursor, Claude Code, or other terminal-capable agents). Chat-only AIs will guide you step by step but cannot run commands directly.


Features

Chat & Multimodal

  • 🤖 Multi-model chat — Aggregate OpenAI, Claude, Gemini, DeepSeek, Grok and more in a single interface, with Markdown / LaTeX / Mermaid rendering and syntax highlighting.
  • 💭 Reasoning display — Live Reasoning / Thinking content (OpenAI, DeepSeek, xAI, MiMo, etc.).
  • 🧠 Persistent memory — Saves user preferences across sessions so the model keeps understanding your context without repetition.
  • 🎨 AI drawing workspace — Native image generation via DALL·E and Gemini; turn text prompts into images with multiple parallel workspaces (/drawing page).
  • 📎 File & image handling — Parse PDF / Office / images, with paste-to-upload, pre-send preview and auto-conversion of long text to attachments.
  • 🔧 Tool calls & web fetch — Native Function Calling / Tool Use, plus a built-in Fetch Webpage content extractor.
  • 🌐 Web search — Picks the optimal path per model: leading models use the provider's native Web Search, while others are augmented via the Tavily API — no need to self-host SearXNG or similar layers (see table below).

Web Search Routing

Type Applicable models Description
Native search OpenAI Responses (GPT-5 series), Gemini, xAI Grok Calls the provider's native Web Search / Google Search / X Search directly
Tavily augmented Other models with web search enabled Fetches real-time results via the Tavily API, optionally with keyword extraction by a task model

Configure the Tavily API key, search depth, topic and result count under System Settings → Web Search.

Gateway & Channels

  • 📡 OpenAI-compatible API — A unified /v1/chat/completions gateway that works with any OpenAI client.
  • ⚖️ Multi-channel load balancing — Scheduling by priority, weight and user group, with automatic failover and retry.
  • 🔀 Model mapping & redirection — Transparently remap a requested model name to an upstream model; the ! prefix hides the original.
  • 💾 Request caching — Identical requests hit the cache at no charge, cutting repeat-call costs.
  • 📊 Model market — Real call-data metrics (TPS, latency, success rate, availability) to guide model selection.
  • 🔄 Upstream sync — One-click sync of channels, model lists and pricing.

Billing & Operations

  • 🎯 Flexible billing — Per-request / per-token / free modes, with a minimum-points check.
  • 📅 Subscriptions (dual-window quota) — Short-cycle (5h) and weekly quotas computed and reset independently, with per-plan quota pools.
  • 🎁 Gift codes / redemption codes — Bulk generation; single-user-limited gift codes vs. multi-user redemption codes.
  • 📝 Usage tracking — Full request logs, token consumption and cost breakdowns.

Admin Dashboard

  • 📈 Dashboard & announcements — Real-time operations data and announcement pushes.
  • 👥 User management — Bulk operations, direct creation, grouping and quota control.
  • 💼 Plans & pricing — Subscription plans, price templates, channel and model-market configuration.
  • 🎨 Site customization — Name / logo, SMTP email, attachments and object storage (S3 / Cloudflare R2 / MinIO).

Experience

  • 🌍 Multilingual — 中文 / English / 日本語 / Русский.
  • 🌗 Themes — Light / dark mode.
  • 📱 PWA — "Add to Home Screen" on mobile for a near-native app experience.
  • 🔐 Secure auth — JWT signing, optional Passkey / WebAuthn passwordless login; self-hosted data stays under your control.
  • 🔄 Cross-device sync & sharing — Conversations sync across devices, with link / image sharing.

Supported Models

Provider Capabilities
OpenAI & Azure Vision, Function Calling, GPT-5 series, Reasoning Summaries, native Web Search, image generation (DALL·E / gpt-image-1)
Anthropic Claude Vision, Function Calling
Google Gemini Vision, native Google Search / URL Context, native image generation
DeepSeek V4, Thinking control, Prompt Cache stats
xAI Grok Responses API, native Web Search / X Search, Writable Memory, Reasoning
Xiaomi MiMo Thinking Toggle, Token Plan China
MiniMax Token Plan CN
GLM Coding Plan CN
LocalAI / Ollama OpenAI-compatible format (local models)

💡 Any provider that conforms to the OpenAI API format can be integrated. For locally deployed models, use Ollama or LocalAI.


Deployment

Important

First launch (empty user table) auto-creates an admin account, username root. Password source: the ROOT_INITIAL_PASSWORD env var or root.initial_password in config.yaml (6–36 chars, either one; env var takes precedence); if neither is set, a 24-char random password is generated and printed to the startup logs (view with docker compose logs). Full details in the FAQ.

Option 1: Docker Compose (recommended)

Access at http://localhost:8000

git clone --depth=1 --branch=main --single-branch https://github.com/qwq202/prism.git
cd prism
docker compose up -d

Data & config directories (auto-created on first launch):

Path Description
./db MySQL data
./redis Redis data
./config Config files (auto-generates config.yaml and a random secret)

Note

After the MySQL container initializes for the first time, credentials are persisted in ./db. If a data directory already exists, changing the MySQL password in .env will not migrate it automatically — update the in-database password or reinitialize.

Use the stable image (MySQL 5.7 / Redis 8.2)
docker compose -f docker-compose.stable.yaml up -d

For legacy environments with database-version compatibility requirements.

Option 2: Single-container Docker (external MySQL / Redis)

Already have your own database? Use this. Access at http://localhost:8094

docker run -d --name prism \
  --network host \
  -v ~/config:/config \
  -v ~/logs:/logs \
  -v ~/storage:/storage \
  -e MYSQL_HOST=localhost \
  -e MYSQL_PORT=3306 \
  -e MYSQL_DB=prism \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=your_mysql_password \
  -e REDIS_HOST=localhost \
  -e REDIS_PORT=6379 \
  -e SECRET=replace_with_a_random_32_byte_string \
  -e ROOT_INITIAL_PASSWORD=replace_with_a_strong_initial_password \
  -e SERVE_STATIC=true \
  qunqin45/prism:latest
Env var Description
SECRET JWT signing key, at least 32 random characters
ROOT_INITIAL_PASSWORD root password for first empty-DB launch (6–36 chars); if unset, read the random one from logs
SERVE_STATIC Whether the backend serves static files (default true)
curl http://localhost:8094/health   # health check
docker stop prism && docker rm prism && docker pull qunqin45/prism:latest  # update image

Option 3: Decoupled frontend/backend

  • Frontend: host statically via Nginx / Vercel etc., set VITE_BACKEND_ENDPOINT at build time (e.g. https://api.example.com)
  • Backend: set SERVE_STATIC=false and deploy the API on its own domain
  • ⚠️ Prism itself does not support full-stack Vercel deployment; only the frontend can go to Vercel

🍓 ARM architecture (Raspberry Pi / Apple Silicon)

The public image qunqin45/prism:latest is linux/amd64. On ARM machines, build from source locally or use BuildX to produce a linux/arm64 image.


Local Development

Prerequisites: Go 1.25+, Node.js (pnpm), MySQL 8, Redis 7

# Backend
go build .                    # compile
go test ./...                 # tests

# Frontend
cd app && pnpm install        # install deps
cd app && pnpm dev            # dev server
cd app && pnpm test:run       # Vitest regression suite
cd app && pnpm lint           # ESLint
cd app && pnpm build          # production build → app/dist

# Repository guardrails
node scripts/check-source-size.mjs  # source-size baseline and limits

# Full stack (database + Redis + backend)
docker compose up -d

The backend entry point is main.go; frontend source lives in app/src/. See config.example.yaml for configuration.


Configuration

The most commonly used options (full reference in config.example.yaml):

Key Description
secret JWT signing key; auto-generated on first launch
root.initial_password Initial admin password; equivalent to the ROOT_INITIAL_PASSWORD env var
serve_static Keep true when serving frontend and backend from the same process
system.general.backend Backend API URL; defaults to same-origin /api, set a full URL for decoupled deployment
ALLOW_ORIGINS Strict CORS allowlist, comma-separated domains (no protocol prefix)
system.search.api_key Tavily API key for non-native-search models
system.search.depth Tavily search depth: basic / advanced / fast / ultra-fast
system.task.model Model used for search keyword extraction (optional)

FAQ

Chat hangs / no response

Chat uses WebSocket (API relay uses plain HTTP and doesn't need WebSocket). Make sure your reverse proxy (Nginx / Apache), CDN or port forwarding has WebSocket support enabled.

🔑 Admin account & initial password

On first launch, when the user table is empty, an admin account is created automatically:

Field Value
Username root (fixed)
Email root@example.com
Role Administrator

Initial password sources (either one; the env var takes precedence over the config file):

Method Key Rule
Env var ROOT_INITIAL_PASSWORD 6–36 chars
Config file root.initial_password in config.yaml 6–36 chars
  • If neither is set or the value is out of range, a 24-character random password is generated and printed in plaintext to the startup logs:
    [service] no user found, creating root user with generated password (username: root, password: <24-char-random>); save it now ...
    
    Retrieve it with docker compose logs.
  • The password is generated only once, when the user table is empty. Changing the env var or config file afterwards will not recreate or update the root password.

View / change the password:

  1. Didn't set one on first launch → read the random password from docker compose logs
  2. Already signed in → Dashboard → System Settings → Change Root Password; or edit under User Management
  3. Reset when locked out:
    • Compose: docker compose exec chatnio prism root <new-password>
    • Single container: docker exec prism prism root <new-password>
    • Binary: ./prism root <new-password>
External dependencies
Service Purpose Required?
MySQL Persistent data: users, conversations, config ✅ Required
Redis Auth, rate limiting, subscription quotas, verification codes ✅ Required
Billing & subscriptions
  • Flexible billing (points): general pay-as-you-go, default 10 points = 1 CNY, adjustable in billing-rule templates
  • Subscriptions: fixed price + windowed quota; charges use points (e.g. a 32 CNY plan requires ≥ 320 points)
  • Four subscription tiers: Regular (0), Basic (1), Standard (2), Pro (3), mapped to channel user groups
Gift codes vs. redemption codes
Type Trait Use case
Gift code Each user can redeem a given type only once Promotions, giveaways
Redemption code A given type can be redeemed by many users Card sales, bulk purchases
Error: user quota is not enough

This is the minimum-request-points check:

  • Free models: no limit
  • Per-request billing: min points = per-request cost
  • Per-token billing: min points = 1K input price + 1K output price

Fix: top up points, or grant the user more quota.

Model mapping

Inside a channel, use the format [from]>[to], one per line. from is the model the user requests, to is the actual upstream model.

gpt-4-all>gpt-4          # map gpt-4-all to gpt-4
!gpt-4-all>gpt-4         # the ! prefix hides gpt-4 on this channel, exposing only gpt-4-all
Payment integration

Configure a purchase link (card-sale URL) in System Settings; redemption codes are generated in bulk from the dashboard.


Tech Stack

Layer Stack
Frontend React 19, Redux Toolkit, Radix UI, Tailwind CSS, Vite
Backend Go 1.25, Gin, MySQL, Redis
Deployment Docker, Docker Compose, PWA, WebSocket

🤝 Support

🙏 Acknowledgements

This project is a secondary development based on coai. Sincere thanks to the original authors for the foundational work.

Star History

Star History Chart

Made with ❤️ · Apache-2.0 License

About

Prism is a modern multi-model AI gateway and subscription platform with an OpenAI-compatible API, model marketplace, tool use, quota windows, billing, admin console, file parsing, web search, and PWA/Tauri clients.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages