@musistudio/claude-code-router 1.0.26 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,12 +8,12 @@
8
8
 
9
9
  ## ✨ Features
10
10
 
11
- - **Model Routing**: Route requests to different models based on your needs (e.g., background tasks, thinking, long context).
12
- - **Multi-Provider Support**: Supports various model providers like OpenRouter, DeepSeek, Ollama, Gemini, Volcengine, and SiliconFlow.
13
- - **Request/Response Transformation**: Customize requests and responses for different providers using transformers.
14
- - **Dynamic Model Switching**: Switch models on-the-fly within Claude Code using the `/model` command.
15
- - **GitHub Actions Integration**: Trigger Claude Code tasks in your GitHub workflows.
16
- - **Plugin System**: Extend functionality with custom transformers.
11
+ - **Model Routing**: Route requests to different models based on your needs (e.g., background tasks, thinking, long context).
12
+ - **Multi-Provider Support**: Supports various model providers like OpenRouter, DeepSeek, Ollama, Gemini, Volcengine, and SiliconFlow.
13
+ - **Request/Response Transformation**: Customize requests and responses for different providers using transformers.
14
+ - **Dynamic Model Switching**: Switch models on-the-fly within Claude Code using the `/model` command.
15
+ - **GitHub Actions Integration**: Trigger Claude Code tasks in your GitHub workflows.
16
+ - **Plugin System**: Extend functionality with custom transformers.
17
17
 
18
18
  ## 🚀 Getting Started
19
19
 
@@ -36,6 +36,7 @@ npm install -g @musistudio/claude-code-router
36
36
  Create and configure your `~/.claude-code-router/config.json` file. For more details, you can refer to `config.example.json`.
37
37
 
38
38
  The `config.json` file has several key sections:
39
+
39
40
  - **`PROXY_URL`** (optional): You can set a proxy for API requests, for example: `"PROXY_URL": "http://127.0.0.1:7890"`.
40
41
  - **`LOG`** (optional): You can enable logging by setting it to `true`. The log file will be located at `$HOME/.claude-code-router.log`.
41
42
  - **`APIKEY`** (optional): You can set a secret key to authenticate requests. When set, clients must provide this key in the `Authorization` header (e.g., `Bearer your-secret-key`) or the `x-api-key` header. Example: `"APIKEY": "your-secret-key"`.
@@ -106,16 +107,20 @@ Here is a comprehensive example:
106
107
  "name": "modelscope",
107
108
  "api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
108
109
  "api_key": "",
109
- "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct"],
110
+ "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct", "Qwen/Qwen3-235B-A22B-Thinking-2507"],
110
111
  "transformer": {
111
112
  "use": [
112
113
  [
113
114
  "maxtoken",
114
115
  {
115
- "max_tokens": 8192
116
+ "max_tokens": 65536
116
117
  }
117
- ]
118
- ]
118
+ ],
119
+ "enhancetool"
120
+ ],
121
+ "Qwen/Qwen3-235B-A22B-Thinking-2507": {
122
+ "use": ["reasoning"]
123
+ }
119
124
  }
120
125
  },
121
126
  {
@@ -128,9 +133,10 @@ Here is a comprehensive example:
128
133
  [
129
134
  "maxtoken",
130
135
  {
131
- "max_tokens": 8192
136
+ "max_tokens": 65536
132
137
  }
133
- ]
138
+ ],
139
+ "enhancetool"
134
140
  ]
135
141
  }
136
142
  }
@@ -140,12 +146,12 @@ Here is a comprehensive example:
140
146
  "background": "ollama,qwen2.5-coder:latest",
141
147
  "think": "deepseek,deepseek-reasoner",
142
148
  "longContext": "openrouter,google/gemini-2.5-pro-preview",
149
+ "longContextThreshold": 60000,
143
150
  "webSearch": "gemini,gemini-2.5-flash"
144
151
  }
145
152
  }
146
153
  ```
147
154
 
148
-
149
155
  ### 3. Running Claude Code with the Router
150
156
 
151
157
  Start Claude Code using the router:
@@ -154,77 +160,84 @@ Start Claude Code using the router:
154
160
  ccr code
155
161
  ```
156
162
 
163
+ > **Note**: After modifying the configuration file, you need to restart the service for the changes to take effect:
164
+ >
165
+ > ```shell
166
+ > ccr restart
167
+ > ```
168
+
157
169
  #### Providers
158
170
 
159
171
  The `Providers` array is where you define the different model providers you want to use. Each provider object requires:
160
172
 
161
- - `name`: A unique name for the provider.
162
- - `api_base_url`: The full API endpoint for chat completions.
163
- - `api_key`: Your API key for the provider.
164
- - `models`: A list of model names available from this provider.
165
- - `transformer` (optional): Specifies transformers to process requests and responses.
173
+ - `name`: A unique name for the provider.
174
+ - `api_base_url`: The full API endpoint for chat completions.
175
+ - `api_key`: Your API key for the provider.
176
+ - `models`: A list of model names available from this provider.
177
+ - `transformer` (optional): Specifies transformers to process requests and responses.
166
178
 
167
179
  #### Transformers
168
180
 
169
181
  Transformers allow you to modify the request and response payloads to ensure compatibility with different provider APIs.
170
182
 
171
- - **Global Transformer**: Apply a transformer to all models from a provider. In this example, the `openrouter` transformer is applied to all models under the `openrouter` provider.
172
- ```json
173
- {
174
- "name": "openrouter",
175
- "api_base_url": "https://openrouter.ai/api/v1/chat/completions",
176
- "api_key": "sk-xxx",
177
- "models": [
178
- "google/gemini-2.5-pro-preview",
179
- "anthropic/claude-sonnet-4",
180
- "anthropic/claude-3.5-sonnet"
181
- ],
182
- "transformer": { "use": ["openrouter"] }
183
- }
184
- ```
185
- - **Model-Specific Transformer**: Apply a transformer to a specific model. In this example, the `deepseek` transformer is applied to all models, and an additional `tooluse` transformer is applied only to the `deepseek-chat` model.
186
- ```json
187
- {
188
- "name": "deepseek",
189
- "api_base_url": "https://api.deepseek.com/chat/completions",
190
- "api_key": "sk-xxx",
191
- "models": ["deepseek-chat", "deepseek-reasoner"],
192
- "transformer": {
193
- "use": ["deepseek"],
194
- "deepseek-chat": { "use": ["tooluse"] }
195
- }
196
- }
197
- ```
198
-
199
- - **Passing Options to a Transformer**: Some transformers, like `maxtoken`, accept options. To pass options, use a nested array where the first element is the transformer name and the second is an options object.
200
- ```json
201
- {
202
- "name": "siliconflow",
203
- "api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
204
- "api_key": "sk-xxx",
205
- "models": ["moonshotai/Kimi-K2-Instruct"],
206
- "transformer": {
207
- "use": [
208
- [
209
- "maxtoken",
210
- {
211
- "max_tokens": 16384
212
- }
213
- ]
183
+ - **Global Transformer**: Apply a transformer to all models from a provider. In this example, the `openrouter` transformer is applied to all models under the `openrouter` provider.
184
+ ```json
185
+ {
186
+ "name": "openrouter",
187
+ "api_base_url": "https://openrouter.ai/api/v1/chat/completions",
188
+ "api_key": "sk-xxx",
189
+ "models": [
190
+ "google/gemini-2.5-pro-preview",
191
+ "anthropic/claude-sonnet-4",
192
+ "anthropic/claude-3.5-sonnet"
193
+ ],
194
+ "transformer": { "use": ["openrouter"] }
195
+ }
196
+ ```
197
+ - **Model-Specific Transformer**: Apply a transformer to a specific model. In this example, the `deepseek` transformer is applied to all models, and an additional `tooluse` transformer is applied only to the `deepseek-chat` model.
198
+
199
+ ```json
200
+ {
201
+ "name": "deepseek",
202
+ "api_base_url": "https://api.deepseek.com/chat/completions",
203
+ "api_key": "sk-xxx",
204
+ "models": ["deepseek-chat", "deepseek-reasoner"],
205
+ "transformer": {
206
+ "use": ["deepseek"],
207
+ "deepseek-chat": { "use": ["tooluse"] }
208
+ }
209
+ }
210
+ ```
211
+
212
+ - **Passing Options to a Transformer**: Some transformers, like `maxtoken`, accept options. To pass options, use a nested array where the first element is the transformer name and the second is an options object.
213
+ ```json
214
+ {
215
+ "name": "siliconflow",
216
+ "api_base_url": "https://api.siliconflow.cn/v1/chat/completions",
217
+ "api_key": "sk-xxx",
218
+ "models": ["moonshotai/Kimi-K2-Instruct"],
219
+ "transformer": {
220
+ "use": [
221
+ [
222
+ "maxtoken",
223
+ {
224
+ "max_tokens": 16384
225
+ }
214
226
  ]
215
- }
227
+ ]
216
228
  }
217
- ```
229
+ }
230
+ ```
218
231
 
219
232
  **Available Built-in Transformers:**
220
233
 
221
- - `deepseek`: Adapts requests/responses for DeepSeek API.
222
- - `gemini`: Adapts requests/responses for Gemini API.
223
- - `openrouter`: Adapts requests/responses for OpenRouter API.
224
- - `groq`: Adapts requests/responses for groq API.
225
- - `maxtoken`: Sets a specific `max_tokens` value.
226
- - `tooluse`: Optimizes tool usage for certain models via `tool_choice`.
227
- - `gemini-cli` (experimental): Unofficial support for Gemini via Gemini CLI [gemini-cli.js](https://gist.github.com/musistudio/1c13a65f35916a7ab690649d3df8d1cd).
234
+ - `deepseek`: Adapts requests/responses for DeepSeek API.
235
+ - `gemini`: Adapts requests/responses for Gemini API.
236
+ - `openrouter`: Adapts requests/responses for OpenRouter API.
237
+ - `groq`: Adapts requests/responses for groq API.
238
+ - `maxtoken`: Sets a specific `max_tokens` value.
239
+ - `tooluse`: Optimizes tool usage for certain models via `tool_choice`.
240
+ - `gemini-cli` (experimental): Unofficial support for Gemini via Gemini CLI [gemini-cli.js](https://gist.github.com/musistudio/1c13a65f35916a7ab690649d3df8d1cd).
228
241
 
229
242
  **Custom Transformers:**
230
243
 
@@ -233,12 +246,12 @@ You can also create your own transformers and load them via the `transformers` f
233
246
  ```json
234
247
  {
235
248
  "transformers": [
236
- {
237
- "path": "$HOME/.claude-code-router/plugins/gemini-cli.js",
238
- "options": {
239
- "project": "xxx"
240
- }
249
+ {
250
+ "path": "$HOME/.claude-code-router/plugins/gemini-cli.js",
251
+ "options": {
252
+ "project": "xxx"
241
253
  }
254
+ }
242
255
  ]
243
256
  }
244
257
  ```
@@ -247,12 +260,12 @@ You can also create your own transformers and load them via the `transformers` f
247
260
 
248
261
  The `Router` object defines which model to use for different scenarios:
249
262
 
250
- - `default`: The default model for general tasks.
251
- - `background`: A model for background tasks. This can be a smaller, local model to save costs.
252
- - `think`: A model for reasoning-heavy tasks, like Plan Mode.
253
- - `longContext`: A model for handling long contexts (e.g., > 60K tokens).
254
- - `webSearch`: Used for handling web search tasks and this requires the model itself to support the feature. If you're using openrouter, you need to add the `:online` suffix after the model name.
255
-
263
+ - `default`: The default model for general tasks.
264
+ - `background`: A model for background tasks. This can be a smaller, local model to save costs.
265
+ - `think`: A model for reasoning-heavy tasks, like Plan Mode.
266
+ - `longContext`: A model for handling long contexts (e.g., > 60K tokens).
267
+ - `longContextThreshold` (optional): The token count threshold for triggering the long context model. Defaults to 60000 if not specified.
268
+ - `webSearch`: Used for handling web search tasks and this requires the model itself to support the feature. If you're using openrouter, you need to add the `:online` suffix after the model name.
256
269
 
257
270
  You can also switch models dynamically in Claude Code with the `/model` command:
258
271
  `/model provider_name,model_name`
@@ -285,11 +298,11 @@ Here is an example of a `custom-router.js` based on `custom-router.example.js`:
285
298
  * @returns {Promise<string|null>} - A promise that resolves to the "provider,model_name" string, or null to use the default router.
286
299
  */
287
300
  module.exports = async function router(req, config) {
288
- const userMessage = req.body.messages.find(m => m.role === 'user')?.content;
301
+ const userMessage = req.body.messages.find((m) => m.role === "user")?.content;
289
302
 
290
- if (userMessage && userMessage.includes('explain this code')) {
303
+ if (userMessage && userMessage.includes("explain this code")) {
291
304
  // Use a powerful model for code explanation
292
- return 'openrouter,anthropic/claude-3.5-sonnet';
305
+ return "openrouter,anthropic/claude-3.5-sonnet";
293
306
  }
294
307
 
295
308
  // Fallback to the default router configuration
@@ -297,7 +310,6 @@ module.exports = async function router(req, config) {
297
310
  };
298
311
  ```
299
312
 
300
-
301
313
  ## 🤖 GitHub Actions
302
314
 
303
315
  Integrate Claude Code Router into your CI/CD pipeline. After setting up [Claude Code Actions](https://docs.anthropic.com/en/docs/claude-code/github-actions), modify your `.github/workflows/claude.yaml` to use the router:
@@ -359,8 +371,8 @@ This setup allows for interesting automations, like running tasks during off-pea
359
371
 
360
372
  ## 📝 Further Reading
361
373
 
362
- - [Project Motivation and How It Works](blog/en/project-motivation-and-how-it-works.md)
363
- - [Maybe We Can Do More with the Router](blog/en/maybe-we-can-do-more-with-the-route.md)
374
+ - [Project Motivation and How It Works](blog/en/project-motivation-and-how-it-works.md)
375
+ - [Maybe We Can Do More with the Router](blog/en/maybe-we-can-do-more-with-the-route.md)
364
376
 
365
377
  ## ❤️ Support & Sponsoring
366
378
 
@@ -382,36 +394,39 @@ A huge thank you to all our sponsors for their generous support!
382
394
  - @Simon Leischnig
383
395
  - [@duanshuaimin](https://github.com/duanshuaimin)
384
396
  - [@vrgitadmin](https://github.com/vrgitadmin)
385
- - @*o
397
+ - @\*o
386
398
  - [@ceilwoo](https://github.com/ceilwoo)
387
- - @*说
388
- - @*更
389
- - @K*g
390
- - @R*R
399
+ - @\*说
400
+ - @\*更
401
+ - @K\*g
402
+ - @R\*R
391
403
  - [@bobleer](https://github.com/bobleer)
392
- - @*苗
393
- - @*划
404
+ - @\*苗
405
+ - @\*划
394
406
  - [@Clarence-pan](https://github.com/Clarence-pan)
395
407
  - [@carter003](https://github.com/carter003)
396
- - @S*r
397
- - @*晖
398
- - @*敏
399
- - @Z*z
400
- - @*然
408
+ - @S\*r
409
+ - @\*晖
410
+ - @\*敏
411
+ - @Z\*z
412
+ - @\*然
401
413
  - [@cluic](https://github.com/cluic)
402
- - @*苗
414
+ - @\*苗
403
415
  - [@PromptExpert](https://github.com/PromptExpert)
404
- - @*应
416
+ - @\*应
405
417
  - [@yusnake](https://github.com/yusnake)
406
- - @*飞
407
- - @董*
408
- - @*汀
409
- - @*涯
410
- - @*:-)
411
- - @**磊
412
- - @*琢
413
- - @*成
414
- - @Z*o
415
- - @*琨
418
+ - @\*飞
419
+ - @董\*
420
+ - @\*汀
421
+ - @\*涯
422
+ - @\*:-)
423
+ - @\*\*磊
424
+ - @\*琢
425
+ - @\*成
426
+ - @Z\*o
427
+ - @\*琨
428
+ - [@congzhangzh](https://github.com/congzhangzh)
429
+ - @\*\_
430
+ - @Z\*m
416
431
 
417
432
  (If your name is masked, please contact me via my homepage email to update it with your GitHub username.)
package/README_zh.md CHANGED
@@ -103,16 +103,20 @@ npm install -g @musistudio/claude-code-router
103
103
  "name": "modelscope",
104
104
  "api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
105
105
  "api_key": "",
106
- "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct"],
106
+ "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct", "Qwen/Qwen3-235B-A22B-Thinking-2507"],
107
107
  "transformer": {
108
108
  "use": [
109
109
  [
110
110
  "maxtoken",
111
111
  {
112
- "max_tokens": 8192
112
+ "max_tokens": 65536
113
113
  }
114
- ]
115
- ]
114
+ ],
115
+ "enhancetool"
116
+ ],
117
+ "Qwen/Qwen3-235B-A22B-Thinking-2507": {
118
+ "use": ["reasoning"]
119
+ }
116
120
  }
117
121
  },
118
122
  {
@@ -125,9 +129,10 @@ npm install -g @musistudio/claude-code-router
125
129
  [
126
130
  "maxtoken",
127
131
  {
128
- "max_tokens": 8192
132
+ "max_tokens": 65536
129
133
  }
130
- ]
134
+ ],
135
+ "enhancetool"
131
136
  ]
132
137
  }
133
138
  }
@@ -137,6 +142,7 @@ npm install -g @musistudio/claude-code-router
137
142
  "background": "ollama,qwen2.5-coder:latest",
138
143
  "think": "deepseek,deepseek-reasoner",
139
144
  "longContext": "openrouter,google/gemini-2.5-pro-preview",
145
+ "longContextThreshold": 60000,
140
146
  "webSearch": "gemini,gemini-2.5-flash"
141
147
  }
142
148
  }
@@ -151,6 +157,11 @@ npm install -g @musistudio/claude-code-router
151
157
  ccr code
152
158
  ```
153
159
 
160
+ > **注意**: 修改配置文件后,需要重启服务使配置生效:
161
+ > ```shell
162
+ > ccr restart
163
+ > ```
164
+
154
165
  #### Providers
155
166
 
156
167
  `Providers` 数组是您定义要使用的不同模型提供商的地方。每个提供商对象都需要:
@@ -248,6 +259,7 @@ Transformers 允许您修改请求和响应负载,以确保与不同提供商
248
259
  - `background`: 用于后台任务的模型。这可以是一个较小的本地模型以节省成本。
249
260
  - `think`: 用于推理密集型任务(如计划模式)的模型。
250
261
  - `longContext`: 用于处理长上下文(例如,> 60K 令牌)的模型。
262
+ - `longContextThreshold` (可选): 触发长上下文模型的令牌数阈值。如果未指定,默认为 60000。
251
263
  - `webSearch`: 用于处理网络搜索任务,需要模型本身支持。如果使用`openrouter`需要在模型后面加上`:online`后缀。
252
264
 
253
265
  您还可以使用 `/model` 命令在 Claude Code 中动态切换模型:
@@ -408,9 +420,12 @@ jobs:
408
420
  - @*琢
409
421
  - @*成
410
422
  - @Z*o
423
+ - [@congzhangzh](https://github.com/congzhangzh)
424
+ - @*_
425
+ - @Z\*m
411
426
 
412
427
  (如果您的名字被屏蔽,请通过我的主页电子邮件与我联系,以便使用您的 GitHub 用户名进行更新。)
413
428
 
414
429
 
415
430
  ## 交流群
416
- <img src="/blog/images/wechat_group.jpg" width="200" alt="wechat_group" />
431
+ <img src="/blog/images/wechat_group.jpg" width="200" alt="wechat_group" />
@@ -70,16 +70,20 @@
70
70
  "name": "modelscope",
71
71
  "api_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
72
72
  "api_key": "",
73
- "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct"],
73
+ "models": ["Qwen/Qwen3-Coder-480B-A35B-Instruct", "Qwen/Qwen3-235B-A22B-Thinking-2507"],
74
74
  "transformer": {
75
75
  "use": [
76
76
  [
77
77
  "maxtoken",
78
78
  {
79
- "max_tokens": 8192
79
+ "max_tokens": 65536
80
80
  }
81
- ]
82
- ]
81
+ ],
82
+ "enhancetool"
83
+ ],
84
+ "Qwen/Qwen3-235B-A22B-Thinking-2507": {
85
+ "use": ["reasoning"]
86
+ }
83
87
  }
84
88
  },
85
89
  {
@@ -92,9 +96,10 @@
92
96
  [
93
97
  "maxtoken",
94
98
  {
95
- "max_tokens": 8192
99
+ "max_tokens": 65536
96
100
  }
97
- ]
101
+ ],
102
+ "enhancetool"
98
103
  ]
99
104
  }
100
105
  }
@@ -103,7 +108,9 @@
103
108
  "default": "deepseek,deepseek-chat",
104
109
  "background": "ollama,qwen2.5-coder:latest",
105
110
  "think": "deepseek,deepseek-reasoner",
106
- "longContext": "openrouter,google/gemini-2.5-pro-preview"
111
+ "longContext": "openrouter,google/gemini-2.5-pro-preview",
112
+ "longContextThreshold": 60000,
113
+ "webSearch": "gemini,gemini-2.5-flash"
107
114
  },
108
115
  "APIKEY": "your-secret-key",
109
116
  "HOST": "0.0.0.0"