Files
2026-06-15 06:16:16 +08:00

7.4 KiB

AGENTS.md — Project Conventions for new-api

Overview

AI API gateway/proxy (Go) aggregating 40+ upstream AI providers behind a unified API, with user management, billing, rate limiting, and a React admin dashboard.

  • Backend: Go 1.25+, Gin, GORM v2, testify
  • Frontend: Two themes — web/default/ (React 19, Rsbuild, Base UI, Tailwind CSS 4, TanStack Router) and web/classic/ (React 18, Vite, Semi Design). Default is the primary.
  • Databases: SQLite, MySQL >= 5.7.8, PostgreSQL >= 9.6 (all three supported simultaneously)
  • Cache: Redis (go-redis) + in-memory
  • Auth: JWT, WebAuthn/Passkeys, OAuth (GitHub, Discord, OIDC)
  • Desktop: Electron app at electron/

Architecture

Layered: router/controller/service/model/

router/         — HTTP routing (api, relay, dashboard, web)
controller/     — Request handlers
service/        — Business logic
model/          — Data models and DB access (GORM), auto-migrations
relay/          — AI relay/proxy with 40+ provider adapters in relay/channel/
middleware/     — Auth, rate limiting, CORS, logging, distribution
setting/        — Config management (ratio, model, operation, system, performance)
common/         — Shared utilities (JSON, crypto, Redis, env, rate-limit, etc.)
dto/            — Request/response DTOs
constant/       — API types, channel types, context keys
types/          — Relay format types, file sources, errors
i18n/           — Backend i18n (go-i18n, 3 locales: en, zh-CN, zh-TW)
oauth/          — OAuth provider implementations
pkg/            — Internal packages: cachex, ionet, billingexpr, perf_metrics
web/            — Frontend themes: web/default/, web/classic/

Key Conventions

1. JSON — Use common/json.go wrappers

All marshal/unmarshal MUST use common.Marshal, common.Unmarshal, etc. Do NOT call encoding/json directly in business code. Type definitions from encoding/json (e.g. json.RawMessage) are still fine to reference.

2. Cross-DB Compatibility (SQLite, MySQL, PostgreSQL)

  • Prefer GORM methods over raw SQL.
  • Use commonGroupCol, commonKeyCol, commonTrueVal, commonFalseVal from model/main.go for reserved words and boolean literals.
  • Branch DB-specific logic with common.UsingPostgreSQL, common.UsingSQLite, common.UsingMySQL.
  • Forbidden without cross-DB fallback: MySQL-only GROUP_CONCAT, PostgreSQL @>/JSONB operators, ALTER COLUMN on SQLite, DB-specific column types (use TEXT for JSON).
  • Migrations must pass on all three DBs.

3. Frontend — Bun required

Use bun (not npm/yarn/pnpm) for web/default/:

  • bun install / bun run dev / bun run build
  • See web/default/AGENTS.md for detailed frontend conventions (i18n, components, forms, routing, etc.)

4. New Channel — StreamOptions

When adding a channel, check if the provider supports StreamOptions. If so, add the channel type to streamSupportedChannels in relay/common/relay_info.go:320.

5. Protected Identity — DO NOT Modify

Do NOT remove, rename, or replace any reference to new-api (project) or QuantumNous (organization). This includes README, HTML titles, Go module paths, Docker images, package metadata, comments, and deployment configs.

6. Upstream DTOs — Pointer Types for Zero Values

Optional scalar fields in request structs that are parsed from client JSON and re-marshaled to upstream providers MUST use pointer types (*int, *float64, *bool, etc.) with omitempty. Non-nil pointer = preserve zero value. Non-pointer scalars with omitempty silently drop zeros.

7. Billing Expressions — Read pkg/billingexpr/expr.md

When working on tiered/dynamic billing, read pkg/billingexpr/expr.md first. It documents the expression language, system architecture, token normalization, and settlement rules.

Development

Run Backend

cp .env.example .env       # edit as needed
go run main.go             # starts on :3000

Build (matches CI/Docker)

The VERSION file is created by CI (from git tag). For a manual build:

echo "dev" > VERSION
(cd web/default && bun install && DISABLE_ESLINT_PLUGIN='true' bun run build)
go build -ldflags "-s -w -X 'github.com/QuantumNous/new-api/common.Version=$(cat VERSION)'" -o new-api

Run Backend Tests

go test ./...                          # all packages
go test ./pkg/billingexpr/...          # single package

Run Frontend Dev

cd web/default && bun install && bun run dev
# proxies /api, /mj, /pg -> http://localhost:3000 (configurable via VITE_REACT_APP_SERVER_URL)

Other Scripts

cd web/default && bun run typecheck    # tsc -b
cd web/default && bun run lint         # eslint
cd web/default && bun run format       # prettier --write
cd web/default && bun run i18n:sync    # sync translation key structure
cd web/default && bun run knip         # dead code detection
cd web/default && bun run build:check  # typecheck + build

Frontend Dev Server Management

Background dev server (stays alive after tool invocation):

# Start (background, log to /tmp/frontend.log)
cd web/default && setsid bun run dev > /tmp/frontend.log 2>&1 &

# Stop
pkill -f "bun run dev"

# Restart
pkill -f "bun run dev" && cd web/default && setsid bun run dev > /tmp/frontend.log 2>&1 &

# Check status
ps aux | grep -E "rsbuild|bun" | grep -v grep

# View logs
tail -f /tmp/frontend.log

OpenAPI Specs

  • Admin API: docs/openapi/api.json (131 endpoints)
  • Relay API: docs/openapi/relay.json (30+ endpoints)

CI/Docker

  • Docker image: calciumion/new-api. Multi-arch (amd64 + arm64). Multi-stage build: bun builds frontend, then Go builds the binary with embedded //go:embed web/default/dist.
  • PRs are checked by peakoss/anti-slop (requires PR template, description, no AI-generated markers).
  • Tags trigger Docker pushes.

Local Dev + Production Deployment

Environment Layout

Item Dev (chaos user) Prod (www user)
Directory /home/chaos/new-api/ /home/www/new-api-prod/
Port localhost:3000 (API) / localhost:5173 (frontend hot-reload) localhost:3001
Config docker-compose.dev.yml /home/www/new-api-prod/docker-compose.prod.yml
Data Docker volume dev_data /home/www/new-api-prod/data/

Git Remotes

  • originhttps://git.nomsg.cn/chaos/chaos-api.git (fork, push here)
  • upstreamhttps://github.com/QuantumNous/new-api.git (official, pull from here)

Daily Workflow

# Sync upstream (auto-triggers deploy via post-merge hook)
git fetch upstream && git merge upstream/main

# Manual deploy
./deploy.sh

Deploy Script (deploy.sh)

Located at project root. Does three things:

  1. Builds frontend (web/default/) with bun
  2. Builds Docker image my-new-api:latest
  3. Restarts production containers as www user via sudo -u www docker compose ...

Git Hook

.git/hooks/post-merge automatically runs ./deploy.sh after git merge.

Permission Isolation

  • chaos: owns code, builds images, triggers deploy via sudoers whitelist
  • www: owns production data dir, runs production containers
  • sudoers rule: /etc/sudoers.d/chaos-deploy — chaos can only run docker compose -f /home/www/new-api-prod/docker-compose.prod.yml * as www

Production Secrets

Stored in /home/www/new-api-prod/.env (owned by www, mode 600). Contains:

  • DB_PASS — PostgreSQL password
  • REDIS_PASS — Redis password
  • SESSION_SECRET — multi-node session secret