diff --git a/.env.example b/.env.example index 3d87b2491..75d8b5a16 100644 --- a/.env.example +++ b/.env.example @@ -52,20 +52,3 @@ ENABLE_CIRCUIT_BREAKER_ON_NETWORK_ERRORS=false # - true:支持 Gemini CLI、OpenAI Compatible 等其他类型 # 警告:其他类型功能仍在开发中,暂不建议启用 ENABLE_MULTI_PROVIDER_TYPES=false - -# Codex Instructions 注入(实验性功能) -# 功能说明:控制是否强制替换 Codex 请求中的 instructions 字段为官方完整 prompt -# - false (默认):保持原样透传,不修改 instructions(推荐) -# - true:强制替换为官方 Codex CLI instructions(约 4000+ 字完整 prompt) -# 使用场景: -# - 默认关闭:适用于官方 Codex CLI 客户端(已包含完整 instructions)和大多数场景 -# - 启用:某些 Codex 供应商可能要求必须包含官方 instructions,如遇代理失败可尝试启用 -# 注意:即使关闭此选项,仍会删除 Codex 不支持的参数(temperature, max_tokens 等) -ENABLE_CODEX_INSTRUCTIONS_INJECTION=false - -# 客户端版本检查配置 -# 功能说明:控制客户端版本检查和 GA 版本检测的行为 -# - GA 版本定义:当某个版本有至少 N 个用户使用时,该版本被视为 GA(General Availability)版本 -# - 版本检查:在管理后台启用后,旧版本客户端会被拦截并提示升级 -# 注意:版本检查功能默认关闭,需要在管理后台【设置 → 客户端版本】中手动启用 -CLIENT_VERSION_GA_THRESHOLD=2 # GA 版本检测阈值(用户数,默认:2) diff --git a/CLAUDE.md b/CLAUDE.md index 38b8656a6..77751cdfd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -398,7 +398,11 @@ DSN="postgres://..." # PostgreSQL 连接字符串 AUTO_MIGRATE=true # 启动时自动执行迁移 # Redis 配置 -REDIS_URL=redis://localhost:6379 # Redis 连接地址 +# - TCP:使用 redis:// +# - TLS(Upstash 等云服务):使用 rediss://,客户端会显式启用 tls: {} +REDIS_URL=redis://localhost:6379 # Redis 连接地址(本地/容器) +# 例:Upstash TLS 连接(请替换密码和主机) +# REDIS_URL=rediss://default:your_password@your-subdomain.upstash.io:6379 ENABLE_RATE_LIMIT=true # 启用限流功能 # Session 配置 diff --git a/README.en.md b/README.en.md index 5e94678d7..b5c053767 100644 --- a/README.en.md +++ b/README.en.md @@ -1,549 +1,224 @@

- 中文 | English + English | 中文

# Claude Code Hub -**🚀 Intelligent AI API relay and proxy platform** - -Designed for teams and enterprises that need to centrally manage multiple AI service providers +**🚀 Intelligent AI API relay platform — the control center for multi-provider onboarding, elastic routing, and granular operations** [![Container Image](https://img.shields.io/badge/ghcr.io-ding113%2Fclaude--code--hub-181717?logo=github)](https://github.com/ding113/claude-code-hub/pkgs/container/claude-code-hub) [![License](https://img.shields.io/github/license/ding113/claude-code-hub)](LICENSE) [![GitHub Stars](https://img.shields.io/github/stars/ding113/claude-code-hub)](https://github.com/ding113/claude-code-hub/stargazers) -[![Telegram](https://img.shields.io/badge/Telegram-@ygxz__group-26A5E4?logo=telegram)](https://t.me/ygxz_group) - -[Features](#-features) • -[Quick Deployment](#-quick-deployment) • -[Usage Guide](#-usage-guide) • -[FAQ](#-faq) - -
- -> **💡 Acknowledgements** -> This project is a heavily customized fork of [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub). -> Many thanks to the original author [@zsio](https://github.com/zsio) for the open-source contribution! +[![Telegram Group](https://img.shields.io/badge/Telegram-Join%20Group-blue?logo=telegram)](https://t.me/ygxz_group) -> **💬 Join the community** -> -> Feel free to join the Telegram group to discuss product usage, feature requests, and technical questions: -> ->
-> -> **📱 [Tap to join @ygxz_group](https://t.me/ygxz_group)** -> ->
- ---- - -## ✨ Features - -### Core Capabilities - -- **🔄 Unified proxy** - Single API endpoint that fronts every AI provider (OpenAI, Claude, Gemini, etc.) -- **⚖️ Intelligent load balancing** - Weight-based routing with automatic failover and sticky sessions -- **👥 Multi-tenancy** - Full user system with granular permissions and quota management -- **🔑 Key management** - API key generation, rotation, and expiration governance -- **📊 Real-time monitoring** - Request analytics, cost tracking, performance insights, and visual dashboards -- **🎨 Modern UI** - Responsive Shadcn UI-based admin console with dark mode support -- **🚀 Production ready** - One-command Docker deployment, automated DB migrations, and health checks - -This fork delivers extensive enhancements over [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub): - -- **📋 Detailed logging** - Full request history with token usage, cost calculations, cache hits, and more -- **🔒 Concurrency control** - Session limits per user and per provider -- **⏱️ Multi-window rate limiting** - 5-hour / weekly / monthly spending ceilings for flexible quota control -- **📈 Leaderboards** - Daily and monthly rankings to reveal user/provider utilization at a glance -- **🎚️ Priority routing** - Provider-level priority and weight settings for precise traffic shaping -- **🔗 Decision chain tracing** - Complete provider call-chain history with error-driven failover visibility -- **🛡️ Circuit breaker** - Automatic short-term fuse when a provider fails to prevent repeated errors -- **💰 Price sync** - One-click LiteLLM price import covering Claude, OpenAI, Codex, and every other model family -- **🤖 OpenAI compatibility** - Works with Codex CLI and other OpenAI-style coding tools, including model redirects and price policies -- **💵 Currency symbol configuration** - Optional frontend currency display aligned with provider cost multipliers -- **🎯 Model allowlist** - Restrict callable models per provider for fine-grained access control -- **🧹 Log cleanup** - Automatic history pruning to keep the database lean -- **🛡️ Sensitive phrase filtering** - Built-in safeguard to keep the platform compliant -- **📝 Session details** - Optional logging for UA, request, and response payloads to debug provider performance -- **🔐 Key-level permissions** - Optionally forbid specific keys from logging in to the web UI to enforce sharing boundaries -- **📖 Public usage docs** - Rewritten public documentation with anonymous access for faster onboarding -- **📚 Automated API docs** - OpenAPI 3.1.0 plus Swagger UI and Scalar UI with 39 REST endpoints - -### UI Preview - -
+Claude Code Hub combines Next.js 15, Hono, PostgreSQL, and Redis to deliver a Claude/OpenAI-compatible API gateway with smart load balancing, live observability, price governance, and automated documentation, enabling teams to manage multiple AI vendors safely and transparently. -![首页](/public/readme/首页.png) - -_Home dashboard – system overview and quick shortcuts_ - -![供应商管理](/public/readme/供应商管理.png) - -_Provider management – configure upstream services, weights, and throttling_ - -![排行榜](/public/readme/排行榜.png) - -_Leaderboards – instant visibility into user and provider usage_ - -![日志](/public/readme/日志.png) - -_Detailed logs – token accounting, cost tracking, and call-chain tracing_ +💬 **Join the discussion**: Questions about deployment, features or technical issues? Join our [Telegram community](https://t.me/ygxz_group)!
-## 🚀 Quick Deployment - -### Prerequisites - -- Docker and Docker Compose -- ⏱️ The full stack spins up in **under 2 minutes** - -### One-Command Deployment - -**1. Configure environment variables** - -Copy `.env.example` to `.env` and adjust the required values: - -```bash -cp .env.example .env -``` - -**⚠️ You must change `ADMIN_TOKEN` to a strong secret!** +--- -See the full environment reference: [.env.example](.env.example) +## ✨ Core Highlights -**2. Start the stack** +- 🤖 **Intelligent load balancing**: Weight + priority + grouping scheduler with built-in circuit breaker and up to three failover retries to keep requests stable. +- 🧩 **Multi-provider management**: Connect Claude, Codex, Gemini CLI, and OpenAI-compatible vendors simultaneously with per-provider model redirection and HTTP/HTTPS/SOCKS proxy rules. +- 🛡️ **Rate limiting & concurrency control**: Enforce RPM, monetary quotas (5-hour / weekly / monthly), and session concurrency via Redis Lua scripts with atomic counters and fail-open degradation. +- 📘 **Automated OpenAPI docs**: 39 REST endpoints exported from Server Actions into OpenAPI 3.1.0, instantly browsable in Swagger and Scalar UI. +- 📊 **Real-time monitoring & analytics**: Dashboards, active sessions, consumption leaderboards, decision-chain tracing, and proxy health tracking provide second-level visibility. +- 💰 **Price sheet management**: Paginated SQL queries with debounce search and LiteLLM sync keep thousands of model prices searchable in milliseconds. +- 🔁 **Session management**: Five-minute context cache preserves decision trails, reduces vendor switches, and maintains full auditability. +- 🔄 **OpenAI compatibility layer**: Supports `/v1/chat/completions`, handles format conversions, tool calls, reasoning fields, and Codex CLI instruction injection automatically. -```bash -# 启动所有服务(后台运行) -docker compose up -d +## ⚡️ Quick Start -# 查看启动日志 -docker compose logs -f -``` +### Requirements -**3. Verify the deployment** +- Docker and Docker Compose (latest version recommended) +- Optional (for local development): Node.js ≥ 20, pnpm ≥ 9.15 -```bash -docker compose ps -``` +### Three-Step Launch (Docker Compose) -Ensure all three containers report `healthy` or `running`: +1. **Clone and configure** -- `claude-code-hub-db` (PostgreSQL) -- `claude-code-hub-redis` (Redis) -- `claude-code-hub-app` (Application service) + ```bash + git clone https://github.com/ding113/claude-code-hub.git + cd claude-code-hub + cp .env.example .env + ``` -### Configuration Files +2. **Edit configuration** -- **[docker-compose.yaml](docker-compose.yaml)** - Docker Compose definition -- **[.env.example](.env.example)** - Environment variable template + Edit the `.env` file and **update** `ADMIN_TOKEN` (admin login token): -### Common Management Commands + ```bash + # MUST change this! + ADMIN_TOKEN=your-secure-token-here -```bash -# 查看日志 -docker compose logs -f # 所有服务 -docker compose logs -f app # 仅应用 + # Docker Compose defaults (usually no changes needed) + DSN=postgres://postgres:postgres@postgres:5432/claude_code_hub + REDIS_URL=redis://redis:6379 + ``` -# 重启服务 -docker compose restart app # 重启应用 +3. **Start services** -# 升级到最新版本 -docker compose pull && docker compose up -d + ```bash + docker compose up -d + ``` -# 备份数据(数据持久化在宿主机 ./data/ 目录) -# - ./data/postgres 映射到容器 /data (PostgreSQL 数据目录: /data/pgdata) -# - ./data/redis 映射到容器 /data (Redis AOF 持久化文件) -tar -czf backup_$(date +%Y%m%d_%H%M%S).tar.gz ./data/ -``` + Check status: -
-More management commands + ```bash + docker compose ps + docker compose logs -f app + ``` -**Service management**: +### Access the application -```bash -docker compose stop # 停止服务 -docker compose down # 停止并删除容器 -docker compose restart redis # 重启 Redis -``` +Once started: -**Database operations**: +- **Admin Dashboard**: `http://localhost:23000` (login with `ADMIN_TOKEN` from `.env`) +- **API Docs (Scalar UI)**: `http://localhost:23000/api/actions/scalar` +- **API Docs (Swagger UI)**: `http://localhost:23000/api/actions/docs` -```bash -# SQL 备份 -docker exec claude-code-hub-db pg_dump -U postgres claude_code_hub > backup.sql +> 💡 **Tip**: To change the port, edit the `ports` section in `docker-compose.yml`. -# 恢复数据 -docker exec -i claude-code-hub-db psql -U postgres claude_code_hub < backup.sql -``` +## 🖼️ Screenshots -**Redis operations**: +| Feature | Screenshot | Description | +| ------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| Dashboard | ![Dashboard](public/readme/首页.png) | Aggregates request volume, spending, active sessions, and time-series distribution for instant situational awareness. | +| Provider management | ![Provider Management](public/readme/供应商管理.png) | Configure weight, cost multiplier, concurrency caps, proxies, and model redirection per vendor for precise routing. | +| Logs & audit | ![Logs](public/readme/日志.png) | Unified request log with filters for time/user/provider/model plus token, cost, and cache-hit details. | +| Leaderboard | ![Leaderboard](public/readme/排行榜.png) | Ranks users by requests, tokens, and spending to support chargeback and usage governance. | -```bash -docker compose exec redis redis-cli ping # 检查连接 -docker compose exec redis redis-cli info stats # 查看统计 -docker compose exec redis redis-cli --scan # 查看所有 key -docker compose exec redis redis-cli FLUSHALL # ⚠️ 清空数据 -``` +## 🏗️ Architecture -**Full reset** (⚠️ Deletes all data): +### High-level view -```bash -docker compose down && rm -rf ./data/ && docker compose up -d ``` - -
- -## 📖 Usage Guide - -### 1️⃣ Initial setup - -Visit http://localhost:23000 for the first login and authenticate with `ADMIN_TOKEN`. - -### 2️⃣ Add AI providers - -Navigate to **Settings → Provider Management** and click “Add Provider”: - -> **📌 Important: API format compatibility** -> -> This platform **only supports the Claude Code API format** (e.g., Zhipu GLM, Kimi, Packy). To integrate other formats such as Gemini, OpenAI, or Ollama, first deploy `claude-code-router` for protocol conversion, then register the converted endpoint here. - -### 3️⃣ Create users and keys - -**Add a user**: - -1. Go to **Settings → User Management** -2. Click “Add User” -3. Configure: - - User name - - Description - - RPM limit (requests per minute) - - Daily quota (USD) - -**Generate an API key**: - -1. Select the user and choose “Generate Key” -2. Set a key name -3. Optionally configure an expiration time -4. **⚠️ Copy the key immediately** (it is only shown once) - -### 4️⃣ Use the proxy API - -Users can call the proxy with their generated keys: -See `http://localhost:23000/usage-doc` - -### 5️⃣ Monitor and analyze - -The **Dashboard** view provides: - -- 📈 Real-time request trends -- 💰 Cost statistics and analysis -- 👤 Active user rankings -- 🔧 Provider performance comparison -- ⚠️ Anomalous request monitoring - -### 6️⃣ Configure model pricing - -Head to **Settings → Price Management** to set per-model billing rates: - -- Configure input/output token pricing per model (Claude and OpenAI formats included) -- Dedicated pricing for cache tokens (`cache_creation_input_tokens`, `cache_read_input_tokens`) -- Automatic cost calculation per request -- Exportable cost reports - -**OpenAI pricing example**: - -- Model: `gpt-5-codex` -- Input price (USD per million tokens): `0.003` -- Output price (USD per million tokens): `0.006` - -### 7️⃣ API documentation and integrations - -A complete REST API is available for every administrative action. - -**Access the API docs**: - -After logging in, open **Settings → API Documentation** or visit directly: - -- **Scalar UI** (recommended): `http://localhost:23000/api/actions/scalar` -- **Swagger UI**: `http://localhost:23000/api/actions/docs` -- **OpenAPI JSON**: `http://localhost:23000/api/actions/openapi.json` - -**Highlights**: - -- 📋 **39 REST API endpoints** covering the full feature set -- 🔐 Cookie-based authentication -- 📝 Comprehensive request/response samples -- 🧪 Interactive testing surface -- 📦 Auto-validated types (Zod schemas) - -**Available modules**: - -- User, key, and provider management -- Model pricing, analytics, usage logs -- Sensitive term policies, session management, notification management - -**API example**: - -```bash -# 创建用户(需要先登录获取 session cookie) -curl -X POST http://localhost:23000/api/actions/users/addUser \ - -H "Content-Type: application/json" \ - -H "Cookie: session=your-session-cookie" \ - -d '{ - "name": "Alice", - "rpm": 60, - "dailyQuota": 10 - }' +Clients / CLI / Integrations + │ + ▼ +Next.js 15 App Router (v1 API routes) + │ +Hono + Proxy Pipeline (Auth → Session Allocation → Rate Limiting → Provider Selection → Forwarding → Response Handling) + │ +Multi-provider pool (Claude / OpenAI / Gemini / others) + PostgreSQL + Redis ``` -**Full documentation**: see [API Documentation Guide](docs/api-documentation.md) +- **App layer**: `src/app` hosts dashboards, settings, and API actions for UI and internal APIs. +- **Proxy core**: `src/app/v1/_lib/proxy-handler.ts` chains `ProxyAuthenticator`, `ProxySessionGuard`, `ProxyRateLimitGuard`, `ProxyProviderResolver`, `ProxyForwarder`, and `ProxyResponseHandler`. +- **Business logic**: `src/lib` contains rate limiting, session manager, circuit breaker, proxy utilities, and price-sync; `src/repository` encapsulates Drizzle ORM queries. +- **Documentation system**: `src/app/api/actions/[...route]/route.ts` converts Server Actions into OpenAPI endpoints automatically. -## 🛠️ FAQ +### Data flow & components -
-❓ How do I reset the admin password? +1. **Ingress**: Requests with API keys hit the Next.js route and pass through `ProxyAuthenticator`. +2. **Context control**: `SessionManager` fetches the five-minute cache from Redis, enforces concurrency, and records the decision chain. +3. **Rate limiting**: `RateLimitService` applies Lua-driven atomic counters for RPM, spend, and session caps, falling back gracefully if Redis is unavailable. +4. **Routing**: `ProxyProviderResolver` scores vendors with weights, priorities, breaker states, and session reuse, retrying up to three times. +5. **Forwarding & compatibility**: `ProxyForwarder` plus `ResponseTransformer` adapt Claude/OpenAI/Response formats, handle proxies, and honor model redirects. +6. **Observability**: Dashboards, leaderboards, and price sheets query PostgreSQL via repositories with hourly aggregations. -Edit `.env`, update `ADMIN_TOKEN`, then restart: +## 🚢 Deployment -```bash -docker compose restart app -``` +### 🐳 Docker Compose (✨ Recommended, Production-Ready) -
- -
-❓ What if the port is already in use? - -Adjust the port mapping in `docker-compose.yaml`: - -```yaml -services: - app: - ports: - - "8080:23000" # 修改左侧端口为可用端口 -``` - -
- -
-❓ What should I do when database migrations fail? - -1. Inspect the application logs: +Docker Compose is the **preferred deployment method** — it automatically provisions the database, Redis, and application services without manual dependency installation, ideal for production quick-start. +1. Prepare `.env` (see `.env.example`) and point `DSN`/`REDIS_URL` to the Compose services. +2. Start the stack: ```bash - docker compose logs app | grep -i migration + docker compose up -d ``` - -2. Run the migration manually: - +3. Monitor: ```bash - docker compose exec app pnpm db:migrate + docker compose logs -f app + docker compose ps ``` - -3. If it still fails, reset the database (⚠️ data loss): - +4. Upgrade: ```bash - docker compose down && rm -rf ./data/postgres && docker compose up -d + docker compose pull && docker compose up -d ``` + Stop and clean up with `docker compose down` when necessary. -
- -
-❓ Redis connection issues? - -The platform uses a **Fail Open strategy**, so Redis outages do not block request handling. - -Check Redis status: - -```bash -docker compose ps redis -docker compose exec redis redis-cli ping # 应返回 PONG -``` - -When Redis is unavailable, rate limiting gracefully degrades and traffic continues to pass. - -See the [Common Management Commands](#common-management-commands) section for more Redis tips. - -
- -
-❓ Unable to sign in over HTTP? - -**Symptom**: When using HTTP (non-localhost), the login page warns about insecure cookies and rejects the session. - -**Cause**: By default `ENABLE_SECURE_COOKIES=true`, so cookies are only transmitted over HTTPS. Browsers allow HTTP on localhost but not on remote hosts. - -**Solution**: - -**Option 1: Use HTTPS (recommended)** - -Configure a reverse proxy (e.g., Nginx) with TLS as shown in [How do I configure a reverse proxy (Nginx + HTTPS)?](#-how-do-i-configure-a-reverse-proxy-nginx--https) - -**Option 2: Allow HTTP cookies (reduced security)** - -Update `.env`: - -```bash -ENABLE_SECURE_COOKIES=false -``` - -Restart the app: - -```bash -docker compose restart app -``` - -⚠️ **Security warning**: Disabling secure cookies permits HTTP transport and should only be used in internal or test environments. - -
- -
-❓ Which AI providers are supported? - -**Only Claude Code-compatible APIs are supported.** - -**Direct support**: +### Local development (dev toolchain) -- Providers that natively expose the Claude Code protocol +1. Enter the `dev/` folder: `cd dev`. +2. Run `make dev` to launch PostgreSQL + Redis + `pnpm dev` in one command. +3. Helpful targets: + - `make db`: start only database and Redis. + - `make logs` / `make logs-app`: tail all services or app logs. + - `make clean` / `make reset`: clean or fully reset the environment. +4. Use `make migrate` and `make db-shell` for schema operations. -**Indirect support** (requires [claude-code-router](https://github.com/zsio/claude-code-router) for translation): +### Manual deployment (pnpm build + start) -- 🔄 Zhipu AI (GLM), Moonshot AI (Kimi), Packy, etc. -- 🔄 Alibaba Qwen, Baidu ERNIE Bot, etc. -- 🔄 Any other non-Claude-Code AI services - -
- -
-❓ How do I configure a reverse proxy (Nginx + HTTPS)? - -Sample Nginx configuration: - -```nginx -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - location / { - proxy_pass http://localhost:23000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} -``` - -After enabling HTTPS, keep `ENABLE_SECURE_COOKIES=true` (the default) to enforce secure cookie transport. - -
- -
-❓ How do I use the API documentation? - -The platform includes full REST documentation to streamline integrations. - -**Access**: - -1. Sign in to the admin console -2. Open **Settings → API Documentation** -3. Pick Scalar UI (recommended) or Swagger UI -4. Execute API calls directly from the docs - -**Authentication**: - -- All endpoints rely on cookie auth -- Sign in through the web UI to obtain a session cookie -- Include the cookie to call any endpoint - -**Supported capabilities**: - -- 39 REST endpoints -- Full coverage of user, key, provider, pricing, log, and analytics modules -- Interactive testing without extra tooling - -**Full documentation**: see [API Documentation Guide](docs/api-documentation.md) - -
+1. Install dependencies and build: + ```bash + pnpm install + pnpm build # Copies the VERSION file automatically + ``` +2. Export environment variables via your process manager (systemd, PM2, etc.) and ensure PostgreSQL/Redis endpoints are reachable. +3. Launch production server: + ```bash + pnpm start + ``` +4. You may keep `AUTO_MIGRATE=true` for the first run, then disable it and manage migrations explicitly with Drizzle CLI. -
-❓ Large price tables load slowly? +## ⚙️ Configuration -Version v0.2.21+ introduces pagination for price tables to dramatically improve performance at scale. +| Variable | Default | Description | +| ------------------------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------- | +| `ADMIN_TOKEN` | `change-me` | Admin console token — must be updated before deployment. | +| `DSN` | - | PostgreSQL connection string, e.g., `postgres://user:pass@host:5432/db`. | +| `AUTO_MIGRATE` | `true` | Executes Drizzle migrations on startup; consider disabling in production for manual control. | +| `REDIS_URL` | `redis://localhost:6379` | Redis endpoint, supports `rediss://` for TLS providers. | +| `ENABLE_RATE_LIMIT` | `true` | Toggles multi-dimensional rate limiting; Fail-Open handles Redis outages gracefully. | +| `SESSION_TTL` | `300` | Session cache window (seconds) that drives vendor reuse. | +| `ENABLE_SECURE_COOKIES` | `true` | Browsers require HTTPS for Secure cookies; set to `false` when serving plain HTTP outside localhost. | +| `ENABLE_CIRCUIT_BREAKER_ON_NETWORK_ERRORS` | `false` | When `true`, network errors also trip the circuit breaker for quicker isolation. | +| `APP_PORT` | `23000` | Production port (override via container or process manager). | +| `APP_URL` | empty | Populate to expose correct `servers` entries in OpenAPI docs. | -**Highlights**: +> Boolean values should be `true/false` or `1/0` without quotes; otherwise Zod may coerce strings incorrectly. See `.env.example` for the full list. -- 50 rows per page by default -- Model search with built-in debounce to avoid repeated calls -- Page size options: 20 / 50 / 100 / 200 rows -- URL parameters persist, so refreshes keep context +## ❓ FAQ -**How to use**: +1. **Database connection failures** + - Verify the `DSN` format and credentials; use service names (e.g., `postgres:5432`) within Docker. + - Inspect `docker compose ps` or local PostgreSQL status, and use `make db-shell` for deeper checks. -1. Go to **Settings → Price Management** -2. Filter models with the top search bar -3. Browse via the pagination controls -4. Adjust rows per page as needed +2. **What if Redis goes offline?** + - The platform uses a fail-open policy: rate limiting and session metrics degrade gracefully while requests continue flowing. Monitor logs for Redis errors and restore the service asap. -**Performance optimizations**: +3. **Circuit breaker keeps opening** + - Inspect `[CircuitBreaker]` logs to see whether repeated 4xx/5xx or network errors triggered it. + - Check provider health in the admin console and wait 30 minutes or restart the app to reset state. -- SQL-level pagination prevents full table scans -- 500ms debounced search to cut unnecessary queries -- SSR plus client interactivity for fast first paint +4. **“No provider available” errors** + - Ensure providers are enabled, have reasonable weights/priorities, and haven’t hit concurrency or spend caps. + - Review the decision-chain log to confirm whether breakers or proxy failures removed them. -
+5. **Proxy configuration issues** + - Make sure URLs include a protocol (`http://`, `socks5://`, etc.) and validate via the “Test Connection” button in the UI. + - If `proxy_fallback_to_direct` is enabled, confirm via logs that the system retried without the proxy when failures occur. ## 🤝 Contributing -We welcome Issues and Pull Requests! - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/AmazingFeature`) -3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -## 🙏 Credits - -This project draws inspiration from the following open-source efforts: - -- **[zsio/claude-code-hub](https://github.com/zsio/claude-code-hub)** - Core foundation of this project; thanks to [@zsio](https://github.com/zsio) for the excellent architecture -- **[router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** - The Codex CLI OpenAI compatibility layer builds upon this MIT-licensed implementation +We welcome issues and PRs! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for the bilingual guidelines, branch strategy, and Conventional Commits requirements before submitting changes. -Huge thanks to the authors and contributors of these projects! +## 🌐 Acknowledgments -## 📄 License +This project builds on [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) and references [router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) for the OpenAI-compatible layer. Huge thanks to the original authors and community contributors! -This project uses the [MIT License](LICENSE). - -**References**: - -- The Codex CLI OpenAI compatibility layer is adapted from [router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) (MIT) - -## 🌟 Star History - -If the project helps you, please consider leaving a ⭐ +## ⭐ Star History [![Star History Chart](https://api.star-history.com/svg?repos=ding113/claude-code-hub&type=Date)](https://star-history.com/#ding113/claude-code-hub&Date) -## 📞 Support & Feedback +## 📜 License -
- -**[🐛 Report Issues](https://github.com/ding113/claude-code-hub/issues)** • -**[💡 Request Features](https://github.com/ding113/claude-code-hub/issues/new)** • -**[📖 Read the Docs](https://github.com/ding113/claude-code-hub/wiki)** - -Based on [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) • Modified by [ding113](https://github.com/ding113) - -
+Released under the [MIT License](LICENSE). You’re welcome to use and extend the project as long as you comply with the license and retain the attribution. diff --git a/README.md b/README.md index eb1801ba4..97f998a2c 100644 --- a/README.md +++ b/README.md @@ -6,545 +6,219 @@ # Claude Code Hub -**🚀 智能 AI API 代理中转服务平台** - -专为需要统一管理多个 AI 服务提供商的团队和企业设计 +**🚀 智能 AI API 代理中转服务平台|面向团队的多供应商统一接入、弹性调度与精细化运营中心** [![Container Image](https://img.shields.io/badge/ghcr.io-ding113%2Fclaude--code--hub-181717?logo=github)](https://github.com/ding113/claude-code-hub/pkgs/container/claude-code-hub) [![License](https://img.shields.io/github/license/ding113/claude-code-hub)](LICENSE) [![GitHub Stars](https://img.shields.io/github/stars/ding113/claude-code-hub)](https://github.com/ding113/claude-code-hub/stargazers) -[![Telegram](https://img.shields.io/badge/Telegram-@ygxz__group-26A5E4?logo=telegram)](https://t.me/ygxz_group) - -[功能特性](#-功能特性) • -[快速部署](#-快速部署) • -[使用指南](#-使用指南) • -[常见问题](#-常见问题) - - - -> **💡 致谢** -> 本项目基于 [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) 二次开发而来。 -> 感谢原作者 [@zsio](https://github.com/zsio) 的开源贡献! +[![Telegram Group](https://img.shields.io/badge/Telegram-交流群-blue?logo=telegram)](https://t.me/ygxz_group) -> **💬 加入交流群** -> -> 欢迎加入 Telegram 交流群讨论项目使用、功能建议和技术问题: -> ->
-> -> **📱 [点击加入 @ygxz_group](https://t.me/ygxz_group)** -> ->
- ---- - -## ✨ 功能特性 - -### 核心能力 - -- **🔄 统一代理** - 一个 API 接口管理所有 AI 服务提供商(OpenAI、Claude、Gemini 等) -- **⚖️ 智能负载** - 基于权重的智能分发 + 自动故障转移 + 会话保持 -- **👥 多租户** - 完整的用户体系,细粒度权限控制和配额管理 -- **🔑 密钥管理** - API Key 生成、轮换、过期管理 -- **📊 实时监控** - 请求统计、成本追踪、性能分析、可视化报表 -- **🎨 现代 UI** - 基于 Shadcn UI 的响应式管理面板,深色模式 -- **🚀 生产就绪** - Docker 一键部署、自动数据库迁移、健康检查 - -本项目基于 [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) 进行了大量增强和优化: - -- **📋 详细日志记录** - 完整的请求日志,包含 Token 使用、成本计算、缓存命中等详细信息 -- **🔒 并发控制** - 支持为用户和供应商设置并发 Session 限制 -- **⏱️ 多时段限流** - 5小时/周/月 三个时间窗口的金额限制,更灵活的配额管理 -- **📈 统计排行榜** - 日统计、月统计排行榜,快速了解用户和供应商使用情况 -- **🎚️ 优先级路由** - 支持多供应商优先级和权重设置,精细化流量分配 -- **🔗 决策链追踪** - 完整的供应商调用链记录,支持错误切换决策链显示 -- **🛡️ 熔断保护** - 供应商出错时自动临时熔断,避免重复调用失败的服务 -- **💰 价格同步** - 一键拉取 LiteLLM 模型价格表,支持所有模型类型(Claude、OpenAI、Codex 等) -- **🤖 OpenAI 兼容** - 支持 Codex CLI 等 OpenAI 格式的 AI 编程工具,包括模型重定向、价格管理 -- **💵 货币符号配置** - 可选前端展示货币符号,配合供应商成本倍率清晰掌握调用成本 -- **🎯 模型白名单** - 为特定供应商配置可调用的模型白名单,精细化权限控制 -- **🧹 日志清理** - 自动清理历史日志,优化数据库性能 -- **🛡️ 敏感词拦截** - 内置敏感词过滤功能,保障服务安全合规 -- **📝 Session 详情** - 记录 UA、请求体和响应体(可选,默认关闭),便于排查供应商模型性能问题 -- **🔐 密钥权限控制** - 可选特定密钥不允许登录 Web UI,为分享划清权限边界 -- **📖 公开使用文档** - 使用文档重写并支持免登录访问,便于用户快速上手 -- **📚 自动化 API 文档** - OpenAPI 3.1.0 规范 + Swagger UI + Scalar UI 双界面,支持 39 个 REST API 端点 -- **📄 价格表分页** - 支持大规模模型数据查询,搜索防抖,SQL 层面性能优化 - -### 界面预览 - -
+Claude Code Hub 通过 Next.js 15 + Hono + PostgreSQL + Redis 组合,实现 Claude/OpenAI 兼容 API 代理、智能负载均衡、实时监控、价格管理与自动化文档,帮助团队安全、可观测地管理多家 AI 服务商。 -![首页](/public/readme/首页.png) - -_首页面板 - 系统概览与快速访问_ - -![供应商管理](/public/readme/供应商管理.png) - -_供应商管理 - 配置上游服务、权重分配、流量限制_ - -![排行榜](/public/readme/排行榜.png) - -_统计排行榜 - 用户和供应商使用情况一目了然_ - -![日志](/public/readme/日志.png) - -_详细日志记录 - Token 使用、成本计算、调用链追踪_ +💬 **加入讨论**:有部署、功能或技术问题?欢迎加入 [Telegram 交流群](https://t.me/ygxz_group) 与社区一起讨论!
-## 🚀 快速部署 - -### 前置要求 - -- Docker 和 Docker Compose -- ⏱️ 仅需 **2 分钟**即可启动完整服务 - -### 一键部署 - -**1. 配置环境变量** - -复制 `.env.example` 为 `.env` 并修改必要配置: - -```bash -cp .env.example .env -``` - -**⚠️ 必须修改 `ADMIN_TOKEN` 为强密码!** - -查看完整环境变量说明:[.env.example](.env.example) - -**2. 启动服务** - -```bash -# 启动所有服务(后台运行) -docker compose up -d - -# 查看启动日志 -docker compose logs -f -``` - -**3. 验证部署** - -```bash -docker compose ps -``` - -确保三个容器都是 `healthy` 或 `running` 状态: - -- `claude-code-hub-db` (PostgreSQL) -- `claude-code-hub-redis` (Redis) -- `claude-code-hub-app` (应用服务) - -### 配置文件说明 - -- **[docker-compose.yaml](docker-compose.yaml)** - Docker Compose 配置文件 -- **[.env.example](.env.example)** - 环境变量配置模板 - -### 常用管理命令 - -```bash -# 查看日志 -docker compose logs -f # 所有服务 -docker compose logs -f app # 仅应用 - -# 重启服务 -docker compose restart app # 重启应用 - -# 升级到最新版本 -docker compose pull && docker compose up -d - -# 备份数据(数据持久化在宿主机 ./data/ 目录) -# - ./data/postgres 映射到容器 /data (PostgreSQL 数据目录: /data/pgdata) -# - ./data/redis 映射到容器 /data (Redis AOF 持久化文件) -tar -czf backup_$(date +%Y%m%d_%H%M%S).tar.gz ./data/ -``` - -
-更多管理命令 - -**服务管理**: - -```bash -docker compose stop # 停止服务 -docker compose down # 停止并删除容器 -docker compose restart redis # 重启 Redis -``` - -**数据库操作**: - -```bash -# SQL 备份 -docker exec claude-code-hub-db pg_dump -U postgres claude_code_hub > backup.sql - -# 恢复数据 -docker exec -i claude-code-hub-db psql -U postgres claude_code_hub < backup.sql -``` - -**Redis 操作**: - -```bash -docker compose exec redis redis-cli ping # 检查连接 -docker compose exec redis redis-cli info stats # 查看统计 -docker compose exec redis redis-cli --scan # 查看所有 key -docker compose exec redis redis-cli FLUSHALL # ⚠️ 清空数据 -``` - -**完全重置**(⚠️ 会删除所有数据): - -```bash -docker compose down && rm -rf ./data/ && docker compose up -d -``` - -
- -## 📖 使用指南 - -### 1️⃣ 初始设置 - -首次访问 http://localhost:23000 -使用 `ADMIN_TOKEN` 登录管理后台。 - -### 2️⃣ 添加 AI 服务提供商 - -进入 **设置 → 供应商管理**,点击"添加供应商": - -> **📌 重要说明:API 格式兼容性** -> -> 本服务**仅支持 Claude Code 格式**的 API 接口(如智谱 GLM、Kimi、Packy 等)。如果您需要使用其他格式的 AI 服务,比如 Gemini、OpenAI、 Ollama 等格式,请先使用 `claude-code-router` 进行格式转换,然后将转换后的服务地址添加到本系统。 - -### 3️⃣ 创建用户和密钥 +--- -**添加用户**: +## ✨ 核心功能 Highlights -1. 进入 **设置 → 用户管理** -2. 点击"添加用户" -3. 配置: - - 用户名称 - - 描述信息 - - RPM 限制(每分钟请求数) - - 每日额度(USD) +- 🤖 **智能负载均衡**:权重 + 优先级 + 分组调度,内置熔断保护与最多 3 次故障转移,保障请求稳定。 +- 🧩 **多供应商管理**:同时接入 Claude、Codex、Gemini CLI、OpenAI Compatible,自定义模型重定向与 HTTP/HTTPS/SOCKS 代理。 +- 🛡️ **限流与并发控制**:RPM、金额(5 小时/周/月)、并发 Session 多维限制,Redis Lua 脚本确保原子性与 Fail-Open 降级。 +- 📘 **自动化 OpenAPI 文档**:39 个 REST 端点由 Server Actions 自动生成 OpenAPI 3.1.0,Swagger + Scalar UI 双界面即刻试用。 +- 📊 **实时监控与统计**:仪表盘、活跃 Session、消耗排行榜、决策链记录、代理状态追踪,秒级掌控运行态势。 +- 💰 **价格表管理**:分页查询 + SQL 优化,支持搜索防抖、LiteLLM 同步,千级模型也能快速检索。 +- 🔁 **Session 管理**:5 分钟上下文缓存,记录决策链,避免频繁切换供应商并保留全链路审计。 +- 🔄 **OpenAI 兼容层**:支持 `/v1/chat/completions`,自动格式转换、工具调用、reasoning 字段与 Codex CLI 指令注入。 -**生成 API 密钥**: +## ⚡️ 快速开始 Quick Start -1. 选择用户,点击"生成密钥" -2. 设置密钥名称 -3. 设置过期时间(可选) -4. **⚠️ 复制并保存密钥**(仅显示一次) +### 环境要求 -### 4️⃣ 使用代理 API +- Docker 与 Docker Compose(推荐使用最新版本) +- 可选(本地开发):Node.js ≥ 20,pnpm ≥ 9.15 -用户使用生成的密钥调用服务: -查看 `http://localhost:23000/usage-doc` +### 三步启动(Docker Compose) -### 5️⃣ 监控和统计 +1. **克隆项目并配置环境** -**仪表盘**页面提供: + ```bash + git clone https://github.com/ding113/claude-code-hub.git + cd claude-code-hub + cp .env.example .env + ``` -- 📈 实时请求量趋势 -- 💰 成本统计和分析 -- 👤 用户活跃度排行 -- 🔧 供应商性能对比 -- ⚠️ 异常请求监控 +2. **修改配置文件** -### 6️⃣ 配置模型价格 + 编辑 `.env` 文件,**必须修改** `ADMIN_TOKEN`(后台登录令牌): -进入 **设置 → 价格管理**,配置各模型的计费单价: + ```bash + # 必须修改此项! + ADMIN_TOKEN=your-secure-token-here -- 支持按模型配置输入/输出 Token 单价(包括 Claude 和 OpenAI 格式模型) -- 支持缓存 Token 单独定价(`cache_creation_input_tokens`、`cache_read_input_tokens`) -- 自动计算请求成本 -- 导出成本报表 + # Docker Compose 默认配置(通常无需修改) + DSN=postgres://postgres:postgres@postgres:5432/claude_code_hub + REDIS_URL=redis://redis:6379 + ``` -**OpenAI 模型价格配置示例**: +3. **启动服务** -- 模型名称:`gpt-5-codex` -- 输入价格(USD/M tokens):`0.003` -- 输出价格(USD/M tokens):`0.006` + ```bash + docker compose up -d + ``` -### 7️⃣ API 文档和集成 + 查看启动状态: -本系统提供完整的 REST API 接口,支持通过 HTTP 请求进行所有管理操作。 + ```bash + docker compose ps + docker compose logs -f app + ``` -**访问 API 文档**: +### 访问应用 -登录后,进入 **设置 → API 文档** 或直接访问: +启动成功后: -- **Scalar UI**(推荐):`http://localhost:23000/api/actions/scalar` -- **Swagger UI**:`http://localhost:23000/api/actions/docs` -- **OpenAPI JSON**:`http://localhost:23000/api/actions/openapi.json` +- **管理后台**:`http://localhost:23000`(使用 `.env` 中的 `ADMIN_TOKEN` 登录) +- **API 文档(Scalar UI)**:`http://localhost:23000/api/actions/scalar` +- **API 文档(Swagger UI)**:`http://localhost:23000/api/actions/docs` -**功能特性**: +> 💡 **提示**:如需修改端口,请编辑 `docker-compose.yml` 中的 `ports` 配置。 -- 📋 **39 个 REST API 端点**,覆盖所有管理功能 -- 🔐 Cookie 认证保护 -- 📝 完整的请求/响应示例 -- 🧪 交互式 API 测试界面 -- 📦 自动类型验证(Zod schemas) +## 🖼️ 界面预览 Screenshots -**支持的功能模块**: +| 功能 | 截图 | 说明 | +| ---------- | ---------------------------------------------------- | --------------------------------------------------------------------------------- | +| 仪表盘 | ![Dashboard](public/readme/首页.png) | 汇总调用量、成本、活跃 Session 与时间分布,实时洞察整体使用情况。 | +| 供应商管理 | ![Provider Management](public/readme/供应商管理.png) | 为每个供应商配置权重、成本系数、并发限制、代理及模型重定向,实现精细调度。 | +| 日志与审计 | ![Logs](public/readme/日志.png) | 统一查询请求日志,支持时间/用户/供应商/模型筛选,查看 Token、成本与缓冲命中情况。 | +| 排行榜 | ![Leaderboard](public/readme/排行榜.png) | 按用户统计请求数、Token 与成本,用于费用分摊与用量治理。 | -- 用户管理、密钥管理、供应商管理 -- 模型价格、统计数据、使用日志 -- 敏感词管理、Session 管理、通知管理 +## 🏗️ 架构说明 Architecture -**API 调用示例**: +### 高层架构 -```bash -# 创建用户(需要先登录获取 session cookie) -curl -X POST http://localhost:23000/api/actions/users/addUser \ - -H "Content-Type: application/json" \ - -H "Cookie: session=your-session-cookie" \ - -d '{ - "name": "Alice", - "rpm": 60, - "dailyQuota": 10 - }' ``` - -**详细文档**:参见 [API 文档使用指南](docs/api-documentation.md) - -## 🛠️ 常见问题 - -
-❓ 如何重置管理员密码? - -编辑 `.env` 文件,修改 `ADMIN_TOKEN`,然后重启: - -```bash -docker compose restart app +客户端 / CLI / 第三方系统 + │ + ▼ +Next.js 15 App Router (v1 API 路由) + │ +Hono + Proxy Pipeline (认证 → Session 分配 → 限流 → 供应商选择 → 请求转发 → 响应处理) + │ +多供应商 (Claude / OpenAI / Gemini / 第三方) + PostgreSQL + Redis ``` -
- -
-❓ 端口已被占用怎么办? +- **App 层**:`src/app` 中的 dashboard、settings、api actions,提供 UI 与内部 API。 +- **Proxy 核心**:`src/app/v1/_lib/proxy-handler.ts` 串联 Auth、SessionGuard、RateLimitGuard、ProviderResolver、Forwarder、ResponseHandler。 +- **业务逻辑**:`src/lib` 存放限流、Session、熔断器、代理、price-sync;`src/repository` 封装 Drizzle ORM 查询。 +- **文档体系**:`src/app/api/actions/[...route]/route.ts` 自动注册 Action → OpenAPI 端点。 -编辑 `docker-compose.yaml`,修改端口映射: +### 数据流与组件 -```yaml -services: - app: - ports: - - "8080:23000" # 修改左侧端口为可用端口 -``` +1. **入口**:请求携带 API Key 命中 Next.js API Route → `ProxyAuthenticator` 校验身份。 +2. **上下文管理**:`SessionManager` 从 Redis 读取 5 分钟缓存,控制并发并记录决策链。 +3. **限流**:`RateLimitService` 使用 Lua 脚本原子写入 RPM/金额/并发指标,Redis 不可用则 Fail-Open 降级。 +4. **调度**:`ProviderResolver` 根据权重、优先级、熔断状态与 Session 复用策略选择最佳供应商,至多 3 次重试。 +5. **转发与兼容**:`ProxyForwarder` + `ResponseTransformer` 适配 Claude/OpenAI/Response API,支持代理与模型重定向。 +6. **监控**:日志、排行榜、价格表等 UI 通过 `repository` 查询 PostgreSQL,以小时级聚合呈现指标。 -
+## 🚢 部署指南 Deployment -
-❓ 数据库迁移失败怎么办? +### 🐳 Docker Compose(✨ 推荐方式,开箱即用) -1. 检查应用日志: +Docker Compose 是**首选部署方式**,自动配置数据库、Redis 和应用服务,无需手动安装依赖,适合生产环境快速部署。 +1. 准备 `.env`(参考 `.env.example`);确认 `DSN` 与 `REDIS_URL` 指向 Compose 内的服务。 +2. 启动: ```bash - docker compose logs app | grep -i migration + docker compose up -d ``` - -2. 手动执行迁移: - +3. 查看日志与状态: ```bash - docker compose exec app pnpm db:migrate + docker compose logs -f app + docker compose ps ``` - -3. 如果持续失败,重置数据库(⚠️ 会丢失数据): +4. 升级: ```bash - docker compose down && rm -rf ./data/postgres && docker compose up -d + docker compose pull && docker compose up -d ``` + 若需停止并清理,执行 `docker compose down`. -
- -
-❓ Redis 连接失败怎么办? - -本服务采用 **Fail Open 策略**,Redis 连接失败不会影响服务可用性。 - -检查 Redis 状态: - -```bash -docker compose ps redis -docker compose exec redis redis-cli ping # 应返回 PONG -``` - -Redis 不可用时,限流功能会自动降级,所有请求仍然正常通过。 - -更多 Redis 操作请参考[常用管理命令](#常用管理命令)部分。 - -
- -
-❓ HTTP 访问时无法登录怎么办? - -**问题现象**:使用 HTTP 访问系统(非 localhost)时,登录页面显示 Cookie 安全警告,无法登录。 - -**原因**:默认情况下,系统启用了 Cookie 安全策略(`ENABLE_SECURE_COOKIES=true`),仅允许 HTTPS 传输 Cookie。浏览器会自动放行 localhost 的 HTTP 访问,但拒绝远程 HTTP。 - -**解决方案**: - -**方案 1:使用 HTTPS 访问(推荐)** - -配置反向代理(如 Nginx)并启用 HTTPS,参见下方 [如何配置反向代理(Nginx + HTTPS)](#-如何配置反向代理nginx--https) 部分。 - -**方案 2:允许 HTTP Cookie(降低安全性)** - -编辑 `.env` 文件,添加或修改: - -```bash -ENABLE_SECURE_COOKIES=false -``` - -重启应用: - -```bash -docker compose restart app -``` - -⚠️ **安全警告**:设置为 `false` 会允许 HTTP 传输 Cookie,仅推荐用于内网部署或测试环境。 - -
- -
-❓ 支持哪些 AI 服务提供商? - -**本服务仅支持 Claude Code 格式的 API 接口。** - -**直接支持**: +### 本地开发(dev 工具链) -- 原生提供 Claude Code 格式接口的服务商 +1. 进入 `dev/` 目录:`cd dev`. +2. `make dev` 一键启动 PostgreSQL + Redis + pnpm dev。 +3. 常用命令: + - `make db`:仅启动数据库与 Redis + - `make logs` / `make logs-app`:快速查看服务日志 + - `make clean` / `make reset`:清理或重置环境 +4. 推荐使用 `make migrate`、`make db-shell` 处理数据库变更。 -**间接支持**(需要先部署 [claude-code-router](https://github.com/zsio/claude-code-router) 进行协议转换): +### 手动部署(pnpm build + start) -- 🔄 智谱 AI (GLM)、Moonshot AI (Kimi)、Packy 等 -- 🔄 阿里通义千问、百度文心一言等 -- 🔄 其他非 Claude Code 格式的 AI 服务 - -
- -
-❓ 如何配置反向代理(Nginx + HTTPS)? - -Nginx 配置示例: - -```nginx -server { - listen 443 ssl http2; - server_name your-domain.com; - - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; - - location / { - proxy_pass http://localhost:23000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} -``` - -配置 HTTPS 后,确保 `.env` 中 `ENABLE_SECURE_COOKIES=true`(默认值),以启用 Cookie 安全传输。 - -
- -
-❓ 如何使用 API 文档? - -本系统提供完整的 REST API 文档,方便第三方系统集成和自动化管理。 - -**访问方式**: - -1. 登录管理后台 -2. 进入 **设置 → API 文档** -3. 选择 Scalar UI(推荐)或 Swagger UI -4. 在文档页面直接测试 API - -**认证说明**: - -- 所有 API 端点使用 Cookie 认证 -- 需要先通过 Web UI 登录获取 session cookie -- 在 API 请求中包含 cookie 即可调用 - -**支持的功能**: - -- 39 个 REST API 端点 -- 覆盖用户、密钥、供应商、价格、日志、统计等所有管理功能 -- 交互式测试界面,无需额外工具 - -**详细文档**:参见 [API 文档使用指南](docs/api-documentation.md) - -
- -
-❓ 价格表数据量大,加载很慢? - -系统已支持价格表分页功能(v0.2.21+),可显著提升大规模数据加载性能。 - -**功能特性**: - -- 默认每页显示 50 条记录 -- 支持搜索模型名称(自动防抖,避免频繁请求) -- 可选每页 20/50/100/200 条 -- URL 参数同步,刷新页面不丢失状态 - -**使用方式**: - -1. 进入 **设置 → 价格管理** -2. 使用顶部搜索框过滤模型 -3. 通过分页控件浏览数据 -4. 可调整每页显示数量 - -**性能优化**: - -- SQL 层面分页查询,避免全表扫描 -- 搜索防抖(500ms),减少不必要的请求 -- 服务端渲染 + 客户端交互,首屏加载快 +1. 安装依赖并构建: + ```bash + pnpm install + pnpm build # 自动复制 VERSION + ``` +2. 设置环境变量(建议通过系统服务或 PM2 注入),确保数据库、Redis 可访问。 +3. 启动生产服务器: + ```bash + pnpm start + ``` +4. 注意:首次运行可开启 `AUTO_MIGRATE=true` 自动迁移,生产环境完成后建议改为 `false` 并使用 Drizzle CLI 手动管理。 -
+## ⚙️ 配置说明 Configuration -## 🤝 贡献 +| 变量 | 默认值 | 说明与建议 | +| ------------------------------------------ | ------------------------ | ---------------------------------------------------------------------------- | +| `ADMIN_TOKEN` | `change-me` | 后台登录令牌,部署前必须修改。 | +| `DSN` | - | PostgreSQL 连接串,如 `postgres://user:pass@host:5432/db`. | +| `AUTO_MIGRATE` | `true` | 启动时自动执行 Drizzle 迁移;生产环境可关闭以人工控制。 | +| `REDIS_URL` | `redis://localhost:6379` | Redis 地址,支持 `rediss://` 用于 TLS。 | +| `ENABLE_RATE_LIMIT` | `true` | 控制多维限流开关;Fail-Open 策略在 Redis 不可用时自动降级。 | +| `SESSION_TTL` | `300` | Session 缓存时间(秒),影响供应商复用策略。 | +| `ENABLE_SECURE_COOKIES` | `true` | 仅 HTTPS 场景能设置 Secure Cookie;HTTP 访问(非 localhost)需改为 `false`。 | +| `ENABLE_CIRCUIT_BREAKER_ON_NETWORK_ERRORS` | `false` | 是否将网络错误计入熔断器;开启后能更激进地阻断异常线路。 | +| `APP_PORT` | `23000` | 生产端口,可被容器或进程管理器覆盖。 | +| `APP_URL` | 空 | 设置后 OpenAPI 文档 `servers` 将展示正确域名/端口。 | -欢迎提交 Issue 和 Pull Request! +> 布尔变量请直接写 `true/false` 或 `1/0`,勿加引号,避免被 Zod 转换为真值。更多字段参考 `.env.example`。 -1. Fork 本仓库 -2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) -3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) -4. 推送到分支 (`git push origin feature/AmazingFeature`) -5. 开启 Pull Request +## ❓ FAQ -## 🙏 致谢 +1. **数据库连接失败怎么办?** + - 确认 `DSN` 格式与凭据无误;Docker 场景下使用服务名(如 `postgres:5432`)。 + - 查看 `docker compose ps` 或本地 PostgreSQL 状态,必要时通过 `make db-shell` 诊断。 -本项目的开发过程中参考和借鉴了以下优秀的开源项目: +2. **Redis 离线会影响服务吗?** + - 平台采用 Fail-Open 策略:限流与会话统计会降级,但请求仍会继续;建议监控日志中的 Redis Error 并尽快恢复。 -- **[zsio/claude-code-hub](https://github.com/zsio/claude-code-hub)** - 本项目的基础框架,感谢 [@zsio](https://github.com/zsio) 提供的优秀架构设计 -- **[router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** - Codex CLI OpenAI 兼容层的实现参考了该项目,感谢其在 MIT 协议下的开源贡献 +3. **熔断器持续打开如何排查?** + - 查看日志中的 `[CircuitBreaker]` 记录,确认是否由于 4xx/5xx 或网络错误导致。 + - 在管理后台检查供应商健康状态,等待 30 分钟或重启应用重置状态。 -特别感谢上述项目的作者和贡献者! +4. **提示“无可用供应商”该怎么办?** + - 检查供应商是否启用、权重/优先级设置合理,以及是否达到并发/金额限制。 + - 查看决策链日志,确认是否被熔断或代理失败导致。 -## 📄 许可证 +5. **代理配置失败?** + - 确认 URL 含协议前缀(`http://`、`socks5://` 等),并使用后台“测试连接”按钮验证。 + - 若启用降级策略(`proxy_fallback_to_direct`),请在日志中确认是否已自动切换至直连。 -本项目采用 [MIT 许可证](LICENSE) +## 🤝 贡献指南 Contributing -**关于引用和参考**: +欢迎通过 Issue / PR 参与开发,提交前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md),遵循双语目录、分支命名和 Conventional Commits 规则。 -- Codex CLI 的 OpenAI 兼容层实现参考了 [router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) 项目(MIT 协议) +## 🌐 致谢 Acknowledgments -## 🌟 Star History +项目基于 [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) 深度改进,OpenAI 兼容层参考 [router-for-me/CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)。感谢原作者及社区贡献者! -如果这个项目对你有帮助,请给它一个 ⭐ +## ⭐ Star History [![Star History Chart](https://api.star-history.com/svg?repos=ding113/claude-code-hub&type=Date)](https://star-history.com/#ding113/claude-code-hub&Date) -## 📞 支持与反馈 +## 📜 许可证 License -
- -**[🐛 报告问题](https://github.com/ding113/claude-code-hub/issues)** • -**[💡 功能建议](https://github.com/ding113/claude-code-hub/issues/new)** • -**[📖 查看文档](https://github.com/ding113/claude-code-hub/wiki)** - -Based on [zsio/claude-code-hub](https://github.com/zsio/claude-code-hub) • Modified by [ding113](https://github.com/ding113) - -
+本项目采用 [MIT License](LICENSE),可自由使用与二次开发,仍需遵守条款并保留致谢信息。 diff --git a/src/app/v1/_lib/proxy/errors.ts b/src/app/v1/_lib/proxy/errors.ts index 6c67c5671..8183ba3bb 100644 --- a/src/app/v1/_lib/proxy/errors.ts +++ b/src/app/v1/_lib/proxy/errors.ts @@ -161,24 +161,28 @@ export enum ErrorCategory { PROVIDER_ERROR, // 供应商问题(所有 4xx/5xx HTTP 错误)→ 计入熔断器 + 直接切换 SYSTEM_ERROR, // 系统/网络问题(fetch 网络异常)→ 不计入熔断器 + 先重试1次 CLIENT_ABORT, // 客户端主动中断 → 不计入熔断器 + 不重试 + 直接返回 - NON_RETRYABLE_CLIENT_ERROR, // 客户端输入错误(Prompt 超限、内容过滤、PDF 限制、Thinking 格式)→ 不计入熔断器 + 不重试 + 直接返回 + NON_RETRYABLE_CLIENT_ERROR, // 客户端输入错误(Prompt 超限、内容过滤、PDF 限制、Thinking 格式、参数缺失、非法请求)→ 不计入熔断器 + 不重试 + 直接返回 } /** * 预编译的不可重试客户端错误正则表达式数组 * 用于高性能的白名单错误匹配,避免每次调用时重新编译正则 * - * 包含 4 类错误模式: + * 包含 6 类错误模式: * 1. Prompt 长度超限 * 2. 内容过滤拦截 * 3. PDF 页数限制 * 4. Thinking 格式错误 + * 5. 参数缺失/验证错误 + * 6. 非法请求 */ const NON_RETRYABLE_ERROR_PATTERNS = [ /prompt is too long: \d+ tokens > \d+ maximum/i, /Request blocked by content filter|permission_error.*content filter/i, /A maximum of \d+ PDF pages may be provided/i, /Expected.*thinking.*but found|thinking.*must start with a thinking block/i, + /Field required|required field|missing required/i, + /非法请求|illegal request|invalid request/i, ]; /** @@ -187,11 +191,13 @@ const NON_RETRYABLE_ERROR_PATTERNS = [ * 采用白名单模式,检测明确不应重试的客户端错误(如输入超限、内容过滤等), * 这些错误即使重试也不会成功,应直接返回给客户端,且不计入熔断器。 * - * 检测的 4 类错误: + * 检测的 6 类错误: * 1. Prompt 长度超限:`prompt is too long: {tokens} tokens > {max} maximum` * 2. 内容过滤拦截:`Request blocked by content filter` 或 `permission_error.*content filter` * 3. PDF 页数限制:`A maximum of {n} PDF pages may be provided` * 4. Thinking 格式错误:`Expected.*thinking.*but found` 或 `thinking.*must start with a thinking block` + * 5. 参数缺失/验证错误:`Field required`、`required field`、`missing required` + * 6. 非法请求:`非法请求`、`illegal request`、`invalid request` * * @param error - 错误对象 * @returns 是否为不可重试的客户端错误 @@ -201,6 +207,14 @@ const NON_RETRYABLE_ERROR_PATTERNS = [ * // => true * * @example + * isNonRetryableClientError(new ProxyError('max_tokens: Field required', 400)) + * // => true + * + * @example + * isNonRetryableClientError(new ProxyError('非法请求', 400)) + * // => true + * + * @example * isNonRetryableClientError(new ProxyError('Internal server error', 500)) * // => false */ @@ -271,7 +285,7 @@ export function isClientAbortError(error: Error): boolean { * → 不应重试(客户端已经不想要结果了) * → 应立即返回错误 * - * 2. 不可重试的客户端输入错误(Prompt 超限、内容过滤、PDF 限制、Thinking 格式) + * 2. 不可重试的客户端输入错误(Prompt 超限、内容过滤、PDF 限制、Thinking 格式、参数缺失、非法请求) * → 客户端输入违反了 API 的硬性限制或安全策略 * → 不应计入熔断器(不是供应商故障) * → 不应重试(重试也会失败) diff --git a/src/lib/redis/client.ts b/src/lib/redis/client.ts index 278d14b7c..49b2b6ed2 100644 --- a/src/lib/redis/client.ts +++ b/src/lib/redis/client.ts @@ -3,6 +3,56 @@ import { logger } from "@/lib/logger"; let redisClient: Redis | null = null; +/** + * Mask password in a URL for safe logging. + * Example: rediss://user:pass@host:6379 -> rediss://user:***@host:6379 + */ +function maskRedisUrl(urlStr: string): string { + try { + const u = new URL(urlStr); + if (u.password) u.password = "***"; + return u.toString(); + } catch { + return urlStr.replace(/:(?:[^:@]+)@/, ":***@"); + } +} + +/** + * Build ioredis connection options with protocol-based TLS detection. + * - When `rediss://` is used, explicitly enable TLS via `tls: {}` + * - When `redis://` is used, keep plaintext TCP (no TLS option) + */ +export function buildRedisOptionsForUrl(redisUrl: string) { + const isTLS = (() => { + try { + const parsed = new URL(redisUrl); + return parsed.protocol === "rediss:"; + } catch { + // fallback when URL cannot be parsed; conservative detection + return redisUrl.startsWith("rediss://"); + } + })(); + + const baseOptions = { + enableOfflineQueue: false, // 快速失败 + maxRetriesPerRequest: 3, + retryStrategy(times: number) { + if (times > 5) { + logger.error("[Redis] Max retries reached, giving up"); + return null; // 停止重试,降级 + } + const delay = Math.min(times * 200, 2000); + logger.warn(`[Redis] Retry ${times}/5 after ${delay}ms`); + return delay; + }, + } as const; + + // Explicit TLS config for Upstash and other managed Redis providers + const tlsOptions = isTLS ? { tls: {} as Record } : {}; + + return { isTLS, options: { ...baseOptions, ...tlsOptions } }; +} + export function getRedisClient(): Redis | null { // Skip Redis connection during CI/build phase (avoid connection attempts) if (process.env.CI === "true" || process.env.NEXT_PHASE === "phase-production-build") { @@ -60,11 +110,22 @@ export function getRedisClient(): Redis | null { // 4. 保持原始的事件监听器 redisClient.on("connect", () => { - logger.info("[Redis] Connected successfully"); + logger.info("[Redis] Connected successfully", { + protocol: proto || (options as unknown as { tls?: object }).tls ? "rediss" : "redis", + host, + port, + tlsEnabled: Boolean((options as unknown as { tls?: object }).tls), + }); }); redisClient.on("error", (error) => { - logger.error("[Redis] Connection error:", error); + logger.error("[Redis] Connection error", { + error: error instanceof Error ? error.message : String(error), + protocol: proto || (isTLS ? "rediss" : "redis"), + host, + port, + tlsEnabled: isTLS, + }); }); redisClient.on("close", () => {