Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ Claude Code is a powerful, production-grade AI coding assistant — but its sour

| Feature | Details |
|---|---|
| Multi-provider | Anthropic · OpenAI · Gemini · Kimi · Qwen · Zhipu · DeepSeek · MiniMax · OpenRouter · Ollama · LM Studio · Custom endpoint |
| Multi-provider | Anthropic · OpenAI · Gemini · Kimi · Qwen · Zhipu · DeepSeek · MiniMax · OpenRouter · Requesty · Ollama · LM Studio · Custom endpoint |
| Agent loop | Streaming API + automatic tool-use loop; the whole loop is in `agent.py` |
| 28 built-in tools | Read · Write · Edit · Bash · Glob · Grep · WebFetch · WebSearch · NotebookEdit · GetDiagnostics · Memory* · Agent/SendMessage · Skill · AskUserQuestion · Task* · SleepTimer · EnterPlanMode/ExitPlanMode · *(MCP + plugin tools auto-added)* |
| Tool profiles | `tool_profile` trims the tool surface sent each turn to save prompt tokens: `full` (default, everything) · `standard` (compact coding) · `research` (web + documents) · `orchestration` (agents + tasks). Set with `/config tool_profile=standard`. [Guide](docs/guides/usage.md#tool-profiles-tool_profile) |
Expand Down Expand Up @@ -212,10 +212,13 @@ Claude Code is a powerful, production-grade AI coding assistant — but its sour
| **DeepSeek** | `deepseek-chat` · `deepseek-reasoner` | 64k | `DEEPSEEK_API_KEY` |
| **MiniMax** | `MiniMax-Text-01` · `MiniMax-VL-01` · `abab6.5s-chat` | 256k–1M | `MINIMAX_API_KEY` |
| **OpenRouter** _(400+ models, one key)_ | `openrouter/deepseek/deepseek-v4-flash` · `openrouter/anthropic/claude-sonnet-4-6` · `openrouter/openai/gpt-5` | varies | `OPENROUTER_API_KEY` |
| **Requesty** _(700+ models, one key)_ | `requesty/openai/gpt-4o-mini` · `requesty/anthropic/claude-sonnet-4-6` · `requesty/claude-sonnet-4-6` | varies | `REQUESTY_API_KEY` |
| **AWS Bedrock / Azure / Vertex** _(via litellm)_ | `litellm/<provider>/<model>` | varies | provider-specific |

> **`openrouter/` gateway:** one key for 400+ models across vendors. The model ID keeps OpenRouter's upstream `<vendor>/<model>` path, so the call is double-prefixed: `openrouter/deepseek/deepseek-v4-flash`. To pin which upstream provider (and quantization) serves the request, append `@<provider>[/<quantization>]` — `openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8` — which is sent as OpenRouter's `provider` request-body object rather than glued into the model ID. See [usage.md](docs/guides/usage.md#openrouter-400-models-one-key).

> **`requesty/` gateway:** works the same way: everything after `requesty/` is sent as the model ID, either a catalog `<vendor>/<model>` path (`requesty/openai/gpt-4o-mini`) or a managed policy ID (`requesty/claude-sonnet-4-6`). Managed policy IDs ending in `@eu` (`requesty/gpt-5-mini@eu`) route through EU providers only. See [usage.md](docs/guides/usage.md#requesty-700-models-one-key).

> **`litellm/` adapter:** routes to 100+ providers behind one SDK — mainly for upstreams with awkward auth (Bedrock SigV4, Azure deployment routing, Vertex service-account JWTs). For plain OpenAI-shaped endpoints, prefer the zero-dependency `custom/` adapter. Install with `pip install ".[litellm]"`. See [recipes.md](docs/guides/recipes.md#alternative-cloud-providers-with-non-trivial-auth-via-the-litellm-provider).

### Open-Source (Local via Ollama)
Expand Down Expand Up @@ -311,7 +314,7 @@ cheetahclaws --model gpt-4o # pick any model
cheetahclaws --model deepseek-chat --thinking --verbose
```

Provider get-key pages: [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com) · [Kimi](https://platform.moonshot.cn) · [Qwen](https://dashscope.aliyun.com) · [Zhipu](https://open.bigmodel.cn) · [DeepSeek](https://platform.deepseek.com) · [MiniMax](https://platform.minimaxi.chat) · [OpenRouter](https://openrouter.ai/keys).
Provider get-key pages: [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com) · [Kimi](https://platform.moonshot.cn) · [Qwen](https://dashscope.aliyun.com) · [Zhipu](https://open.bigmodel.cn) · [DeepSeek](https://platform.deepseek.com) · [MiniMax](https://platform.minimaxi.chat) · [OpenRouter](https://openrouter.ai/keys) · [Requesty](https://app.requesty.ai/api-keys).

**One key for 400+ models** — [OpenRouter](https://openrouter.ai) fronts every major vendor behind one OpenAI-compatible endpoint, so a single key covers Claude, GPT, Gemini, DeepSeek, Llama, Qwen and the rest:

Expand All @@ -322,6 +325,14 @@ cheetahclaws --model openrouter/anthropic/claude-sonnet-4-6
cheetahclaws --model openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8 # pin the upstream provider
```

[Requesty](https://www.requesty.ai) is another one-key gateway (700+ models, OpenAI-compatible):

```bash
export REQUESTY_API_KEY=rqsty-...
cheetahclaws --model requesty/openai/gpt-4o-mini
cheetahclaws --model requesty/claude-sonnet-4-6 # managed policy ID
```

**AWS Bedrock / Azure / Vertex** use the `litellm/<provider>/<model>` form (`pip install ".[litellm]"`) — full env-var recipes in [recipes.md](docs/guides/recipes.md#alternative-cloud-providers-with-non-trivial-auth-via-the-litellm-provider).

> **Full per-provider guide** — every provider's get-key page + example model commands, plus Bedrock/Azure/Vertex env-var recipes: [docs/guides/usage.md](docs/guides/usage.md).
Expand Down Expand Up @@ -387,11 +398,12 @@ cheetahclaws --model ollama/qwen2.5-coder # 2. provider/model
cheetahclaws --model kimi:moonshot-v1-32k # 3. provider:model
```

**Gateways keep the upstream path.** OpenRouter, NIM and LiteLLM address models by a `<vendor>/<model>` path of their own, so those calls are double-prefixed — only the **first** segment is the provider, everything after it is passed through verbatim:
**Gateways keep the upstream path.** OpenRouter, Requesty, NIM and LiteLLM address models by a `<vendor>/<model>` path of their own, so those calls are double-prefixed — only the **first** segment is the provider, everything after it is passed through verbatim:

```bash
cheetahclaws --model openrouter/deepseek/deepseek-v4-flash # → OpenRouter, model "deepseek/deepseek-v4-flash"
cheetahclaws --model nim/meta/llama-3.3-70b-instruct # → NVIDIA NIM
cheetahclaws --model requesty/openai/gpt-4o-mini # → Requesty, model "openai/gpt-4o-mini"
cheetahclaws --model openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8 # + pinned provider / quantization
```

Expand Down
1 change: 1 addition & 0 deletions cheetahclaws/commands/config_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def cmd_model(args: str, _state, config) -> bool:
info(" e.g. /model kimi:moonshot-v1-32k")
info(" e.g. /model openrouter/deepseek/deepseek-v4-flash (multi-level: provider/upstream/model)")
info(" e.g. /model openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8 (pin provider/quantization)")
info(" e.g. /model requesty/openai/gpt-4o-mini (or a managed policy: requesty/claude-sonnet-4-6)")
else:
m = args.strip()
# "/model ollama" with no model name → interactive picker
Expand Down
33 changes: 32 additions & 1 deletion cheetahclaws/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
zhipu — Zhipu GLM (glm-4, glm-4-plus, ...)
deepseek — DeepSeek (deepseek-v4-flash, deepseek-v4-pro, deepseek-chat, deepseek-reasoner)
openrouter — OpenRouter (openrouter/deepseek/deepseek-v4-flash, ...)
requesty — Requesty (requesty/openai/gpt-4o-mini, requesty/claude-sonnet-4-6, ...)
minimax — MiniMax (MiniMax-Text-01, abab6.5s-chat, ...)
ollama — Local Ollama (llama3.3, qwen2.5-coder, ...)
lmstudio — Local LM Studio (any loaded model)
Expand All @@ -22,7 +23,8 @@
"custom/my-model" uses CUSTOM_BASE_URL from config
"openrouter/<vendor>/<model>" multi-level path: the first segment is the
provider, everything after it is passed through as the upstream model ID
(e.g. "openrouter/deepseek/deepseek-v4-flash"). Also used by nim/ and litellm/.
(e.g. "openrouter/deepseek/deepseek-v4-flash"). Also used by nim/, requesty/
and litellm/.
"openrouter/<vendor>/<model>@<provider>[/<quant>]" optional routing suffix:
pins the secondary OpenRouter provider (and quantization level) via the
`provider` request body, keeping the model field a real model ID.
Expand Down Expand Up @@ -139,6 +141,35 @@
"mistralai/mistral-large-latest",
],
},
# Requesty: LLM gateway with 700+ models behind one OpenAI-compatible
# endpoint. Get a key at https://app.requesty.ai/api-keys. Like OpenRouter,
# the model ID after the first segment is passed through verbatim, either a
# catalog <vendor>/<model> path or a managed policy ID (no vendor prefix):
# /model requesty/openai/gpt-4o-mini
# /model requesty/claude-sonnet-4-6
# Managed policy IDs ending in "@eu" route through EU providers only; the
# suffix is part of the model ID and is sent as is.
"requesty": {
"type": "openai",
"api_key_env": "REQUESTY_API_KEY",
"base_url": "https://router.requesty.ai/v1",
"context_limit": 128000,
"max_completion_tokens": 16384,
"models": [
"claude-sonnet-4-6",
"claude-haiku-4-5",
"gpt-5.4",
"gpt-5.4-mini",
"deepseek-v4-flash",
"deepseek-v4-pro",
"gemini-3.5-flash",
"kimi-k3",
"glm-5.3",
"qwen3.8-max",
"openai/gpt-4o-mini",
"anthropic/claude-sonnet-4-6",
],
},
"minimax": {
"type": "openai",
"api_key_env": "MINIMAX_API_KEY",
Expand Down
3 changes: 2 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,14 +308,15 @@ based on the model string:
"custom/my-endpoint" → custom
"nim/meta/llama-3.3-70b-instruct" → nim (build.nvidia.com free tier)
"openrouter/deepseek/deepseek-v4-flash" → openrouter (400+ models, one key)
"requesty/openai/gpt-4o-mini" → requesty (700+ models, one key)
```

`stream(model, system, messages, tool_schemas, config) -> Generator`
is the one entry point agent.py uses. Internally it dispatches to
`stream_anthropic()` (native SDK) or `stream_openai_compat()` (used by
every OpenAI-compatible provider).

**Gateway model IDs are multi-level.** OpenRouter, NIM and LiteLLM
**Gateway model IDs are multi-level.** OpenRouter, Requesty, NIM and LiteLLM
address models by an upstream `<vendor>/<model>` path, so only the first
segment is the provider and `bare_model()` deliberately strips just that
one. Two consequences the rest of the file relies on:
Expand Down
4 changes: 3 additions & 1 deletion docs/guides/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ over both `custom/` and `litellm/openrouter/…`: the base URL and key env
(`OPENROUTER_API_KEY`) are built in, the models show up in the `/model` Tab
picker, and it is the only route that supports pinning the upstream provider
with the `@<provider>[/<quantization>]` suffix. See
[usage.md](usage.md#openrouter-400-models-one-key).
[usage.md](usage.md#openrouter-400-models-one-key). The same goes for
Requesty: use `requesty/<model>` with `REQUESTY_API_KEY` rather than
`custom/` (see [usage.md](usage.md#requesty-700-models-one-key)).

---

Expand Down
5 changes: 4 additions & 1 deletion docs/guides/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ export ZHIPU_API_KEY=... # Zhipu GLM
export DEEPSEEK_API_KEY=sk-... # DeepSeek
export MINIMAX_API_KEY=... # MiniMax
export OPENROUTER_API_KEY=sk-or-... # OpenRouter (400+ models, one key)
export REQUESTY_API_KEY=rqsty-... # Requesty (700+ models, one key)
```

#### `.env` file (loaded automatically)
Expand Down Expand Up @@ -370,6 +371,7 @@ The env var always wins over any persisted value in `~/.cheetahclaws/config.json
/config deepseek_api_key=sk-...
/config minimax_api_key=...
/config openrouter_api_key=sk-or-...
/config requesty_api_key=rqsty-...
```

Keys are saved to `~/.cheetahclaws/config.json` and loaded automatically on next launch.
Expand Down Expand Up @@ -397,7 +399,8 @@ Keys are saved to `~/.cheetahclaws/config.json` and loaded automatically on next
"kimi_api_key": "sk-...",
"deepseek_api_key": "sk-...",
"minimax_api_key": "...",
"openrouter_api_key": "sk-or-..."
"openrouter_api_key": "sk-or-...",
"requesty_api_key": "rqsty-..."
}
```

Expand Down
24 changes: 24 additions & 0 deletions docs/guides/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ suffix if you would rather have OpenRouter reroute around an outage.
> tokens but estimates $0 — set a **token** budget rather than a dollar one
> if you rely on hard caps for exotic models.

### Requesty (700+ models, one key)

[Requesty](https://www.requesty.ai) is an LLM gateway with 700+ models behind
one OpenAI-compatible endpoint (`https://router.requesty.ai/v1`). Get a key at
[app.requesty.ai/api-keys](https://app.requesty.ai/api-keys); docs are at
[docs.requesty.ai](https://docs.requesty.ai).

```bash
export REQUESTY_API_KEY=rqsty-... # or: /config requesty_api_key=rqsty-...

cheetahclaws --model requesty/openai/gpt-4o-mini
cheetahclaws --model requesty/anthropic/claude-sonnet-4-6
cheetahclaws --model requesty/claude-sonnet-4-6 # managed policy ID
cheetahclaws --model requesty/gpt-5-mini@eu # EU providers only
```

As with OpenRouter, the first segment (`requesty`) is the provider and
everything after it is sent verbatim as the model ID. That can be a catalog
`<vendor>/<model>` path (the full list is at `GET /v1/models`) or a managed
policy ID with no vendor prefix (`GET /v1/models/managed`), which is a
Requesty maintained routing chain across several upstream providers for one
model. Managed policy IDs ending in `@eu` only route through EU providers.
Cost tracking uses the same per-model table as direct calls.

### LiteLLM (AWS Bedrock / Azure / Vertex AI)

Use the `litellm/` prefix when the upstream needs auth that's painful to
Expand Down
3 changes: 3 additions & 0 deletions docs/i18n/README.CN.MD
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,13 @@ Claude Code 是一款强大的、生产级的 AI 编码助手 —— 但它的
| **DeepSeek** | `deepseek-chat` · `deepseek-reasoner` | 64k | `DEEPSEEK_API_KEY` |
| **MiniMax** | `MiniMax-Text-01` · `MiniMax-VL-01` · `abab6.5s-chat` | 256k–1M | `MINIMAX_API_KEY` |
| **OpenRouter** _(400+ 模型,一把 key)_ | `openrouter/deepseek/deepseek-v4-flash` · `openrouter/anthropic/claude-sonnet-4-6` · `openrouter/openai/gpt-5` | 视情况而定 | `OPENROUTER_API_KEY` |
| **Requesty** _(700+ 模型,一把 key)_ | `requesty/openai/gpt-4o-mini` · `requesty/anthropic/claude-sonnet-4-6` · `requesty/claude-sonnet-4-6` | 视情况而定 | `REQUESTY_API_KEY` |
| **AWS Bedrock / Azure / Vertex** _(通过 litellm)_ | `litellm/<provider>/<model>` | 视情况而定 | 特定于提供商 |

> **`openrouter/` 网关:** 一把 key 覆盖跨厂商的 400+ 模型。模型 ID 保留 OpenRouter 上游的 `<vendor>/<model>` 路径,因此调用是双层前缀的:`openrouter/deepseek/deepseek-v4-flash`。若要指定由哪个上游提供商(及量化精度)来服务该请求,在模型后追加 `@<provider>[/<quantization>]` —— `openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8` —— 它会作为 OpenRouter 的 `provider` 请求体对象发送,而不是拼进模型 ID。参见 [usage.md](../guides/usage.md#openrouter-400-models-one-key)。

> **`requesty/` 网关:** 用法相同:`requesty/` 之后的全部内容作为模型 ID 发送,可以是目录中的 `<vendor>/<model>` 路径(`requesty/openai/gpt-4o-mini`),也可以是托管策略 ID(`requesty/claude-sonnet-4-6`)。以 `@eu` 结尾的托管策略 ID(`requesty/gpt-5-mini@eu`)只经由欧盟提供商路由。参见 [usage.md](../guides/usage.md#requesty-700-models-one-key)。

> **`litellm/` 适配器:** 在单一 SDK 后路由到 100+ 提供商 —— 主要用于认证方式较棘手的上游(Bedrock SigV4、Azure 部署路由、Vertex 服务账号 JWT)。对于普通的 OpenAI 形态端点,优先使用零依赖的 `custom/` 适配器。用 `pip install ".[litellm]"` 安装。参见 [recipes.md](../guides/recipes.md#alternative-cloud-providers-with-non-trivial-auth-via-the-litellm-provider)。

### 开源(通过 Ollama 本地运行)
Expand Down
3 changes: 3 additions & 0 deletions docs/i18n/README.DE.MD
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,13 @@ Claude Code ist ein leistungsstarker, produktionsreifer KI-Coding-Assistent –
| **DeepSeek** | `deepseek-chat` · `deepseek-reasoner` | 64k | `DEEPSEEK_API_KEY` |
| **MiniMax** | `MiniMax-Text-01` · `MiniMax-VL-01` · `abab6.5s-chat` | 256k–1M | `MINIMAX_API_KEY` |
| **OpenRouter** _(400+ Modelle, ein Schlüssel)_ | `openrouter/deepseek/deepseek-v4-flash` · `openrouter/anthropic/claude-sonnet-4-6` · `openrouter/openai/gpt-5` | variiert | `OPENROUTER_API_KEY` |
| **Requesty** _(700+ Modelle, ein Schlüssel)_ | `requesty/openai/gpt-4o-mini` · `requesty/anthropic/claude-sonnet-4-6` · `requesty/claude-sonnet-4-6` | variiert | `REQUESTY_API_KEY` |
| **AWS Bedrock / Azure / Vertex** _(über litellm)_ | `litellm/<provider>/<model>` | variiert | anbieterspezifisch |

> **`openrouter/`-Gateway:** ein Schlüssel für über 400 Modelle verschiedener Anbieter. Die Modell-ID behält den Upstream-Pfad `<vendor>/<model>` von OpenRouter bei, der Aufruf ist also doppelt präfixiert: `openrouter/deepseek/deepseek-v4-flash`. Um festzulegen, welcher Upstream-Anbieter (und welche Quantisierung) die Anfrage bedient, hänge `@<provider>[/<quantization>]` an — `openrouter/deepseek/deepseek-v4-flash@gmicloud/fp8` — das als `provider`-Objekt im Request-Body gesendet wird, statt in die Modell-ID eingebaut zu werden. Siehe [usage.md](../guides/usage.md#openrouter-400-models-one-key).

> **`requesty/`-Gateway:** funktioniert genauso: alles nach `requesty/` wird als Modell-ID gesendet, entweder ein Katalogpfad `<vendor>/<model>` (`requesty/openai/gpt-4o-mini`) oder eine Managed-Policy-ID (`requesty/claude-sonnet-4-6`). Managed-Policy-IDs mit der Endung `@eu` (`requesty/gpt-5-mini@eu`) werden nur über EU-Anbieter geroutet. Siehe [usage.md](../guides/usage.md#requesty-700-models-one-key).

> **`litellm/`-Adapter:** leitet zu über 100 Anbietern hinter einem SDK weiter – hauptsächlich für Upstreams mit umständlicher Authentifizierung (Bedrock SigV4, Azure-Deployment-Routing, Vertex-Service-Account-JWTs). Für einfache OpenAI-förmige Endpunkte ist der abhängigkeitsfreie `custom/`-Adapter vorzuziehen. Installiere mit `pip install ".[litellm]"`. Siehe [recipes.md](../guides/recipes.md#alternative-cloud-providers-with-non-trivial-auth-via-the-litellm-provider).

### Open-Source (lokal über Ollama)
Expand Down
Loading
Loading