[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-92395":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},92395,"gateway","superagent-ai\u002Fgateway","superagent-ai","A tiny Rust gateway for running coding agents across model providers safely.","",null,"Rust",62,5,53,0,9,40.23,false,"main",true,[],"2026-07-22 04:02:06","# Superagent Gateway\n\n**A tiny Rust gateway for running coding agents across model providers safely.**\n\nPoint Claude Code and Codex at one local endpoint and run them on any model —\nKimi, GPT, Qwen, Claude, or anything OpenAI-compatible.\n\n```mermaid\nflowchart LR\n    subgraph Clients\n        claude[\"Claude Code\"]\n        codex[\"Codex CLI\"]\n    end\n\n    gateway[\"gateway\"]\n\n    subgraph Providers\n        hosted[\"OpenRouter · OpenAI · Anthropic · Moonshot · ...\"]\n        local[\"vLLM · Ollama · any OpenAI-compatible server\"]\n    end\n\n    claude --> gateway\n    codex --> gateway\n    gateway --> hosted\n    gateway --> local\n```\n\n- **Native protocol per client.** Claude Code gets an Anthropic Messages API,\n  Codex gets an OpenAI Responses API. The gateway translates bodies, streams,\n  tool calls, and reasoning between them and whatever the provider speaks.\n- **One config file.** Name your models once, assign them to traffic roles\n  (`main`, `subagent`, `background`) per client. The name you write is the id\n  you use everywhere.\n- **Tool-loop-safe fallback.** Retries and failover happen only before a\n  response starts streaming — a model that has begun answering or calling a\n  tool is never silently swapped.\n- **Small and boring on purpose.** Single binary, one YAML file, structured\n  JSON logs, ~60 MB Docker image. A compatibility layer for coding agents,\n  not a universal LLM platform.\n\n## Run\n\n```bash\ncargo build --release\n.\u002Ftarget\u002Frelease\u002Fgateway --config .\u002Fgateway.yaml\n```\n\nThe default config path is `.\u002Fgateway.yaml`. `.env.local` \u002F `.env` are loaded\nautomatically for provider API keys.\n\n### Secrets\n\n`gateway.yaml` should never contain real secrets, and it doesn't need to:\n\n- Provider keys are read from env vars by convention (`OPENROUTER_API_KEY`,\n...) — put them in `.env.local` (gitignored, auto-loaded) or the process\nenvironment.\n- Any config value can reference an env var with `${VAR}` syntax, e.g.\n`token: \"${GATEWAY_TOKEN}\"`. Missing variables fail at startup.\n- `GATEWAY_TOKEN` \u002F `GATEWAY_BIND` env vars override auth token and bind\naddress directly (handy for containers).\n\n\n\n### Docker\n\n```bash\ndocker build -t gateway .\ndocker run -p 4000:4000 \\\n  -v .\u002Fgateway.yaml:\u002Fetc\u002Fgateway\u002Fgateway.yaml:ro \\\n  -e OPENROUTER_API_KEY \\\n  gateway\n```\n\nOr `docker compose up` (see `docker-compose.yml`). The image sets\n`GATEWAY_BIND=0.0.0.0:4000` so the server is reachable from outside the\ncontainer; auth tokens are mandatory for non-localhost binds, so keep a token\nin the config or pass `GATEWAY_TOKEN`. Cloud platforms can probe\n`GET \u002Fhealth` for liveness. Env overrides:\n\n```text\nGATEWAY_BIND   listen address (overrides server.bind)\nGATEWAY_TOKEN  extra accepted auth token (appended to server.token\u002Ftokens)\n```\n\n\n\n## Configuration\n\nFour sections: `server`, `providers`, `models`, `clients`.\n\n```yaml\nserver:\n  token: local-dev-token\n\nproviders:                       # only for what presets can't know\n  azure: { resource: my-foundry }\n\nmodels:\n  gpt-55: azure\u002Fgpt-5.5\n  kimi-27: openrouter\u002Fmoonshotai\u002Fkimi-k2.7-code\n\nclients:\n  claude_code:\n    main: [gpt-55, kimi-27]      # list = fallback chain, pre-stream only\n    subagent: kimi-27            # Task-tool subagents (claude-opus-* ids)\n    background: kimi-27          # titles\u002Fsummaries (claude-haiku-* ids)\n  codex:\n    main: kimi-27\n```\n\nKnown providers imply their base URL and key env var:\n\n\n| Provider     | Key env var          | Notes                                |\n| ------------ | -------------------- | ------------------------------------ |\n| `openrouter` | `OPENROUTER_API_KEY` |                                      |\n| `openai`     | `OPENAI_API_KEY`     |                                      |\n| `anthropic`  | `ANTHROPIC_API_KEY`  | Anthropic wire protocol              |\n| `moonshot`   | `MOONSHOT_API_KEY`   |                                      |\n| `fireworks`  | `FIREWORKS_API_KEY`  |                                      |\n| `together`   | `TOGETHER_API_KEY`   |                                      |\n| `groq`       | `GROQ_API_KEY`       |                                      |\n| `deepinfra`  | `DEEPINFRA_API_KEY`  |                                      |\n| `deepseek`   | `DEEPSEEK_API_KEY`   |                                      |\n| `mistral`    | `MISTRAL_API_KEY`    |                                      |\n| `xai`        | `XAI_API_KEY`        |                                      |\n| `cerebras`   | `CEREBRAS_API_KEY`   |                                      |\n| `ollama`     | —                    | local, `http:\u002F\u002Flocalhost:11434\u002Fv1`   |\n| `azure`      | `AZURE_AI_API_KEY`   | needs `resource:` under `providers:` |\n\n\nAnything else is declared under `providers:` with a `base_url` (add\n`type: anthropic` for Anthropic-protocol upstreams).\n\nKnown model families get capabilities from a built-in quirk table (Kimi:\nfixed sampling stripped, reasoning preserved, vision; GPT\u002FClaude: vision;\nClaude: native tools + cache). Override per model with the long form:\n\n```yaml\nmodels:\n  qwen-local:\n    model: vllm-local\u002Fqwen3-coder\n    images: false\n    tools: openai            # openai | native | none\n    thinking: none            # native | none\n    drop_params: [presence_penalty]\n    timeout_ms: 120000\n    expose: [codex]           # hide from other clients\n```\n\nThe name you give a model in `models:` is the id you use everywhere —\n`claude --model kimi` and Codex's `model = \"kimi\"` alike. Unrecognized model\nids (Claude Code pins concrete `claude-opus-*` \u002F `claude-haiku-*` ids for\nsubagents and background tasks) route to the `subagent` \u002F `background` roles,\nand anything else to `unknown` (default `main`, or `reject` to 404).\n\n## Claude Code setup\n\n```bash\nexport ANTHROPIC_BASE_URL=\"http:\u002F\u002Flocalhost:4000\u002Fanthropic\"\nexport ANTHROPIC_AUTH_TOKEN=\"local-dev-token\"\n\nclaude --model kimi\n```\n\n\n\n## Codex setup\n\nCodex ignores provider\u002Fauth overrides in project-local config, so configure\nthe provider at user level in `~\u002F.codex\u002Fconfig.toml`:\n\n```toml\nmodel = \"main\"\nmodel_provider = \"gateway\"\n\n[model_providers.gateway]\nname = \"Gateway\"\nbase_url = \"http:\u002F\u002Flocalhost:4000\u002Fopenai\u002Fv1\"\nenv_key = \"GATEWAY_TOKEN\"\nwire_api = \"responses\"\n```\n\n```bash\nexport GATEWAY_TOKEN=\"local-dev-token\"\ncodex\n```\n\n\n\n## Endpoints\n\n```text\nGET  \u002Fhealth\nHEAD \u002F\n\nPOST \u002Fanthropic\u002Fv1\u002Fmessages               (alias: \u002Fv1\u002Fmessages)\nPOST \u002Fanthropic\u002Fv1\u002Fmessages\u002Fcount_tokens  (alias: \u002Fv1\u002Fmessages\u002Fcount_tokens)\nGET  \u002Fanthropic\u002Fv1\u002Fmodels                 (alias: \u002Fv1\u002Fmodels)\n\nPOST \u002Fopenai\u002Fv1\u002Fresponses                 (alias: \u002Fv1\u002Fresponses)\nGET  \u002Fopenai\u002Fv1\u002Fmodels                    (alias: \u002Fv1\u002Fmodels)\n```\n\nAuth: `Authorization: Bearer \u003Ctoken>` or `x-api-key: \u003Ctoken>`, checked against\n`auth.tokens` in the config. Binding to a non-localhost address without tokens\nis refused at startup.\n\n## Routing and fallback\n\nEach model alias declares a per-client compatibility level (`full`, `tools`,\n`degraded_tools`, `text_only`, `responses_bridge`, `blocked`) and a list of\nroutes with capability flags. Requests are classified (tools, tool results,\nimages, thinking, cache_control, streaming) and only capability-satisfying\nroutes are eligible.\n\nFallback policy:\n\n- Retry the first route once with jitter on retryable failures\n(connection errors and `fallback.retryable_statuses`), then walk the\nremaining routes, capped at `fallback.max_attempts`.\n- Fallback happens only before user-visible output. Once a text delta or tool\ncall has been streamed, a failure is surfaced to the client as an SSE error\nevent; the request is never silently replayed.\n- Degraded routes borrowed from other models via a per-model `fallback.routes`\nlist require `allow_degraded_fallback: true`.\n- Non-retryable upstream errors are forwarded verbatim (status and body),\nbecause Claude Code's retry behavior depends on the original error wording.\n\n\n\n## Observability\n\nOne structured JSON log line per attempt with `request_id`, `client`,\n`model_alias`, `route_id`, `attempt`, `stream`, `status`, `fallback_used`,\n`duration_ms`, and the Claude Code session id when present. Prompts are not\nlogged unless `telemetry.log_prompts: true`, which logs the full request body\nfor replay.\n\n## Tests\n\n```bash\ncargo test\n```\n\nUnit tests cover the four body translators, the stream state machines, the\nclassifier, and route eligibility. Integration tests run the gateway against\nmocked Anthropic and OpenAI upstreams, including pre-stream fallback on 429\nand the blocked-fallback-after-output case.","Superagent Gateway 是一个轻量级 Rust 编写的 API 网关，用于安全、统一地调度编程类 AI 代理（如 Claude Code、Codex）对接多种大模型服务商。它支持协议转换（Anthropic Messages ↔ OpenAI Compat）、模型路由配置、工具调用语义保真、流式响应不中断的故障隔离，并通过单 YAML 文件管理模型角色（main\u002Fsubagent\u002Fbackground）。适用于本地开发、CI\u002FCD 中的编码代理集成、多模型 A\u002FB 测试及企业内网中对模型提供商的抽象与管控场景。",2,"2026-07-08 04:30:16","CREATED_QUERY"]