@dedenlabs/claude-code-router-cli 2.0.5 → 2.0.6-beta.1
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 +75 -3
- package/dist/cli.js +156 -51
- package/examples/configs/fixed-router-config.json +43 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,6 +112,35 @@ ccr start
|
|
|
112
112
|
ccr start -b
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
+
**修改配置文件:**
|
|
116
|
+
|
|
117
|
+
启动服务后会创建默认配置,您可以通过两种方式修改:
|
|
118
|
+
|
|
119
|
+
1. **手动编辑**:修改 `~/.claude-code-router/config.json` 配置文件
|
|
120
|
+
2. **可视化界面**:访问 http://localhost:3456/ui/ 实时编辑路由规则和替换密钥
|
|
121
|
+
|
|
122
|
+
推荐使用模型替换规则,只需修改路由映射,所有IDE工具无需改动:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"Router": {
|
|
127
|
+
"rules": [
|
|
128
|
+
{
|
|
129
|
+
"name": "haiku模型替换规则",
|
|
130
|
+
"condition": {
|
|
131
|
+
"type": "modelContains",
|
|
132
|
+
"value": "haiku"
|
|
133
|
+
},
|
|
134
|
+
"action": {
|
|
135
|
+
"route": "haiku-XXX"
|
|
136
|
+
},
|
|
137
|
+
"priority": 205
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
115
144
|
**配置 Claude 环境变量:**
|
|
116
145
|
```bash
|
|
117
146
|
# 编辑 Claude 配置文件
|
|
@@ -124,9 +153,9 @@ ccr start -b
|
|
|
124
153
|
"ANTHROPIC_AUTH_TOKEN": "sk-anything",
|
|
125
154
|
"API_TIMEOUT_MS": "3000000",
|
|
126
155
|
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
|
|
127
|
-
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "haiku
|
|
128
|
-
"ANTHROPIC_DEFAULT_SONNET_MODEL": "sonnet
|
|
129
|
-
"ANTHROPIC_DEFAULT_OPUS_MODEL": "opus
|
|
156
|
+
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "haiku",
|
|
157
|
+
"ANTHROPIC_DEFAULT_SONNET_MODEL": "sonnet",
|
|
158
|
+
"ANTHROPIC_DEFAULT_OPUS_MODEL": "opus"
|
|
130
159
|
},
|
|
131
160
|
"model": "sonnet"
|
|
132
161
|
}
|
|
@@ -319,6 +348,49 @@ function isBusinessHours(context) {
|
|
|
319
348
|
"engine": "unified",
|
|
320
349
|
"defaultRoute": "sonnet-minimax",
|
|
321
350
|
"rules": [
|
|
351
|
+
{
|
|
352
|
+
"name": "haiku模型替换规则",
|
|
353
|
+
"condition": {
|
|
354
|
+
"type": "modelContains",
|
|
355
|
+
"value": "haiku",
|
|
356
|
+
"operator": "contains"
|
|
357
|
+
},
|
|
358
|
+
"action": {
|
|
359
|
+
"route": "haiku-minimax",
|
|
360
|
+
"description": "模型替换任意模型规则"
|
|
361
|
+
},
|
|
362
|
+
"priority": 205,
|
|
363
|
+
"enabled": true
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"name": "sonnet模型替换规则",
|
|
367
|
+
"condition": {
|
|
368
|
+
"type": "modelContains",
|
|
369
|
+
"value": "sonnet",
|
|
370
|
+
"operator": "contains"
|
|
371
|
+
},
|
|
372
|
+
"action": {
|
|
373
|
+
"route": "sonnet-minimax",
|
|
374
|
+
"description": "模型替换任意模型规则"
|
|
375
|
+
},
|
|
376
|
+
"priority": 205,
|
|
377
|
+
"enabled": true
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"name": "opus模型替换规则",
|
|
381
|
+
"condition": {
|
|
382
|
+
"type": "modelContains",
|
|
383
|
+
"value": "opus",
|
|
384
|
+
"operator": "contains"
|
|
385
|
+
},
|
|
386
|
+
"action": {
|
|
387
|
+
"route": "opus-minimax",
|
|
388
|
+
"description": "模型替换任意模型规则"
|
|
389
|
+
},
|
|
390
|
+
"priority": 205,
|
|
391
|
+
"enabled": true
|
|
392
|
+
},
|
|
393
|
+
//---------以下规则不是必须的-----------
|
|
322
394
|
{
|
|
323
395
|
"name": "用户指定规则",
|
|
324
396
|
"priority": 200,
|
package/dist/cli.js
CHANGED
|
@@ -67706,7 +67706,7 @@ var require_package3 = __commonJS({
|
|
|
67706
67706
|
"package.json"(exports2, module2) {
|
|
67707
67707
|
module2.exports = {
|
|
67708
67708
|
name: "@dedenlabs/claude-code-router-cli",
|
|
67709
|
-
version: "2.0.
|
|
67709
|
+
version: "2.0.6-beta.1",
|
|
67710
67710
|
description: "\u57FA\u4E8E@musistudio/claude-code-router\u7684\u589E\u5F3A\u7248CLI\u8DEF\u7531\u5DE5\u5177 - \u652F\u6301\u7EDF\u4E00\u8DEF\u7531\u5F15\u64CE\u3001\u5916\u90E8\u89C4\u5219\u52A0\u8F7D\u3001\u667A\u80FD\u65E5\u5FD7\u7CFB\u7EDF\u3001\u81EA\u52A8\u914D\u7F6E\u8FC1\u79FB\u548CGLM\u601D\u8003\u6A21\u5F0F",
|
|
67711
67711
|
bin: {
|
|
67712
67712
|
ccr: "dist/cli.js"
|
|
@@ -70984,7 +70984,7 @@ var DEFAULT_CONFIG = {
|
|
|
70984
70984
|
"api_base_url": "https://open.bigmodel.cn/api/anthropic/v1/messages",
|
|
70985
70985
|
"api_key": "YOUR_GLM_API_KEY",
|
|
70986
70986
|
"models": [
|
|
70987
|
-
"glm-4.
|
|
70987
|
+
"glm-4.7"
|
|
70988
70988
|
],
|
|
70989
70989
|
"transformer": {
|
|
70990
70990
|
"use": [
|
|
@@ -70997,7 +70997,7 @@ var DEFAULT_CONFIG = {
|
|
|
70997
70997
|
"api_base_url": "https://open.bigmodel.cn/api/anthropic/v1/messages",
|
|
70998
70998
|
"api_key": "YOUR_GLM_API_KEY",
|
|
70999
70999
|
"models": [
|
|
71000
|
-
"glm-4.
|
|
71000
|
+
"glm-4.7"
|
|
71001
71001
|
],
|
|
71002
71002
|
"transformer": {
|
|
71003
71003
|
"use": [
|
|
@@ -71010,7 +71010,7 @@ var DEFAULT_CONFIG = {
|
|
|
71010
71010
|
"api_base_url": "https://api.z.ai/api/coding/paas/v4/chat/completions",
|
|
71011
71011
|
"api_key": "YOUR_GLM_API_KEY",
|
|
71012
71012
|
"models": [
|
|
71013
|
-
"glm-4.
|
|
71013
|
+
"glm-4.7"
|
|
71014
71014
|
],
|
|
71015
71015
|
"transformer": {
|
|
71016
71016
|
"use": [
|
|
@@ -71038,6 +71038,48 @@ var DEFAULT_CONFIG = {
|
|
|
71038
71038
|
"engine": "unified",
|
|
71039
71039
|
"defaultRoute": "sonnet",
|
|
71040
71040
|
"rules": [
|
|
71041
|
+
{
|
|
71042
|
+
"name": "haiku\u6A21\u578B\u66FF\u6362\u89C4\u5219",
|
|
71043
|
+
"condition": {
|
|
71044
|
+
"type": "modelContains",
|
|
71045
|
+
"value": "haiku",
|
|
71046
|
+
"operator": "contains"
|
|
71047
|
+
},
|
|
71048
|
+
"action": {
|
|
71049
|
+
"route": "haiku-minimax",
|
|
71050
|
+
"description": "\u6A21\u578B\u66FF\u6362\u4EFB\u610F\u6A21\u578B\u89C4\u5219"
|
|
71051
|
+
},
|
|
71052
|
+
"priority": 205,
|
|
71053
|
+
"enabled": true
|
|
71054
|
+
},
|
|
71055
|
+
{
|
|
71056
|
+
"name": "sonnet\u6A21\u578B\u66FF\u6362\u89C4\u5219",
|
|
71057
|
+
"condition": {
|
|
71058
|
+
"type": "modelContains",
|
|
71059
|
+
"value": "sonnet",
|
|
71060
|
+
"operator": "contains"
|
|
71061
|
+
},
|
|
71062
|
+
"action": {
|
|
71063
|
+
"route": "sonnet-minimax",
|
|
71064
|
+
"description": "\u6A21\u578B\u66FF\u6362\u4EFB\u610F\u6A21\u578B\u89C4\u5219"
|
|
71065
|
+
},
|
|
71066
|
+
"priority": 205,
|
|
71067
|
+
"enabled": true
|
|
71068
|
+
},
|
|
71069
|
+
{
|
|
71070
|
+
"name": "opus\u6A21\u578B\u66FF\u6362\u89C4\u5219",
|
|
71071
|
+
"condition": {
|
|
71072
|
+
"type": "modelContains",
|
|
71073
|
+
"value": "opus",
|
|
71074
|
+
"operator": "contains"
|
|
71075
|
+
},
|
|
71076
|
+
"action": {
|
|
71077
|
+
"route": "opus-minimax",
|
|
71078
|
+
"description": "\u6A21\u578B\u66FF\u6362\u4EFB\u610F\u6A21\u578B\u89C4\u5219"
|
|
71079
|
+
},
|
|
71080
|
+
"priority": 205,
|
|
71081
|
+
"enabled": true
|
|
71082
|
+
},
|
|
71041
71083
|
{
|
|
71042
71084
|
"name": "\u7528\u6237\u6307\u5B9A\u89C4\u5219",
|
|
71043
71085
|
"condition": {
|
|
@@ -84710,7 +84752,10 @@ var UnifiedRouter = class {
|
|
|
84710
84752
|
} else {
|
|
84711
84753
|
const requestedModel2 = req.body?.model;
|
|
84712
84754
|
if (matchResult.matched && matchResult.ruleName === "directMapping" && requestedModel2 && !requestedModel2.includes(",")) {
|
|
84713
|
-
const mappedRoute = this.mapDirectModelToProvider(
|
|
84755
|
+
const mappedRoute = this.mapDirectModelToProvider(
|
|
84756
|
+
requestedModel2,
|
|
84757
|
+
req
|
|
84758
|
+
);
|
|
84714
84759
|
if (mappedRoute) {
|
|
84715
84760
|
finalRoute = mappedRoute;
|
|
84716
84761
|
if (mappedRoute === this.config.defaultRoute) {
|
|
@@ -84724,6 +84769,7 @@ var UnifiedRouter = class {
|
|
|
84724
84769
|
}
|
|
84725
84770
|
}
|
|
84726
84771
|
}
|
|
84772
|
+
finalRoute = this.resolveProviderModel(finalRoute, req, context, true);
|
|
84727
84773
|
const cacheKey = this.generateCacheKey(req, tokenCount, finalRoute);
|
|
84728
84774
|
var result;
|
|
84729
84775
|
if (this.config.cache?.enabled !== false) {
|
|
@@ -85163,61 +85209,95 @@ ${allLines[totalLines - 1] || ""}`
|
|
|
85163
85209
|
this.logger.debug("${subagent} \u53D8\u91CF\u66FF\u6362\u5931\u8D25\uFF0C\u4FDD\u6301\u539F\u6837");
|
|
85164
85210
|
return processedRoute;
|
|
85165
85211
|
}
|
|
85166
|
-
this.logger.warn(
|
|
85212
|
+
this.logger.warn(
|
|
85213
|
+
`\u53D8\u91CF\u66FF\u6362\u672A\u5B8C\u6210\uFF0C\u4ECD\u5305\u542B\u672A\u66FF\u6362\u7684\u53D8\u91CF: ${processedRoute}\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u8DEF\u7531`
|
|
85214
|
+
);
|
|
85167
85215
|
return this.config.defaultRoute;
|
|
85168
85216
|
}
|
|
85169
85217
|
return processedRoute;
|
|
85170
85218
|
}
|
|
85171
85219
|
/**
|
|
85172
|
-
* 将provider
|
|
85220
|
+
* 将provider名称或模型名称转换为完整的 "provider,model" 路由格式
|
|
85221
|
+
*
|
|
85222
|
+
* 支持两种输入模式:
|
|
85223
|
+
* 1. 模型名映射:如 "claude-3.5-sonnet" → "openrouter,claude-3.5-sonnet"
|
|
85224
|
+
* 2. Provider名称补全:如 "haiku-glm" → "haiku-glm,glm-4.7"
|
|
85225
|
+
*
|
|
85226
|
+
* @param input - 模型名称或provider名称
|
|
85227
|
+
* @param req - 请求对象,包含config.Providers配置
|
|
85228
|
+
* @param context - 路由上下文(可选)
|
|
85229
|
+
* @param fallbackToInput - 失败时是否返回原输入(用于规则路由),默认false
|
|
85230
|
+
* @returns 完整的 "provider,model" 路由,或null表示无法映射
|
|
85173
85231
|
*/
|
|
85174
|
-
|
|
85232
|
+
resolveProviderModel(input, req, context, fallbackToInput = false) {
|
|
85233
|
+
if (input.includes(",")) {
|
|
85234
|
+
return input;
|
|
85235
|
+
}
|
|
85175
85236
|
const providers = req.config?.Providers || [];
|
|
85176
|
-
this.logger.debug("\u5C1D\
|
|
85177
|
-
|
|
85237
|
+
this.logger.debug("\u5C1D\u8BD5provider\u6A21\u578B\u89E3\u6790", {
|
|
85238
|
+
input,
|
|
85178
85239
|
providersCount: providers.length
|
|
85179
85240
|
});
|
|
85180
85241
|
for (const provider of providers) {
|
|
85181
85242
|
if (provider.models && Array.isArray(provider.models)) {
|
|
85182
|
-
if (provider.models.includes(
|
|
85183
|
-
const
|
|
85243
|
+
if (provider.models.includes(input)) {
|
|
85244
|
+
const route = `${provider.name},${provider.models[0]}`;
|
|
85184
85245
|
this.logger.info("\u2713 \u6A21\u578B\u540D\u5339\u914D", {
|
|
85185
|
-
request:
|
|
85186
|
-
route
|
|
85246
|
+
request: input,
|
|
85247
|
+
route
|
|
85187
85248
|
});
|
|
85188
|
-
return
|
|
85249
|
+
return route;
|
|
85189
85250
|
}
|
|
85190
85251
|
}
|
|
85191
|
-
if (provider.model ===
|
|
85192
|
-
const
|
|
85252
|
+
if (provider.model === input) {
|
|
85253
|
+
const route = `${provider.name},${provider.model}`;
|
|
85193
85254
|
this.logger.info("\u2713 \u6A21\u578B\u540D\u5339\u914D", {
|
|
85194
|
-
request:
|
|
85195
|
-
route
|
|
85255
|
+
request: input,
|
|
85256
|
+
route
|
|
85196
85257
|
});
|
|
85197
|
-
return
|
|
85258
|
+
return route;
|
|
85198
85259
|
}
|
|
85199
85260
|
}
|
|
85200
|
-
this.logger.debug("\u672A\u627E\u5230\
|
|
85201
|
-
modelName
|
|
85202
|
-
});
|
|
85261
|
+
this.logger.debug("\u672A\u627E\u5230\u6A21\u578B\u540D\uFF0C\u5C1D\u8BD5\u4F5C\u4E3Aprovider\u540D\u79F0\u5339\u914D", { input });
|
|
85203
85262
|
const matchedProvider = providers.find(
|
|
85204
|
-
(p) => p.name.toLowerCase() ===
|
|
85263
|
+
(p) => p.name.toLowerCase() === input.toLowerCase()
|
|
85205
85264
|
);
|
|
85206
|
-
if (matchedProvider) {
|
|
85207
|
-
|
|
85208
|
-
if (
|
|
85209
|
-
|
|
85210
|
-
return
|
|
85211
|
-
} else {
|
|
85212
|
-
this.logger.error(`Provider '${matchedProvider.name}' \u6CA1\u6709\u914D\u7F6E\u6A21\u578B\uFF01`, {
|
|
85213
|
-
providerName: matchedProvider.name
|
|
85214
|
-
});
|
|
85215
|
-
return null;
|
|
85265
|
+
if (!matchedProvider) {
|
|
85266
|
+
this.logger.debug(`\u672A\u627E\u5230provider '${input}' \u7684\u914D\u7F6E`);
|
|
85267
|
+
if (fallbackToInput) {
|
|
85268
|
+
this.logger.debug(`fallback\u6A21\u5F0F\uFF1A\u4FDD\u6301\u539F\u6837\u8FD4\u56DE ${input}`);
|
|
85269
|
+
return input;
|
|
85216
85270
|
}
|
|
85271
|
+
return null;
|
|
85272
|
+
}
|
|
85273
|
+
let model;
|
|
85274
|
+
if (matchedProvider.defaultModel) {
|
|
85275
|
+
model = matchedProvider.defaultModel;
|
|
85276
|
+
this.logger.info(`\u2713 \u4F7F\u7528provider '${input}' \u7684\u9ED8\u8BA4\u6A21\u578B: ${model}`);
|
|
85277
|
+
} else if (matchedProvider.models && matchedProvider.models.length > 0) {
|
|
85278
|
+
model = matchedProvider.models[0];
|
|
85279
|
+
this.logger.info(`\u2713 \u4F7F\u7528provider '${input}' \u7684\u7B2C\u4E00\u4E2A\u6A21\u578B: ${model}`);
|
|
85280
|
+
} else if (matchedProvider.model) {
|
|
85281
|
+
model = matchedProvider.model;
|
|
85282
|
+
this.logger.info(`\u2713 \u4F7F\u7528provider '${input}' \u7684\u6A21\u578B: ${model}`);
|
|
85283
|
+
}
|
|
85284
|
+
if (model) {
|
|
85285
|
+
return `${matchedProvider.name},${model}`;
|
|
85286
|
+
}
|
|
85287
|
+
this.logger.error(`Provider '${input}' \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B`);
|
|
85288
|
+
if (fallbackToInput) {
|
|
85289
|
+
this.logger.debug(`fallback\u6A21\u5F0F\uFF1A\u4FDD\u6301\u539F\u6837\u8FD4\u56DE ${input}`);
|
|
85290
|
+
return input;
|
|
85217
85291
|
}
|
|
85218
|
-
this.logger.debug(`\u672A\u627E\u5230\u6A21\u578B '${modelName}' \u7684\u6620\u5C04\uFF0C\u8FD4\u56DEnull`);
|
|
85219
85292
|
return null;
|
|
85220
85293
|
}
|
|
85294
|
+
/**
|
|
85295
|
+
* 将provider作为代号,映射到对应的model模型(旧方法别名)
|
|
85296
|
+
* @deprecated 使用 resolveProviderModel 替代
|
|
85297
|
+
*/
|
|
85298
|
+
mapDirectModelToProvider(modelName, req) {
|
|
85299
|
+
return this.resolveProviderModel(modelName, req);
|
|
85300
|
+
}
|
|
85221
85301
|
/**
|
|
85222
85302
|
* 生成缓存键
|
|
85223
85303
|
*/
|
|
@@ -89595,7 +89675,10 @@ var AVAILABLE_TRANSFORMERS = [
|
|
|
89595
89675
|
"rovo-cli"
|
|
89596
89676
|
];
|
|
89597
89677
|
function getConfigPath() {
|
|
89598
|
-
const configDir = path7.join(
|
|
89678
|
+
const configDir = path7.join(
|
|
89679
|
+
process.env.HOME || process.env.USERPROFILE || "",
|
|
89680
|
+
".claude-code-router"
|
|
89681
|
+
);
|
|
89599
89682
|
const configPath = path7.join(configDir, "config.json");
|
|
89600
89683
|
if (!fs6.existsSync(configPath)) {
|
|
89601
89684
|
throw new Error(`config.json not found at ${configPath}`);
|
|
@@ -89629,11 +89712,15 @@ ${BOLDCYAN}Provider:${RESET} ${provider.name}`,
|
|
|
89629
89712
|
return models;
|
|
89630
89713
|
}
|
|
89631
89714
|
function displayCurrentConfig(config) {
|
|
89632
|
-
console.log(
|
|
89633
|
-
|
|
89715
|
+
console.log(
|
|
89716
|
+
`
|
|
89717
|
+
${BOLDCYAN}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550${RESET}`
|
|
89718
|
+
);
|
|
89634
89719
|
console.log(`${BOLDCYAN} Current Configuration${RESET}`);
|
|
89635
|
-
console.log(
|
|
89636
|
-
|
|
89720
|
+
console.log(
|
|
89721
|
+
`${BOLDCYAN}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550${RESET}
|
|
89722
|
+
`
|
|
89723
|
+
);
|
|
89637
89724
|
const formatModel = (routerValue) => {
|
|
89638
89725
|
if (!routerValue || typeof routerValue === "number") {
|
|
89639
89726
|
return `${DIM}Not configured${RESET}`;
|
|
@@ -89670,11 +89757,15 @@ ${BOLDCYAN}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2
|
|
|
89670
89757
|
console.log(` ${formatModel(config.Router.image)}
|
|
89671
89758
|
`);
|
|
89672
89759
|
}
|
|
89673
|
-
console.log(
|
|
89674
|
-
|
|
89760
|
+
console.log(
|
|
89761
|
+
`
|
|
89762
|
+
${BOLDCYAN}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550${RESET}`
|
|
89763
|
+
);
|
|
89675
89764
|
console.log(`${BOLDCYAN} Add/Update Model${RESET}`);
|
|
89676
|
-
console.log(
|
|
89677
|
-
|
|
89765
|
+
console.log(
|
|
89766
|
+
`${BOLDCYAN}\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550${RESET}
|
|
89767
|
+
`
|
|
89768
|
+
);
|
|
89678
89769
|
}
|
|
89679
89770
|
async function selectModelType() {
|
|
89680
89771
|
return await esm_default4({
|
|
@@ -89742,7 +89833,10 @@ ${BOLDYELLOW}Add provider routing options?${RESET}`,
|
|
|
89742
89833
|
message: "Provider (e.g., moonshotai/fp8):",
|
|
89743
89834
|
validate: (value) => value.trim() !== "" || "Provider cannot be empty"
|
|
89744
89835
|
});
|
|
89745
|
-
transformers.push([
|
|
89836
|
+
transformers.push([
|
|
89837
|
+
"openrouter",
|
|
89838
|
+
{ provider: { only: [providerInput] } }
|
|
89839
|
+
]);
|
|
89746
89840
|
} else {
|
|
89747
89841
|
transformers.push(transformer);
|
|
89748
89842
|
}
|
|
@@ -89762,7 +89856,10 @@ async function addNewModel(config) {
|
|
|
89762
89856
|
name: p.name,
|
|
89763
89857
|
value: p.name
|
|
89764
89858
|
}));
|
|
89765
|
-
providerChoices.push({
|
|
89859
|
+
providerChoices.push({
|
|
89860
|
+
name: `${BOLDGREEN}+ Add New Provider${RESET}`,
|
|
89861
|
+
value: "__new__"
|
|
89862
|
+
});
|
|
89766
89863
|
const selectedProvider = await esm_default4({
|
|
89767
89864
|
message: `
|
|
89768
89865
|
${BOLDYELLOW}Select provider for the new model:${RESET}`,
|
|
@@ -89807,7 +89904,9 @@ ${BOLDYELLOW}Add model-specific transformer configuration?${RESET}`,
|
|
|
89807
89904
|
}
|
|
89808
89905
|
}
|
|
89809
89906
|
saveConfig(config);
|
|
89810
|
-
console.log(
|
|
89907
|
+
console.log(
|
|
89908
|
+
`${GREEN}\u2713 Model "${modelName}" added to provider "${providerName}"${RESET}`
|
|
89909
|
+
);
|
|
89811
89910
|
const setAsDefault = await esm_default2({
|
|
89812
89911
|
message: `
|
|
89813
89912
|
${BOLDYELLOW}Do you want to set this model in router configuration?${RESET}`,
|
|
@@ -89894,8 +89993,10 @@ ${BOLDYELLOW}Model names (comma-separated):${RESET}`,
|
|
|
89894
89993
|
}
|
|
89895
89994
|
config.Providers.push(newProvider);
|
|
89896
89995
|
saveConfig(config);
|
|
89897
|
-
console.log(
|
|
89898
|
-
|
|
89996
|
+
console.log(
|
|
89997
|
+
`${GREEN}
|
|
89998
|
+
\u2713 Provider "${providerName}" added successfully${RESET}`
|
|
89999
|
+
);
|
|
89899
90000
|
const setAsDefault = await esm_default2({
|
|
89900
90001
|
message: `
|
|
89901
90002
|
${BOLDYELLOW}Do you want to set one of these models in router configuration?${RESET}`,
|
|
@@ -89938,13 +90039,17 @@ async function runModelSelector() {
|
|
|
89938
90039
|
config = loadConfig();
|
|
89939
90040
|
config.Router[result.modelType] = `${result.providerName},${result.modelName}`;
|
|
89940
90041
|
saveConfig(config);
|
|
89941
|
-
console.log(
|
|
90042
|
+
console.log(
|
|
90043
|
+
`${GREEN}\u2713 ${result.modelType} set to ${result.providerName},${result.modelName}${RESET}`
|
|
90044
|
+
);
|
|
89942
90045
|
}
|
|
89943
90046
|
} else {
|
|
89944
90047
|
const selectedModel = await selectModel(config, action);
|
|
89945
90048
|
config.Router[action] = selectedModel;
|
|
89946
90049
|
saveConfig(config);
|
|
89947
|
-
console.log(
|
|
90050
|
+
console.log(
|
|
90051
|
+
`${GREEN}\u2713 ${action} model updated to: ${selectedModel}${RESET}`
|
|
90052
|
+
);
|
|
89948
90053
|
}
|
|
89949
90054
|
displayCurrentConfig(config);
|
|
89950
90055
|
} catch (error) {
|
|
@@ -18,6 +18,48 @@
|
|
|
18
18
|
}
|
|
19
19
|
],
|
|
20
20
|
"Providers": [
|
|
21
|
+
{
|
|
22
|
+
"name": "haiku模型替换规则",
|
|
23
|
+
"condition": {
|
|
24
|
+
"type": "modelContains",
|
|
25
|
+
"value": "haiku",
|
|
26
|
+
"operator": "contains"
|
|
27
|
+
},
|
|
28
|
+
"action": {
|
|
29
|
+
"route": "haiku-minimax",
|
|
30
|
+
"description": "模型替换任意模型规则"
|
|
31
|
+
},
|
|
32
|
+
"priority": 205,
|
|
33
|
+
"enabled": true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "sonnet模型替换规则",
|
|
37
|
+
"condition": {
|
|
38
|
+
"type": "modelContains",
|
|
39
|
+
"value": "sonnet",
|
|
40
|
+
"operator": "contains"
|
|
41
|
+
},
|
|
42
|
+
"action": {
|
|
43
|
+
"route": "sonnet-minimax",
|
|
44
|
+
"description": "模型替换任意模型规则"
|
|
45
|
+
},
|
|
46
|
+
"priority": 205,
|
|
47
|
+
"enabled": true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "opus模型替换规则",
|
|
51
|
+
"condition": {
|
|
52
|
+
"type": "modelContains",
|
|
53
|
+
"value": "opus",
|
|
54
|
+
"operator": "contains"
|
|
55
|
+
},
|
|
56
|
+
"action": {
|
|
57
|
+
"route": "opus-minimax",
|
|
58
|
+
"description": "模型替换任意模型规则"
|
|
59
|
+
},
|
|
60
|
+
"priority": 205,
|
|
61
|
+
"enabled": true
|
|
62
|
+
},
|
|
21
63
|
{
|
|
22
64
|
"name": "haiku-minimax",
|
|
23
65
|
"api_base_url": "https://api.minimaxi.com/anthropic/v1/messages",
|
|
@@ -242,4 +284,4 @@
|
|
|
242
284
|
"OPENAI_API_KEY": "",
|
|
243
285
|
"OPENAI_BASE_URL": "",
|
|
244
286
|
"OPENAI_MODEL": ""
|
|
245
|
-
}
|
|
287
|
+
}
|