Open-source AI gateway · Bidirectional protocol conversion · Tag-based routing
Speak Anthropic, OpenAI, or Responses on the client side — any of them on the provider side. AginxBrain converts between them, routes by tag, and fails over automatically.
Features · Architecture · Quick Start · Configuration · Comparison
AginxBrain sits between your AI client (Claude Code, Codex CLI, any OpenAI / Anthropic / Responses SDK) and your model providers, and does four things transparently:
- Protocol conversion — clients speak Anthropic Messages, OpenAI Chat, or OpenAI Responses; providers speak any of the three. All 9 combinations, both directions, streaming included.
- Tag-based routing — call a model by its tag name (e.g.
model: "sonnet",model: "gpt-5.5") and AginxBrain maps it to the right provider and model, with multi-candidate failover chains. - Reliability — per-route circuit breaker, automatic failover on retryable errors, smart auto-routing that upgrades the tier based on the request, hot-reloaded config.
- Key custody & observability — providers' real keys live in one place behind per-caller API keys; every request is logged with token usage and estimated cost.
It runs in two shapes:
- Server (the gateway) — a single self-hosted binary. Holds all the keys, runs the proxy, embeds an admin dashboard at
http://host:port/. - Desktop (the client) — a thin Tauri app for monitoring calls and one-click Claude Code / Codex takeover. Enter your server URL + API key to log in — no local proxy, no keys on disk.
AginxBrain 是 Aginx Agent 互联网生态中的「大脑」层:Agent 只表达需求(对话、生图、语音……),AginxBrain 负责选 provider、转格式、failover、审计。
| Client ↓ / Provider → | OpenAI Chat | OpenAI Responses | Anthropic |
|---|---|---|---|
| Anthropic Messages (Claude Code) | ✅ | ✅ | ✅ passthrough |
| OpenAI Chat | ✅ passthrough | ✅ | ✅ |
| OpenAI Responses (Codex CLI) | ✅ | ✅ passthrough | ✅ |
Streaming SSE is fully converted across formats — thinking, text, tool_use, and usage all translate correctly. Send stream: true with stream_options: {include_usage: true} and the final chunk carries correct token counts.
Tags are model aliases — you define any name in config, use it as the model field in requests, and AginxBrain maps it to the right provider:
model: "opus" → Zhipu GLM-5.1
model: "sonnet" → DeepSeek v4-pro ──┐ failover chain
model: "gpt-5.5" → Qwen-3-235b │ on 429 / timeout / 5xx
model: "image" → DashScope wan2.7 │
model: "auto" → smart-routing decides ──┘
A tag is just a name. opus, sonnet, haiku are common choices — but you can name tags anything: gpt-5.5, image, tts, fast… each maps to one or more routes.
- Each tag resolves to an ordered list of candidate routes; the next route is tried when the current one fails with a retryable error (timeout, 5xx, 429, connection error).
- Circuit breaker — a route that fails 3 times in a row is opened for a 60s cooldown, then probed once (half-open) before traffic resumes. Keyed per-route, in-memory only.
- If the model name doesn't match any tag, it falls back to
current_tag— no request is ever dropped. AginxBrain also tries substring matching (e.g.claude-sonnet-4-6matches thesonnettag).
When a request hits a tag marked is_auto: true (e.g. auto), AginxBrain inspects the body and resolves it to a specific tag:
| Signal | Example | Resolves to |
|---|---|---|
agentic |
request carries tools / tool calls |
sonnet |
reasoning |
"think step by step" / 推理 markers | opus |
complex_coding |
heavy Edit/Write/Bash patterns | opus |
code_pattern |
fenced code blocks | sonnet |
subagent |
short system prompt + delegated task | haiku |
The signal-to-tag mapping is fully configurable. Internally, smart routing uses a tier system (haiku < sonnet < opus) to pick the right tag — but the actual tag names come from your config, not from a fixed tier list.
A per-session, upgrade-only cache (30 min TTL) means once a conversation needs a stronger model, it never downgrades. Zero ML, pure string/JSON matching, sub-millisecond overhead. Fully configurable via signal_tiers in config.yaml.
- Per-modality timeouts: 45s non-streaming, 120s for reasoning, 3600s streaming, 10s connect.
- Circuit breaker prevents failover storms from hammering a dead provider.
reasoning_contentstripped from fast/haiku tiers so classifiers and simple chat stay clean.output_tokensis always present in usage (safety-filled when a provider omits it) so clients that divide by token count never crash.
- Admin access — session-based login (username/password), set up on first run.
management_keyis legacy and ignored for auth. - Per-caller API keys — hashed in SQLite, plaintext shown once at creation. Send as
Authorization: Bearer <key>(OpenAI / Codex) orx-api-key: <key>(Anthropic / Claude Code). - Usage & cost — every request logged with input/output tokens + estimated cost, aggregated daily / monthly / all-time, per caller. Per-provider-per-model cost rates are configurable.
- Provider health dashboard — success rate, average latency, token volume, and live circuit state per provider.
Image generation (DashScope wan2.7, MiniMax, OpenAI images), TTS & ASR (DashScope WebSocket, Whisper), vision, and video synthesis — all behind the same tag-routing surface, dispatched by the route's format.
The desktop client (or the admin UI) rewrites your real client config for you, with one-click restore:
- Claude Code — writes
~/.claude/settings.json(ANTHROPIC_BASE_URL+ token) to point at your AginxBrain server. - Codex CLI — writes
~/.codex/config.toml+auth.jsonwithmodel_provider = "aginxbrain",wire_api = "responses".
Both local-proxy (http://127.0.0.1:{port}) and remote-server (https://brain.aginx.net) forms are supported.
Edit ~/.aginxbrain/config.yaml and changes (providers, routes, tags, cost rates) apply within ~1s — no restart. Only port / host require a restart (the TCP listener is already bound).
Claude Code / Codex CLI / any SDK
│ HTTP (Anthropic | OpenAI | Responses)
▼
AginxBrain Server (Rust · axum)
├── protocol conversion (9-way, streaming)
├── tag routing + failover + circuit breaker
├── smart auto-routing (signal → tier)
├── usage logging + cost (SQLite)
└── admin dashboard (embedded SPA)
│
┌──────────┼──────────┬──────────┐
▼ ▼ ▼ ▼
OpenAI Responses Anthropic Image/TTS/ASR/Video
(DeepSeek) (DashScope) (Zhipu…) (wan2.7 / Whisper…)
Two binaries share one codebase:
| Build | Mode | What it is |
|---|---|---|
aginxbrain --server (--features server) |
Gateway | The proxy + admin dashboard + SQLite. Self-host this. |
aginxbrain (default desktop feature) |
Thin client | A Tauri app that connects to a remote gateway. Monitor calls, one-click takeover of Claude Code / Codex. No local proxy. |
Desktop → Server flow:
Desktop app Server
│ │
├─ enter server URL ────→│
├─ enter API key ───────→│ (auth as a caller)
├─ monitor calls ───────→│ (usage logs, health, circuit state)
└─ takeover Claude/Codex →│ (rewrite local config to point at server)
aginxbrain/
├── src-tauri/src/
│ ├── proxy.rs # proxy core: routing, failover, circuit breaker, multimodal
│ ├── convert/ # protocol conversion (requests / responses / streaming)
│ ├── config.rs # config + hot-reload + circuit-breaker state + AppState
│ ├── smart_routing.rs # signal detection → tier upgrade
│ ├── api.rs # admin REST API (CRUD, auth, usage, health)
│ ├── takeover.rs # writes ~/.claude, ~/.codex (local + remote)
│ ├── db.rs # SQLite (sessions, caller keys, usage, cost rates)
│ └── axum_server.rs # router, auth middleware, embedded SPA
├── web/ # admin dashboard SPA (embedded into the server build)
└── web-client/ # thin-client SPA (bundled into the desktop build)
git clone https://github.com/yinnho/AginxBrain.git
cd AginxBrain
# Build the web dashboard (embedded into the server at compile time)
cd web && pnpm install && pnpm build && cd ..
# Build & run the server binary
cd src-tauri && cargo build --release --no-default-features --features server
./target/release/aginxbrain --server # binds 0.0.0.0:8083Open http://localhost:8083/, create the admin account on first launch, then add providers/routes in the dashboard.
systemd unit (production)
# /etc/systemd/system/aginxbrain.service
[Unit]
Description=AginxBrain AI gateway
After=network.target
[Service]
ExecStart=/usr/local/bin/aginxbrain --server
Restart=on-failure
Environment=RUST_LOG=info
[Install]
WantedBy=multi-user.targetGrab the installer for your platform from Releases (macOS / Windows / Linux), or build it:
cd web-client && pnpm install && pnpm build && cd ..
cd src-tauri && cargo tauri buildLaunch it, enter your server URL + caller API key to log in. You can then monitor all calls through the dashboard, and takeover Claude Code or Codex with one click — the app rewrites the local config so your CLI flows through the gateway.
The easiest way is one-click takeover from the desktop client or the admin UI — it automatically rewrites your Claude Code / Codex config to point at the gateway. No manual setup needed.
To connect manually (e.g. custom SDK integrations), use your server URL and a caller API key from the dashboard:
# Claude Code
export ANTHROPIC_BASE_URL=https://brain.aginx.net/anthropic
export ANTHROPIC_API_KEY=agk-xxxxxxxx
# Any OpenAI client
openai --base-url https://brain.aginx.net/v1 --api-key agk-xxxxxxxxConfig lives at ~/.aginxbrain/config.yaml (override with AGINXBRAIN_CONFIG). Providers hold only auth; routes own their base_url.
port: 8083
host: 127.0.0.1 # server mode defaults to 0.0.0.0
current_tag: auto
providers: # name + key + auth only (no base_url here)
deepseek:
name: DeepSeek
api_key: sk-your-key
auth_type: bearer # bearer | x_api_key | x_goog_api_key
routes: # base_url lives on the route
- base_url: https://api.deepseek.com
model: deepseek-v4-pro
provider: deepseek
tags: [sonnet, auto]
format: openai # see formats table below
tool_mode: native # native | react_xml
- base_url: https://open.bigmodel.cn/api/anthropic
model: glm-5.1
provider: zhipu
tags: [opus]
format: anthropic # passthrough from Claude Code
tags:
- { name: opus, color: "#A855F7" }
- { name: sonnet, color: "#3B82F6" }
- { name: haiku, color: "#22C55E" }
- { name: auto, color: "#F59E0B", is_auto: true }
smart_routing: # tune the auto tier
enabled: true
cache_ttl_secs: 1800
cache_max_sessions: 1024
signal_tiers:
agentic: sonnet
reasoning: opus
complex_coding: opus
subagent: haiku
code_pattern: sonnetformat |
Wire format | Upstream path derived |
|---|---|---|
openai |
OpenAI Chat Completions | /v1/chat/completions |
openai_responses |
OpenAI Responses | /v1/responses |
anthropic |
Anthropic Messages | /v1/messages |
openai_images |
OpenAI image generation | /v1/images/generations |
dashscope_image |
DashScope multimodal image | …/multimodal-generation/generation |
dashscope_chat_image |
DashScope chat image | /chat/completions |
dashscope_tts / dashscope_asr |
DashScope TTS / ASR (WebSocket) | per-format |
dashscope_video / kling |
video synthesis | per-format |
minimax_image |
MiniMax image generation | /v1/image_generation |
tool_mode |
Behavior |
|---|---|
native (default) |
Pass tools through as native function-calling |
react_xml |
Inject tool definitions as XML into the system prompt and parse <tool_use> blocks from the response — lets models without native function calling work with Claude Code |
| Endpoint | Protocol |
|---|---|
POST /v1/chat/completions, /openai/v1/chat/completions |
OpenAI Chat |
POST /v1/messages, /anthropic/v1/messages (+ /count_tokens) |
Anthropic Messages |
POST /v1/responses, /openai/v1/responses, /responses (+ /compact) |
OpenAI Responses (Codex) |
GET /v1/models, /models |
model list (Codex-compatible) |
/api/admin/{setup,login,logout,me} · /api/keys · /api/cost-rates · /api/usage/{daily,monthly,summary,provider-health} · /api/circuit-breaker · /api/{config,routes,providers,tags} (CRUD) · /api/test · /api/logs · /api/takeover/{claude,codex} · /api/status
| Routes | Providers |
|---|---|
![]() |
![]() |
| Takeover | Tags |
|---|---|
![]() |
![]() |
Most LLM gateways (One API, OpenRouter, Helicone) expose an OpenAI-compatible input only — so Claude Code (Anthropic Messages) and Codex (Responses) can't connect unchanged, and they route by exact model name. AginxBrain is protocol-native in both directions and routes by tag name:
| AginxBrain | LiteLLM | Portkey | New / One API | OpenRouter | |
|---|---|---|---|---|---|
| Anthropic Messages input | ✅ | ✅ | ✅ | ✅ | ✅ |
| OpenAI Responses input (Codex) | ✅ | partial | ✅ | ✅ | ❌ |
| Bidirectional conversion (Anthropic client ↔ Anthropic provider, etc.) | ✅ | partial | partial | ❌ | ❌ |
| One-click Claude Code / Codex takeover | ✅ | ❌ | ❌ | ❌ | ❌ |
| Tag-based routing (model aliases) + auto-tier | ✅ | ❌ | ❌ | ❌ | ❌ |
| China providers first-class (DeepSeek, GLM, Kimi, Qwen, ERNIE) | ✅ | partial | partial | ✅ | ✅ |
| Self-host single binary + embedded admin UI | ✅ Rust | Python | ❌ SaaS | ✅ | ❌ SaaS |
Full breakdown: COMPARISON.md · 中文省钱攻略: ARTICLE.md
AginxBrain is the AI-capability gateway of the Aginx ecosystem — Agent infrastructure modeled on the internet stack:
| Component | Role | Analogy |
|---|---|---|
| aginx | Agent interconnect (ACP routing) | nginx |
| aginxbrain | unified AI-capability entry | the brain |
| aginx-api | registry / discovery / auth | DNS |
| aginx-relay | NAT traversal / forwarding | CDN |
| aginxium | unified client engine | Chromium |
MIT · © 2026 yinnho



