aicodeswitch 3.9.1 → 3.9.2
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/dist/server/database.js
CHANGED
|
@@ -386,7 +386,7 @@ class DatabaseManager {
|
|
|
386
386
|
CREATE TABLE IF NOT EXISTS rules (
|
|
387
387
|
id TEXT PRIMARY KEY,
|
|
388
388
|
route_id TEXT NOT NULL,
|
|
389
|
-
content_type TEXT NOT NULL CHECK(content_type IN ('default', 'background', 'thinking', 'long-context', 'image-understanding', 'model-mapping')),
|
|
389
|
+
content_type TEXT NOT NULL CHECK(content_type IN ('default', 'background', 'thinking', 'long-context', 'image-understanding', 'model-mapping', 'high-iq')),
|
|
390
390
|
target_service_id TEXT NOT NULL,
|
|
391
391
|
target_model TEXT,
|
|
392
392
|
replaced_model TEXT,
|
|
@@ -1707,7 +1707,7 @@ class FileSystemDatabaseManager {
|
|
|
1707
1707
|
if (!rule.routeId || typeof rule.routeId !== 'string') {
|
|
1708
1708
|
return { valid: false, error: `规则[${index}](${rule.id}) 缺少有效的 routeId 字段` };
|
|
1709
1709
|
}
|
|
1710
|
-
const validContentTypes = ['default', 'background', 'thinking', 'long-context', 'image-understanding', 'model-mapping'];
|
|
1710
|
+
const validContentTypes = ['default', 'background', 'thinking', 'long-context', 'image-understanding', 'model-mapping', 'high-iq'];
|
|
1711
1711
|
if (!rule.contentType || !validContentTypes.includes(rule.contentType)) {
|
|
1712
1712
|
return { valid: false, error: `规则[${index}](${rule.id}) 的 contentType 无效` };
|
|
1713
1713
|
}
|
|
@@ -2264,11 +2264,22 @@ class FileSystemDatabaseManager {
|
|
|
2264
2264
|
existing.lastRequestAt = now;
|
|
2265
2265
|
existing.requestCount++;
|
|
2266
2266
|
existing.totalTokens += session.totalTokens || 0;
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2267
|
+
if (session.vendorId !== undefined)
|
|
2268
|
+
existing.vendorId = session.vendorId;
|
|
2269
|
+
if (session.vendorName !== undefined)
|
|
2270
|
+
existing.vendorName = session.vendorName;
|
|
2271
|
+
if (session.serviceId !== undefined)
|
|
2272
|
+
existing.serviceId = session.serviceId;
|
|
2273
|
+
if (session.serviceName !== undefined)
|
|
2274
|
+
existing.serviceName = session.serviceName;
|
|
2275
|
+
if (session.model !== undefined)
|
|
2276
|
+
existing.model = session.model;
|
|
2277
|
+
if (session.highIqMode !== undefined)
|
|
2278
|
+
existing.highIqMode = session.highIqMode;
|
|
2279
|
+
if (Object.prototype.hasOwnProperty.call(session, 'highIqRuleId'))
|
|
2280
|
+
existing.highIqRuleId = session.highIqRuleId;
|
|
2281
|
+
if (Object.prototype.hasOwnProperty.call(session, 'highIqEnabledAt'))
|
|
2282
|
+
existing.highIqEnabledAt = session.highIqEnabledAt;
|
|
2272
2283
|
}
|
|
2273
2284
|
else {
|
|
2274
2285
|
// 创建新 session
|
|
@@ -2285,6 +2296,9 @@ class FileSystemDatabaseManager {
|
|
|
2285
2296
|
serviceId: session.serviceId,
|
|
2286
2297
|
serviceName: session.serviceName,
|
|
2287
2298
|
model: session.model,
|
|
2299
|
+
highIqMode: session.highIqMode,
|
|
2300
|
+
highIqRuleId: session.highIqRuleId,
|
|
2301
|
+
highIqEnabledAt: session.highIqEnabledAt,
|
|
2288
2302
|
});
|
|
2289
2303
|
}
|
|
2290
2304
|
// 异步保存(不阻塞)
|
|
@@ -144,63 +144,13 @@ class ProxyServer {
|
|
|
144
144
|
// 如果原始配置也不可用,返回错误
|
|
145
145
|
return res.status(404).json({ error: 'No matching route found and no original config available' });
|
|
146
146
|
}
|
|
147
|
-
//
|
|
148
|
-
const
|
|
149
|
-
const sessionId = this.defaultExtractSessionId(req, route.targetType);
|
|
150
|
-
if (highIqCommand === 'on') {
|
|
151
|
-
// 检查是否有可用的高智商规则
|
|
152
|
-
const highIqRule = yield this.findHighIqRule(route.id);
|
|
153
|
-
if (highIqRule) {
|
|
154
|
-
console.log('[HIGH-IQ] Command detected: ON');
|
|
155
|
-
// 更新会话状态
|
|
156
|
-
if (sessionId) {
|
|
157
|
-
const session = this.dbManager.getSession(sessionId);
|
|
158
|
-
this.dbManager.upsertSession({
|
|
159
|
-
id: sessionId,
|
|
160
|
-
targetType: route.targetType,
|
|
161
|
-
title: session === null || session === void 0 ? void 0 : session.title,
|
|
162
|
-
firstRequestAt: (session === null || session === void 0 ? void 0 : session.firstRequestAt) || Date.now(),
|
|
163
|
-
lastRequestAt: Date.now(),
|
|
164
|
-
vendorId: session === null || session === void 0 ? void 0 : session.vendorId,
|
|
165
|
-
vendorName: session === null || session === void 0 ? void 0 : session.vendorName,
|
|
166
|
-
serviceId: session === null || session === void 0 ? void 0 : session.serviceId,
|
|
167
|
-
serviceName: session === null || session === void 0 ? void 0 : session.serviceName,
|
|
168
|
-
model: session === null || session === void 0 ? void 0 : session.model,
|
|
169
|
-
totalTokens: (session === null || session === void 0 ? void 0 : session.totalTokens) || 0,
|
|
170
|
-
requestCount: ((session === null || session === void 0 ? void 0 : session.requestCount) || 0) + 1,
|
|
171
|
-
// 新增字段
|
|
172
|
-
highIqMode: true,
|
|
173
|
-
highIqRuleId: highIqRule.id,
|
|
174
|
-
highIqEnabledAt: Date.now()
|
|
175
|
-
});
|
|
176
|
-
console.log(`[HIGH-IQ] Session ${sessionId} enabled with rule ${highIqRule.id}`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
console.log('[HIGH-IQ] No available high-iq rule found');
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
else if (highIqCommand === 'off') {
|
|
184
|
-
console.log('[HIGH-IQ] Command detected: OFF');
|
|
185
|
-
// 关闭会话的高智商模式
|
|
186
|
-
if (sessionId) {
|
|
187
|
-
const session = this.dbManager.getSession(sessionId);
|
|
188
|
-
if (session === null || session === void 0 ? void 0 : session.highIqMode) {
|
|
189
|
-
this.dbManager.upsertSession(Object.assign(Object.assign({}, session), { highIqMode: false, lastRequestAt: Date.now(), requestCount: (session.requestCount || 0) + 1 }));
|
|
190
|
-
console.log(`[HIGH-IQ] Session ${sessionId} disabled`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// 移除命令前缀(在发送给上游API之前)
|
|
195
|
-
if (highIqCommand) {
|
|
196
|
-
req.body = this.removeHighIqCommand(req.body);
|
|
197
|
-
console.log(`[HIGH-IQ] Removed command prefix`);
|
|
198
|
-
}
|
|
147
|
+
// 高智商请求判定:从消息结构推断是否启用,不再使用 !x 显式关闭语法
|
|
148
|
+
const forcedContentType = yield this.prepareHighIqRouting(req, route, route.targetType);
|
|
199
149
|
// 检查是否启用故障切换
|
|
200
150
|
const enableFailover = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.enableFailover) !== false; // 默认为 true
|
|
201
151
|
if (!enableFailover) {
|
|
202
152
|
// 故障切换已禁用,使用传统的单一规则匹配
|
|
203
|
-
const rule = yield this.findMatchingRule(route.id, req);
|
|
153
|
+
const rule = yield this.findMatchingRule(route.id, req, forcedContentType);
|
|
204
154
|
if (!rule) {
|
|
205
155
|
return res.status(404).json({ error: 'No matching rule found' });
|
|
206
156
|
}
|
|
@@ -212,7 +162,7 @@ class ProxyServer {
|
|
|
212
162
|
return;
|
|
213
163
|
}
|
|
214
164
|
// 启用故障切换:获取所有候选规则
|
|
215
|
-
const allRules = this.getAllMatchingRules(route.id, req);
|
|
165
|
+
const allRules = this.getAllMatchingRules(route.id, req, forcedContentType);
|
|
216
166
|
if (allRules.length === 0) {
|
|
217
167
|
return res.status(404).json({ error: 'No matching rule found' });
|
|
218
168
|
}
|
|
@@ -401,63 +351,13 @@ class ProxyServer {
|
|
|
401
351
|
if (!route) {
|
|
402
352
|
return res.status(404).json({ error: `No active route found for target type: ${targetType}` });
|
|
403
353
|
}
|
|
404
|
-
//
|
|
405
|
-
const
|
|
406
|
-
const sessionId = this.defaultExtractSessionId(req, targetType);
|
|
407
|
-
if (highIqCommand === 'on') {
|
|
408
|
-
// 检查是否有可用的高智商规则
|
|
409
|
-
const highIqRule = yield this.findHighIqRule(route.id);
|
|
410
|
-
if (highIqRule) {
|
|
411
|
-
console.log('[HIGH-IQ] Command detected: ON');
|
|
412
|
-
// 更新会话状态
|
|
413
|
-
if (sessionId) {
|
|
414
|
-
const session = this.dbManager.getSession(sessionId);
|
|
415
|
-
this.dbManager.upsertSession({
|
|
416
|
-
id: sessionId,
|
|
417
|
-
targetType: route.targetType,
|
|
418
|
-
title: session === null || session === void 0 ? void 0 : session.title,
|
|
419
|
-
firstRequestAt: (session === null || session === void 0 ? void 0 : session.firstRequestAt) || Date.now(),
|
|
420
|
-
lastRequestAt: Date.now(),
|
|
421
|
-
vendorId: session === null || session === void 0 ? void 0 : session.vendorId,
|
|
422
|
-
vendorName: session === null || session === void 0 ? void 0 : session.vendorName,
|
|
423
|
-
serviceId: session === null || session === void 0 ? void 0 : session.serviceId,
|
|
424
|
-
serviceName: session === null || session === void 0 ? void 0 : session.serviceName,
|
|
425
|
-
model: session === null || session === void 0 ? void 0 : session.model,
|
|
426
|
-
totalTokens: (session === null || session === void 0 ? void 0 : session.totalTokens) || 0,
|
|
427
|
-
requestCount: ((session === null || session === void 0 ? void 0 : session.requestCount) || 0) + 1,
|
|
428
|
-
// 新增字段
|
|
429
|
-
highIqMode: true,
|
|
430
|
-
highIqRuleId: highIqRule.id,
|
|
431
|
-
highIqEnabledAt: Date.now()
|
|
432
|
-
});
|
|
433
|
-
console.log(`[HIGH-IQ] Session ${sessionId} enabled with rule ${highIqRule.id}`);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
else {
|
|
437
|
-
console.log('[HIGH-IQ] No available high-iq rule found');
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
else if (highIqCommand === 'off') {
|
|
441
|
-
console.log('[HIGH-IQ] Command detected: OFF');
|
|
442
|
-
// 关闭会话的高智商模式
|
|
443
|
-
if (sessionId) {
|
|
444
|
-
const session = this.dbManager.getSession(sessionId);
|
|
445
|
-
if (session === null || session === void 0 ? void 0 : session.highIqMode) {
|
|
446
|
-
this.dbManager.upsertSession(Object.assign(Object.assign({}, session), { highIqMode: false, lastRequestAt: Date.now(), requestCount: (session.requestCount || 0) + 1 }));
|
|
447
|
-
console.log(`[HIGH-IQ] Session ${sessionId} disabled`);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
// 移除命令前缀(在发送给上游API之前)
|
|
452
|
-
if (highIqCommand) {
|
|
453
|
-
req.body = this.removeHighIqCommand(req.body);
|
|
454
|
-
console.log(`[HIGH-IQ] Removed command prefix`);
|
|
455
|
-
}
|
|
354
|
+
// 高智商请求判定:从消息结构推断是否启用,不再使用 !x 显式关闭语法
|
|
355
|
+
const forcedContentType = yield this.prepareHighIqRouting(req, route, targetType);
|
|
456
356
|
// 检查是否启用故障切换
|
|
457
357
|
const enableFailover = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.enableFailover) !== false; // 默认为 true
|
|
458
358
|
if (!enableFailover) {
|
|
459
359
|
// 故障切换已禁用,使用传统的单一规则匹配
|
|
460
|
-
const rule = yield this.findMatchingRule(route.id, req);
|
|
360
|
+
const rule = yield this.findMatchingRule(route.id, req, forcedContentType);
|
|
461
361
|
if (!rule) {
|
|
462
362
|
return res.status(404).json({ error: 'No matching rule found' });
|
|
463
363
|
}
|
|
@@ -469,7 +369,7 @@ class ProxyServer {
|
|
|
469
369
|
return;
|
|
470
370
|
}
|
|
471
371
|
// 启用故障切换:获取所有候选规则
|
|
472
|
-
const allRules = this.getAllMatchingRules(route.id, req);
|
|
372
|
+
const allRules = this.getAllMatchingRules(route.id, req, forcedContentType);
|
|
473
373
|
if (allRules.length === 0) {
|
|
474
374
|
return res.status(404).json({ error: 'No matching rule found' });
|
|
475
375
|
}
|
|
@@ -976,7 +876,7 @@ class ProxyServer {
|
|
|
976
876
|
}
|
|
977
877
|
return service;
|
|
978
878
|
}
|
|
979
|
-
findMatchingRule(routeId, req) {
|
|
879
|
+
findMatchingRule(routeId, req, forcedContentType) {
|
|
980
880
|
return __awaiter(this, void 0, void 0, function* () {
|
|
981
881
|
const rules = this.getRulesByRouteId(routeId);
|
|
982
882
|
if (!rules || rules.length === 0)
|
|
@@ -987,27 +887,32 @@ class ProxyServer {
|
|
|
987
887
|
return undefined;
|
|
988
888
|
const body = req.body;
|
|
989
889
|
const requestModel = body === null || body === void 0 ? void 0 : body.model;
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
if (
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
const
|
|
996
|
-
if (
|
|
997
|
-
|
|
998
|
-
const highIqRule = yield this.findHighIqRule(routeId);
|
|
999
|
-
if (highIqRule && highIqRule.id === session.highIqRuleId) {
|
|
1000
|
-
console.log(`[HIGH-IQ] Session ${sessionId} using high-iq rule ${highIqRule.id}`);
|
|
1001
|
-
return highIqRule;
|
|
1002
|
-
}
|
|
1003
|
-
// 规则不可用,自动关闭高智商模式
|
|
1004
|
-
console.log(`[HIGH-IQ] Rule ${session.highIqRuleId} no longer available, auto-disable`);
|
|
890
|
+
const contentType = forcedContentType || this.determineContentType(req);
|
|
891
|
+
// 高智商规则优先于 model-mapping,确保 !!/推断命中时不会被模型映射覆盖
|
|
892
|
+
if (contentType === 'high-iq') {
|
|
893
|
+
const highIqRules = enabledRules.filter(rule => rule.contentType === 'high-iq');
|
|
894
|
+
for (const rule of highIqRules) {
|
|
895
|
+
const isBlacklisted = yield this.dbManager.isServiceBlacklisted(rule.targetServiceId, routeId, rule.contentType);
|
|
896
|
+
if (isBlacklisted) {
|
|
897
|
+
continue;
|
|
1005
898
|
}
|
|
899
|
+
this.dbManager.checkAndResetRuleIfNeeded(rule.id);
|
|
900
|
+
this.dbManager.checkAndResetRequestCountIfNeeded(rule.id);
|
|
901
|
+
if (rule.tokenLimit && rule.totalTokensUsed !== undefined && rule.totalTokensUsed >= rule.tokenLimit * 1000) {
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
if (rule.requestCountLimit && rule.totalRequestsUsed !== undefined && rule.totalRequestsUsed >= rule.requestCountLimit) {
|
|
905
|
+
continue;
|
|
906
|
+
}
|
|
907
|
+
if (this.isFrequencyLimitExceeded(rule)) {
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
return rule;
|
|
1006
911
|
}
|
|
1007
912
|
}
|
|
1008
913
|
// 1. 首先查找 model-mapping 类型的规则,按 sortOrder 降序匹配
|
|
1009
914
|
if (requestModel) {
|
|
1010
|
-
const modelMappingRules =
|
|
915
|
+
const modelMappingRules = enabledRules.filter(rule => rule.contentType === 'model-mapping' &&
|
|
1011
916
|
rule.replacedModel &&
|
|
1012
917
|
requestModel.includes(rule.replacedModel));
|
|
1013
918
|
// 过滤黑名单和token限制
|
|
@@ -1035,8 +940,7 @@ class ProxyServer {
|
|
|
1035
940
|
}
|
|
1036
941
|
}
|
|
1037
942
|
// 2. 查找其他内容类型的规则
|
|
1038
|
-
const
|
|
1039
|
-
const contentTypeRules = rules.filter(rule => rule.contentType === contentType);
|
|
943
|
+
const contentTypeRules = enabledRules.filter(rule => rule.contentType === contentType);
|
|
1040
944
|
// 过滤黑名单和token限制
|
|
1041
945
|
for (const rule of contentTypeRules) {
|
|
1042
946
|
const isBlacklisted = yield this.dbManager.isServiceBlacklisted(rule.targetServiceId, routeId, contentType);
|
|
@@ -1061,7 +965,7 @@ class ProxyServer {
|
|
|
1061
965
|
return rule;
|
|
1062
966
|
}
|
|
1063
967
|
// 3. 最后返回 default 规则
|
|
1064
|
-
const defaultRules =
|
|
968
|
+
const defaultRules = enabledRules.filter(rule => rule.contentType === 'default');
|
|
1065
969
|
// 过滤黑名单和token限制
|
|
1066
970
|
for (const rule of defaultRules) {
|
|
1067
971
|
const isBlacklisted = yield this.dbManager.isServiceBlacklisted(rule.targetServiceId, routeId, 'default');
|
|
@@ -1088,7 +992,7 @@ class ProxyServer {
|
|
|
1088
992
|
return undefined;
|
|
1089
993
|
});
|
|
1090
994
|
}
|
|
1091
|
-
getAllMatchingRules(routeId, req) {
|
|
995
|
+
getAllMatchingRules(routeId, req, forcedContentType) {
|
|
1092
996
|
const rules = this.getRulesByRouteId(routeId);
|
|
1093
997
|
if (!rules || rules.length === 0)
|
|
1094
998
|
return [];
|
|
@@ -1099,20 +1003,21 @@ class ProxyServer {
|
|
|
1099
1003
|
const body = req.body;
|
|
1100
1004
|
const requestModel = body === null || body === void 0 ? void 0 : body.model;
|
|
1101
1005
|
const candidates = [];
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1006
|
+
const contentType = forcedContentType || this.determineContentType(req);
|
|
1007
|
+
const prioritizeContentType = contentType === 'high-iq';
|
|
1008
|
+
const modelMappingRules = requestModel
|
|
1009
|
+
? enabledRules.filter(rule => rule.contentType === 'model-mapping' &&
|
|
1105
1010
|
rule.replacedModel &&
|
|
1106
|
-
requestModel.includes(rule.replacedModel))
|
|
1107
|
-
|
|
1108
|
-
}
|
|
1109
|
-
// 2. Content type specific rules
|
|
1110
|
-
const contentType = this.determineContentType(req);
|
|
1011
|
+
requestModel.includes(rule.replacedModel))
|
|
1012
|
+
: [];
|
|
1111
1013
|
const contentTypeRules = enabledRules.filter(rule => rule.contentType === contentType);
|
|
1112
|
-
candidates.push(...contentTypeRules);
|
|
1113
|
-
// 3. Default rules
|
|
1114
1014
|
const defaultRules = enabledRules.filter(rule => rule.contentType === 'default');
|
|
1115
|
-
|
|
1015
|
+
if (prioritizeContentType) {
|
|
1016
|
+
candidates.push(...contentTypeRules, ...modelMappingRules, ...defaultRules);
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
candidates.push(...modelMappingRules, ...contentTypeRules, ...defaultRules);
|
|
1020
|
+
}
|
|
1116
1021
|
// 4. 检查并重置到期的规则
|
|
1117
1022
|
candidates.forEach(rule => {
|
|
1118
1023
|
this.dbManager.checkAndResetRuleIfNeeded(rule.id);
|
|
@@ -1371,112 +1276,245 @@ class ProxyServer {
|
|
|
1371
1276
|
((_b = body === null || body === void 0 ? void 0 : body.reasoning) === null || _b === void 0 ? void 0 : _b.enabled));
|
|
1372
1277
|
}
|
|
1373
1278
|
hasHighIqSignal(body) {
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
for (
|
|
1379
|
-
|
|
1279
|
+
return this.inferHighIqRouting(body, false).shouldUseHighIq;
|
|
1280
|
+
}
|
|
1281
|
+
inferHighIqRouting(body, previousMode) {
|
|
1282
|
+
const messages = this.extractConversationMessages(body);
|
|
1283
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1284
|
+
const message = messages[i];
|
|
1285
|
+
if ((message === null || message === void 0 ? void 0 : message.role) !== 'user') {
|
|
1380
1286
|
continue;
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
if (
|
|
1384
|
-
|
|
1385
|
-
|
|
1287
|
+
}
|
|
1288
|
+
const signal = this.analyzeUserMessageForHighIq(message);
|
|
1289
|
+
if (!signal.hasHumanText) {
|
|
1290
|
+
continue;
|
|
1291
|
+
}
|
|
1292
|
+
if (signal.hasHighIqPrefix) {
|
|
1293
|
+
return {
|
|
1294
|
+
shouldUseHighIq: true,
|
|
1295
|
+
shouldStripPrefix: true,
|
|
1296
|
+
decisionSource: 'human',
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
return {
|
|
1300
|
+
shouldUseHighIq: false,
|
|
1301
|
+
shouldStripPrefix: false,
|
|
1302
|
+
decisionSource: 'human',
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
if (previousMode) {
|
|
1306
|
+
return {
|
|
1307
|
+
shouldUseHighIq: true,
|
|
1308
|
+
shouldStripPrefix: false,
|
|
1309
|
+
decisionSource: 'fallback',
|
|
1310
|
+
};
|
|
1311
|
+
}
|
|
1312
|
+
return {
|
|
1313
|
+
shouldUseHighIq: false,
|
|
1314
|
+
shouldStripPrefix: false,
|
|
1315
|
+
decisionSource: 'none',
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
prepareHighIqRouting(req, route, targetType) {
|
|
1319
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1320
|
+
const sessionId = this.defaultExtractSessionId(req, targetType);
|
|
1321
|
+
const session = sessionId ? this.dbManager.getSession(sessionId) : null;
|
|
1322
|
+
const previousMode = (session === null || session === void 0 ? void 0 : session.highIqMode) === true;
|
|
1323
|
+
const inference = this.inferHighIqRouting(req.body, previousMode);
|
|
1324
|
+
if (inference.shouldStripPrefix) {
|
|
1325
|
+
req.body = this.removeHighIqPrefix(req.body);
|
|
1326
|
+
console.log('[HIGH-IQ] Removed "!!" prefix from user message');
|
|
1327
|
+
}
|
|
1328
|
+
if (!inference.shouldUseHighIq) {
|
|
1329
|
+
if (sessionId && (session === null || session === void 0 ? void 0 : session.highIqMode) && inference.decisionSource === 'human') {
|
|
1330
|
+
yield this.dbManager.updateSession(sessionId, {
|
|
1331
|
+
highIqMode: false,
|
|
1332
|
+
highIqRuleId: undefined,
|
|
1333
|
+
lastRequestAt: Date.now(),
|
|
1334
|
+
});
|
|
1335
|
+
console.log(`[HIGH-IQ] Session ${sessionId} auto-disabled by latest human message`);
|
|
1386
1336
|
}
|
|
1337
|
+
return undefined;
|
|
1387
1338
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
}
|
|
1339
|
+
const highIqRule = yield this.findHighIqRule(route.id);
|
|
1340
|
+
if (!highIqRule) {
|
|
1341
|
+
if (sessionId && (session === null || session === void 0 ? void 0 : session.highIqMode)) {
|
|
1342
|
+
yield this.dbManager.updateSession(sessionId, {
|
|
1343
|
+
highIqMode: false,
|
|
1344
|
+
highIqRuleId: undefined,
|
|
1345
|
+
lastRequestAt: Date.now(),
|
|
1346
|
+
});
|
|
1396
1347
|
}
|
|
1348
|
+
console.log('[HIGH-IQ] Inferred high-iq request but no available high-iq rule found');
|
|
1349
|
+
return undefined;
|
|
1397
1350
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1351
|
+
if (sessionId && (!(session === null || session === void 0 ? void 0 : session.highIqMode) || session.highIqRuleId !== highIqRule.id)) {
|
|
1352
|
+
yield this.dbManager.updateSession(sessionId, {
|
|
1353
|
+
highIqMode: true,
|
|
1354
|
+
highIqRuleId: highIqRule.id,
|
|
1355
|
+
highIqEnabledAt: (session === null || session === void 0 ? void 0 : session.highIqEnabledAt) || Date.now(),
|
|
1356
|
+
lastRequestAt: Date.now(),
|
|
1357
|
+
});
|
|
1358
|
+
console.log(`[HIGH-IQ] Session ${sessionId} inferred ON with rule ${highIqRule.id}`);
|
|
1359
|
+
}
|
|
1360
|
+
return 'high-iq';
|
|
1361
|
+
});
|
|
1400
1362
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
*/
|
|
1405
|
-
detectHighIqCommand(body) {
|
|
1406
|
-
const messages = body === null || body === void 0 ? void 0 : body.messages;
|
|
1407
|
-
if (!Array.isArray(messages)) {
|
|
1408
|
-
return null;
|
|
1363
|
+
extractConversationMessages(body) {
|
|
1364
|
+
if (!body || typeof body !== 'object') {
|
|
1365
|
+
return [];
|
|
1409
1366
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1367
|
+
if (Array.isArray(body.messages)) {
|
|
1368
|
+
return body.messages;
|
|
1369
|
+
}
|
|
1370
|
+
if (typeof body.input === 'string') {
|
|
1371
|
+
return [{ role: 'user', content: body.input }];
|
|
1372
|
+
}
|
|
1373
|
+
if (Array.isArray(body.input)) {
|
|
1374
|
+
const normalized = [];
|
|
1375
|
+
for (const item of body.input) {
|
|
1376
|
+
if (item && typeof item === 'object' && typeof item.role === 'string') {
|
|
1377
|
+
normalized.push(item);
|
|
1420
1378
|
}
|
|
1421
|
-
if (
|
|
1422
|
-
|
|
1379
|
+
else if (typeof item === 'string') {
|
|
1380
|
+
normalized.push({ role: 'user', content: item });
|
|
1423
1381
|
}
|
|
1424
1382
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1383
|
+
return normalized;
|
|
1384
|
+
}
|
|
1385
|
+
if (body.input && typeof body.input === 'object' && typeof body.input.role === 'string') {
|
|
1386
|
+
return [body.input];
|
|
1387
|
+
}
|
|
1388
|
+
return [];
|
|
1389
|
+
}
|
|
1390
|
+
analyzeUserMessageForHighIq(message) {
|
|
1391
|
+
let hasHumanText = false;
|
|
1392
|
+
let hasHighIqPrefix = false;
|
|
1393
|
+
const scanText = (text, treatAsHuman) => {
|
|
1394
|
+
const trimmed = text.trim();
|
|
1395
|
+
if (!trimmed) {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
if (treatAsHuman) {
|
|
1399
|
+
hasHumanText = true;
|
|
1400
|
+
}
|
|
1401
|
+
if (treatAsHuman && trimmed.startsWith('!!')) {
|
|
1402
|
+
hasHighIqPrefix = true;
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
const content = message === null || message === void 0 ? void 0 : message.content;
|
|
1406
|
+
if (typeof content === 'string') {
|
|
1407
|
+
scanText(content, true);
|
|
1408
|
+
return { hasHumanText, hasHighIqPrefix };
|
|
1409
|
+
}
|
|
1410
|
+
const blocks = Array.isArray(content) ? content : [content];
|
|
1411
|
+
for (const block of blocks) {
|
|
1412
|
+
if (typeof block === 'string') {
|
|
1413
|
+
scanText(block, true);
|
|
1414
|
+
continue;
|
|
1415
|
+
}
|
|
1416
|
+
if (!block || typeof block !== 'object') {
|
|
1417
|
+
continue;
|
|
1418
|
+
}
|
|
1419
|
+
const type = typeof block.type === 'string' ? block.type : '';
|
|
1420
|
+
const toolGenerated = type === 'tool_result' || type === 'tool' || Boolean(block.tool_use_id || block.tool_call_id);
|
|
1421
|
+
if (typeof block.text === 'string') {
|
|
1422
|
+
scanText(block.text, !toolGenerated);
|
|
1423
|
+
}
|
|
1424
|
+
if (typeof block.content === 'string') {
|
|
1425
|
+
scanText(block.content, !toolGenerated);
|
|
1426
|
+
}
|
|
1427
|
+
if (Array.isArray(block.content)) {
|
|
1428
|
+
for (const nested of block.content) {
|
|
1429
|
+
if (typeof nested === 'string') {
|
|
1430
|
+
scanText(nested, !toolGenerated);
|
|
1431
|
+
continue;
|
|
1432
|
+
}
|
|
1433
|
+
if (nested && typeof nested === 'object') {
|
|
1434
|
+
if (typeof nested.text === 'string') {
|
|
1435
|
+
scanText(nested.text, !toolGenerated);
|
|
1431
1436
|
}
|
|
1432
|
-
if (
|
|
1433
|
-
|
|
1437
|
+
if (typeof nested.content === 'string') {
|
|
1438
|
+
scanText(nested.content, !toolGenerated);
|
|
1434
1439
|
}
|
|
1435
1440
|
}
|
|
1436
1441
|
}
|
|
1437
1442
|
}
|
|
1438
|
-
break; // 只检查最后一条用户消息
|
|
1439
1443
|
}
|
|
1440
|
-
return
|
|
1444
|
+
return { hasHumanText, hasHighIqPrefix };
|
|
1441
1445
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
*/
|
|
1445
|
-
removeHighIqCommand(body) {
|
|
1446
|
-
if (!(body === null || body === void 0 ? void 0 : body.messages))
|
|
1446
|
+
removeHighIqPrefix(body) {
|
|
1447
|
+
if (!body || typeof body !== 'object') {
|
|
1447
1448
|
return body;
|
|
1449
|
+
}
|
|
1448
1450
|
const processed = JSON.parse(JSON.stringify(body));
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
message.content = trimmed.replace(/^!x\s*/, '').trim();
|
|
1451
|
+
if (typeof processed.input === 'string') {
|
|
1452
|
+
processed.input = processed.input.replace(/^\s*!!\s*/, '');
|
|
1453
|
+
return processed;
|
|
1454
|
+
}
|
|
1455
|
+
if (Array.isArray(processed.input)) {
|
|
1456
|
+
for (let i = processed.input.length - 1; i >= 0; i--) {
|
|
1457
|
+
if (typeof processed.input[i] !== 'string') {
|
|
1458
|
+
continue;
|
|
1458
1459
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
1460
|
+
const next = processed.input[i].replace(/^\s*!!\s*/, '');
|
|
1461
|
+
if (next !== processed.input[i]) {
|
|
1462
|
+
processed.input[i] = next;
|
|
1463
|
+
return processed;
|
|
1461
1464
|
}
|
|
1462
1465
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1466
|
+
}
|
|
1467
|
+
const messages = this.extractConversationMessages(processed);
|
|
1468
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1469
|
+
const message = messages[i];
|
|
1470
|
+
if ((message === null || message === void 0 ? void 0 : message.role) !== 'user') {
|
|
1471
|
+
continue;
|
|
1472
|
+
}
|
|
1473
|
+
if (this.stripHighIqPrefixInMessage(message)) {
|
|
1474
|
+
break;
|
|
1475
1475
|
}
|
|
1476
|
-
break; // 只处理最后一条用户消息
|
|
1477
1476
|
}
|
|
1478
1477
|
return processed;
|
|
1479
1478
|
}
|
|
1479
|
+
stripHighIqPrefixInMessage(message) {
|
|
1480
|
+
const content = message === null || message === void 0 ? void 0 : message.content;
|
|
1481
|
+
if (typeof content === 'string') {
|
|
1482
|
+
const next = content.replace(/^\s*!!\s*/, '');
|
|
1483
|
+
if (next !== content) {
|
|
1484
|
+
message.content = next;
|
|
1485
|
+
return true;
|
|
1486
|
+
}
|
|
1487
|
+
return false;
|
|
1488
|
+
}
|
|
1489
|
+
if (!Array.isArray(content)) {
|
|
1490
|
+
return false;
|
|
1491
|
+
}
|
|
1492
|
+
for (const block of content) {
|
|
1493
|
+
if (!block || typeof block !== 'object') {
|
|
1494
|
+
continue;
|
|
1495
|
+
}
|
|
1496
|
+
const type = typeof block.type === 'string' ? block.type : '';
|
|
1497
|
+
const toolGenerated = type === 'tool_result' || type === 'tool' || Boolean(block.tool_use_id || block.tool_call_id);
|
|
1498
|
+
if (toolGenerated) {
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
if (typeof block.text === 'string') {
|
|
1502
|
+
const next = block.text.replace(/^\s*!!\s*/, '');
|
|
1503
|
+
if (next !== block.text) {
|
|
1504
|
+
block.text = next;
|
|
1505
|
+
return true;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
if (typeof block.content === 'string') {
|
|
1509
|
+
const next = block.content.replace(/^\s*!!\s*/, '');
|
|
1510
|
+
if (next !== block.content) {
|
|
1511
|
+
block.content = next;
|
|
1512
|
+
return true;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
return false;
|
|
1517
|
+
}
|
|
1480
1518
|
/**
|
|
1481
1519
|
* 查找可用的高智商规则
|
|
1482
1520
|
*/
|
|
@@ -1513,14 +1551,6 @@ class ProxyServer {
|
|
|
1513
1551
|
return undefined;
|
|
1514
1552
|
});
|
|
1515
1553
|
}
|
|
1516
|
-
/**
|
|
1517
|
-
* 获取路由的目标类型
|
|
1518
|
-
*/
|
|
1519
|
-
getRouteTargetType(routeId) {
|
|
1520
|
-
const routes = this.dbManager.getRoutes();
|
|
1521
|
-
const route = routes.find(r => r.id === routeId);
|
|
1522
|
-
return (route === null || route === void 0 ? void 0 : route.targetType) || null;
|
|
1523
|
-
}
|
|
1524
1554
|
hasBackgroundSignal(body) {
|
|
1525
1555
|
var _a, _b, _c;
|
|
1526
1556
|
// 检测 count tokens 请求:messages 只有一条,role 为 "user",content 为 "count"
|
|
@@ -2246,6 +2276,7 @@ class ProxyServer {
|
|
|
2246
2276
|
const totalTokens = ((usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.inputTokens) || 0) + ((usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.outputTokens) || 0) +
|
|
2247
2277
|
((usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.totalTokens) || 0);
|
|
2248
2278
|
const sessionTitle = this.defaultExtractSessionTitle(req, sessionId);
|
|
2279
|
+
const existingSession = this.dbManager.getSession(sessionId);
|
|
2249
2280
|
this.dbManager.upsertSession({
|
|
2250
2281
|
id: sessionId,
|
|
2251
2282
|
targetType,
|
|
@@ -2258,6 +2289,11 @@ class ProxyServer {
|
|
|
2258
2289
|
serviceName: service.name,
|
|
2259
2290
|
model: requestModel || rule.targetModel,
|
|
2260
2291
|
totalTokens,
|
|
2292
|
+
highIqMode: rule.contentType === 'high-iq' ? true : existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqMode,
|
|
2293
|
+
highIqRuleId: rule.contentType === 'high-iq' ? rule.id : existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqRuleId,
|
|
2294
|
+
highIqEnabledAt: rule.contentType === 'high-iq'
|
|
2295
|
+
? ((existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqEnabledAt) || Date.now())
|
|
2296
|
+
: existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqEnabledAt,
|
|
2261
2297
|
});
|
|
2262
2298
|
}
|
|
2263
2299
|
// 更新规则的token使用量(只在成功请求时更新)
|
|
@@ -119,7 +119,7 @@ Error generating stack: `+a.message+`
|
|
|
119
119
|
|
|
120
120
|
路由未停用,请检查配置文件权限。`)}try{await G.deactivateRoute(C),await _r(),await Gu()}catch(ye){throw new Error(`配置文件已恢复,但路由停用失败: ${ye.message||"未知错误"}
|
|
121
121
|
|
|
122
|
-
请刷新页面后重试。`)}}catch(ye){console.error("停用路由失败:",ye),te.error(ye.message)}finally{ka(null)}},Y2=async C=>{C.preventDefault();const Q=new FormData(C.currentTarget),me={name:Q.get("name"),description:Q.get("description"),targetType:Q.get("targetType"),isActive:!1};S?await G.updateRoute(S.id,me):await G.createRoute(me),v(!1),_r()},G2=async C=>{await e({message:"确定要删除此路由吗?",title:"确认删除",type:"danger",confirmText:"删除",cancelText:"取消"})&&(await G.deleteRoute(C),_r(),g&&g.id===C&&(y(null),a([])),te.success("路由已删除"))},X2=async C=>{if(C.preventDefault(),R==="image-understanding"&&be&&!le){te.warning("请选择一个MCP工具");return}if(!be&&!A){te.warning("请选择供应商API服务");return}if(!be&&P!==void 0&&It!==void 0&&P>It){te.warning(`Token超量值 (${P}k) 不能超过API服务的限制 (${It}k)`);return}if(!be&&se!==void 0&&W!==void 0&&se>W){te.warning(`请求次数超量值 (${se}) 不能超过API服务的限制 (${W})`);return}const Q=new FormData(C.currentTarget),me={routeId:g.id,contentType:Q.get("contentType"),targetServiceId:be?"":A,targetModel:be?void 0:N||void 0,replacedModel:D||void 0,sortOrder:L,timeout:K?K*1e3:void 0,tokenLimit:be?void 0:P||void 0,resetInterval:be?void 0:Z,tokenResetBaseTime:be?void 0:ce?ce.getTime():void 0,requestCountLimit:be?void 0:se,requestResetInterval:be?void 0:V,requestResetBaseTime:be?void 0:q?q.getTime():void 0,frequencyLimit:Ce,frequencyWindow:we,useMCP:R==="image-understanding"?be:!1,mcpId:R==="image-understanding"&&be?le:void 0};j?await G.updateRule(j.id,me):await G.createRule(me),w(!1),g&&Ee(g.id)},Q2=async C=>{await e({message:"确定要删除此路由吗?",title:"确认删除",type:"danger",confirmText:"删除",cancelText:"取消"})&&(await G.deleteRule(C),g&&Ee(g.id),te.success("规则已删除"))},Z2=async C=>{try{await G.clearRuleBlacklist(C),g&&Ee(g.id),te.success("已恢复")}catch(Q){te.error("恢复失败: "+Q.message)}},J2=async C=>{try{const Q=await G.toggleRuleDisable(C);g&&Ee(g.id),te.success(Q.isDisabled?"规则已屏蔽":"规则已启用")}catch(Q){te.error("操作失败: "+Q.message)}},eM=async C=>{try{const Q=i.find(ye=>ye.id===C);if(!Q)return;const me=(Q.sortOrder||0)+1;await G.updateRule(C,{sortOrder:me}),g&&Ee(g.id),te.success("优先级已提升")}catch(Q){te.error("操作失败: "+Q.message)}},tM=async C=>{try{const Q=i.find(ye=>ye.id===C);if(!Q)return;const me=Math.max(0,(Q.sortOrder||0)-1);await G.updateRule(C,{sortOrder:me}),g&&Ee(g.id),te.success("优先级已降低")}catch(Q){te.error("操作失败: "+Q.message)}},nM=async C=>{if(g){if(C&&!B()){te.error("当前 Claude Code 版本不支持 Agent Teams 功能,需要版本 ≥ 2.1.32");return}try{g.isActive?(await G.updateClaudeAgentTeams(C),await G.updateRoute(g.id,{enableAgentTeams:C}),te.success(C?"Agent Teams 功能已开启":"Agent Teams 功能已关闭")):(await G.updateRoute(g.id,{enableAgentTeams:C}),te.success(C?"Agent Teams 设置已保存(将在激活时生效)":"Agent Teams 设置已取消")),y({...g,enableAgentTeams:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}}},rM=async C=>{if(g)try{g.isActive?(await G.updateClaudeBypassPermissionsSupport(C),await G.updateRoute(g.id,{enableBypassPermissionsSupport:C}),te.success(C?"对bypassPermissions的支持已开启":"对bypassPermissions的支持已关闭")):(await G.updateRoute(g.id,{enableBypassPermissionsSupport:C}),te.success(C?"对bypassPermissions的支持设置已保存(将在激活时生效)":"对bypassPermissions的支持设置已取消")),y({...g,enableBypassPermissionsSupport:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}},iM=async C=>{if(!(!g||g.targetType!=="codex"))try{if(Gt(!0),g.isActive){if(!await G.updateCodexReasoningEffort(C))throw new Error("Codex 配置文件未处于代理状态,请先重新激活路由");await G.updateRoute(g.id,{codexModelReasoningEffort:C}),te.success("Reasoning Effort 已更新,Codex 配置已立即生效")}else await G.updateRoute(g.id,{codexModelReasoningEffort:C}),te.success("Reasoning Effort 设置已保存(将在激活时生效)");y({...g,codexModelReasoningEffort:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}finally{Gt(!1)}},aM=()=>Ew,oM=C=>{E(C),z(C.contentType),F(C.useMCP||!1),oe(C.mcpId||"");const Q=s.find(me=>me.id===C.targetServiceId);Q?(Q.vendorId&&(M(Q.vendorId),f(s.filter(me=>me.vendorId===Q.vendorId))),setTimeout(()=>{if(_(Q.id),H(C.targetModel||""),O(C.replacedModel||""),U(C.sortOrder||0),J(C.timeout?C.timeout/1e3:void 0),X(C.tokenLimit||void 0),I(C.resetInterval),ge(C.tokenResetBaseTime?new Date(C.tokenResetBaseTime):void 0),Y(C.requestCountLimit),ue(C.requestResetInterval),_e(C.requestResetBaseTime?new Date(C.requestResetBaseTime):void 0),ve(C.frequencyLimit),Pe(C.frequencyWindow),Q.enableTokenLimit&&Q.tokenLimit){Yt(Q.tokenLimit);const me=C.tokenLimit===Q.tokenLimit&&C.resetInterval===(Q.tokenResetInterval||void 0)&&C.tokenLimit!==null&&C.resetInterval!==null;Bt(me)}else Yt(void 0),Bt(!1);if(Q.enableRequestLimit&&Q.requestCountLimit){ee(Q.requestCountLimit);const me=C.requestCountLimit===Q.requestCountLimit&&C.requestResetInterval===(Q.requestResetInterval||void 0)&&C.requestCountLimit!==null&&C.requestResetInterval!==null;wt(me)}else ee(void 0),wt(!1);Be(!!C.tokenLimit),qe(!!C.requestCountLimit)},0)):C.useMCP&&(M(""),_(""),H(""),O(""),U(C.sortOrder||0),J(C.timeout?C.timeout/1e3:void 0),Be(!1),qe(!1)),w(!0)},lM=C=>{var Ll;const Q=xe[C.id],me=[],ye=t[C.id];if((ye==null?void 0:ye.status)==="in_use")return{status:"in_use",label:"使用中",reason:"正在处理请求"};if(Q!=null&&Q.isBlacklisted){const je=Q.blacklistEntry;(je==null?void 0:je.errorType)==="timeout"?me.push("请求超时"):je!=null&&je.lastStatusCode&&me.push(`HTTP ${je.lastStatusCode}错误`)}const pt=(ye==null?void 0:ye.totalTokensUsed)!==void 0?ye.totalTokensUsed:C.totalTokensUsed;C.tokenLimit&&pt!==void 0&&pt>=C.tokenLimit*1e3&&me.push("Token超限");const Le=(ye==null?void 0:ye.totalRequestsUsed)!==void 0?ye.totalRequestsUsed:C.totalRequestsUsed;if(C.requestCountLimit&&Le!==void 0&&Le>=C.requestCountLimit&&me.push("次数超限"),me.length>0)return{status:"error",label:Q!=null&&Q.isBlacklisted?((Ll=Q.blacklistEntry)==null?void 0:Ll.errorType)==="timeout"?"超时":"服务错误":me[0],reason:me.join(", ")};const Xt=[];if(C.tokenLimit&&pt!==void 0){const je=pt/(C.tokenLimit*1e3)*100;je>=80&&Xt.push(`Token ${je.toFixed(0)}%`)}if(C.requestCountLimit&&Le!==void 0){const je=Le/C.requestCountLimit*100;je>=80&&Xt.push(`次数 ${je.toFixed(0)}%`)}return Xt.length>0?{status:"warning",label:"接近限制",reason:Xt.join(", ")}:{status:"success",label:"正常",reason:""}},sM=()=>{E(null),z("default"),M(""),_(""),H(""),O(""),U(0),J(void 0),X(void 0),I(void 0),ge(void 0),Y(void 0),ue(void 0),_e(void 0),Bt(!1),wt(!1),Yt(void 0),ee(void 0),Be(!1),qe(!1),F(!1),oe(""),w(!0)};return u.jsxs("div",{className:"routes-page",children:[u.jsxs("div",{className:"page-header",children:[u.jsx("h1",{children:"路由管理"}),u.jsx("p",{children:"管理API路由和路由配置"})]}),u.jsx("div",{style:{display:"flex",flexDirection:"column"},children:u.jsxs("div",{style:{display:"flex",gap:"20px"},children:[u.jsxs("div",{className:"card",style:{flex:"0 0 25%",minWidth:300},children:[u.jsxs("div",{className:"toolbar",children:[u.jsx("h3",{children:"路由"}),u.jsx("button",{className:"btn btn-primary",onClick:()=>v(!0),children:"新建"})]}),n.length===0?u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"暂无路由"})}):u.jsx("div",{style:{marginTop:"10px"},children:n.map(C=>{var Q,me;return u.jsx("div",{ref:ye=>{ye?Qn.current.set(C.id,ye):Qn.current.delete(C.id)},onClick:()=>y(C),style:{padding:"12px",marginBottom:"8px",backgroundColor:g&&g.id===C.id?"var(--bg-route-item-selected)":"var(--bg-route-item)",borderRadius:"8px",cursor:"pointer",border:"1px solid var(--border-primary)",position:"relative"},children:u.jsxs("div",{children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[u.jsx("div",{style:{fontWeight:500},children:C.name}),C.isActive&&u.jsxs("span",{className:`badge ${C.targetType==="claude-code"?"badge-claude-code":"badge-codex"}`,style:{position:"absolute",top:-16,right:-8},children:[(Q=rm.find(ye=>ye.value===C.targetType))==null?void 0:Q.label," 已激活"]})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-route-muted)",marginTop:"2px"},children:["客户端工具: ",(me=rm.find(ye=>ye.value===C.targetType))==null?void 0:me.label]}),u.jsxs("div",{className:"action-buttons",style:{marginTop:"8px"},children:[C.isActive?u.jsx("button",{className:"btn btn-warning",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),q2(C.id)},disabled:Xn!==null,children:Xn===C.id?"处理中...":"停用"}):u.jsx("button",{className:"btn btn-success",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),V2(C.id)},disabled:Xn!==null,children:Xn===C.id?"处理中...":"激活"}),u.jsx("button",{className:"btn btn-secondary",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),k(C),v(!0)},children:"编辑"}),u.jsx("button",{className:"btn btn-danger",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),G2(C.id)},disabled:C.isActive,children:"删除"})]})]})},C.id)})})]}),u.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column"},children:[u.jsxs("div",{className:"card",style:{flex:1},children:[u.jsxs("div",{className:"toolbar",children:[u.jsx("h3",{children:"规则列表"}),g&&u.jsx("button",{className:"btn btn-primary",onClick:sM,children:"新建规则"})]}),g?i.length===0?u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"暂无路由"})}):u.jsxs("table",{className:"rules-table",children:[u.jsx("thead",{children:u.jsxs("tr",{children:[u.jsx("th",{className:"col-priority",children:"优先级"}),u.jsx("th",{children:"类型"}),u.jsx("th",{children:"API服务"}),u.jsx("th",{children:"状态"}),u.jsx("th",{children:"用量情况"}),u.jsx("th",{children:"操作"})]})}),u.jsx("tbody",{children:[...i].sort((C,Q)=>{const me=C.sortOrder||0,ye=Q.sortOrder||0;if(me!==ye)return ye-me;const pt=Ow[C.contentType]??999,Le=Ow[Q.contentType]??999;return pt-Le}).map(C=>{var pt,Le,Xt,Ll;const Q=s.find(je=>je.id===C.targetServiceId),me=o.find(je=>je.id===(Q==null?void 0:Q.vendorId)),ye=(pt=Ew.find(je=>je.value===C.contentType))==null?void 0:pt.label;return u.jsxs("tr",{children:[u.jsx("td",{className:"col-priority",children:u.jsxs("div",{className:"col-priority-box",children:[u.jsx("span",{children:C.sortOrder||0}),u.jsx("button",{className:"priority-arrow-btn",onClick:()=>tM(C.id),title:"降低优先级",children:"↓"}),u.jsx("button",{className:"priority-arrow-btn",onClick:()=>eM(C.id),title:"提升优先级",children:"↑"})]})}),u.jsx("td",{children:u.jsxs("div",{style:{fontSize:"12px",whiteSpace:"nowrap"},children:[C.contentType!=="default"&&Aw[C.contentType]&&u.jsx("span",{style:{fontSize:"14px"},children:Aw[C.contentType]}),u.jsx("span",{children:ye}),C.contentType==="model-mapping"&&C.replacedModel&&u.jsxs("div",{style:{position:"relative",display:"inline-block"},onMouseEnter:()=>Pt(C.id),onMouseLeave:()=>Pt(null),children:[u.jsx("span",{style:{cursor:"help",fontSize:"14px",color:"var(--text-info)",fontWeight:"bold"},children:"ⓘ"}),Dn===C.id&&u.jsxs("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"calc(100% + 8px)",backgroundColor:"var(--bg-popover, #333)",color:"var(--text-popover, #fff)",padding:"6px 10px",borderRadius:"4px",fontSize:"12px",whiteSpace:"nowrap",zIndex:1e3,boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},children:["被顶替的模型是: ",C.replacedModel,u.jsx("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"-4px",width:"0",height:"0",borderLeft:"4px solid transparent",borderRight:"4px solid transparent",borderTop:"4px solid var(--bg-popover, #333)"}})]})]})]})}),u.jsx("td",{children:u.jsx("div",{className:"vendor-sevices-col",style:{fontSize:"0.6em"},children:C.useMCP?u.jsxs(u.Fragment,{children:[u.jsxs("div",{children:["MCP:",((Le=p.find(je=>je.id===C.mcpId))==null?void 0:Le.name)||"Unknown"]}),u.jsx("div",{style:{fontSize:"11px",color:"var(--text-muted)"},children:"使用MCP工具"})]}):u.jsxs(u.Fragment,{children:[u.jsxs("div",{children:["供应商:",me?me.name:"Unknown"]}),u.jsxs("div",{children:["服务:",Q?Q.name:"Unknown"]}),u.jsxs("div",{children:["模型:",C.targetModel||"透传模型"]})]})})}),u.jsx("td",{style:{whiteSpace:"nowrap"},children:(()=>{var mb,gb;const je=lM(C),mn=xe[C.id],uM=(mn==null?void 0:mn.isBlacklisted)&&!((mb=je.reason)!=null&&mb.includes("Token超限"))&&!((gb=je.reason)!=null&&gb.includes("次数超限"));return C.isDisabled?u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px"},children:[u.jsx("span",{style:{color:"#6c757d",fontWeight:"bold",fontSize:"14px"},children:"⊘"}),u.jsx("span",{style:{fontSize:"13px",color:"#6c757d",fontWeight:"bold"},children:"已屏蔽"})]}):u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",flexWrap:"wrap"},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px"},children:[je.status==="success"&&u.jsx("span",{style:{color:"#28a745",fontWeight:"bold",fontSize:"14px"},children:"✓"}),je.status==="warning"&&u.jsx("span",{style:{color:"#ffc107",fontWeight:"bold",fontSize:"14px"},children:"⚠"}),je.status==="error"&&u.jsx("span",{style:{color:"#dc3545",fontWeight:"bold",fontSize:"14px"},children:"✗"}),je.status==="in_use"&&u.jsx(u.Fragment,{children:u.jsx("span",{style:{color:"#007bff",fontWeight:"bold",fontSize:"14px",animation:"pulse 1.5s ease-in-out infinite"},children:"●"})}),u.jsx("span",{style:{fontSize:"13px",color:je.status==="success"?"#28a745":je.status==="warning"?"#ffc107":je.status==="in_use"?"#007bff":"#dc3545",fontWeight:je.status!=="success"?"bold":"normal"},children:je.label}),je.reason&&u.jsxs("div",{style:{position:"relative",display:"inline-block",cursor:"help"},onMouseEnter:()=>Pt(C.id+"-status"),onMouseLeave:()=>Pt(null),children:[u.jsx("span",{style:{fontSize:"12px",color:"#999",marginLeft:"4px"},children:" ⓘ"}),Dn===C.id+"-status"&&u.jsxs("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"calc(100% + 8px)",backgroundColor:"var(--bg-popover, #333)",color:"var(--text-popover, #fff)",padding:"6px 10px",borderRadius:"4px",fontSize:"12px",whiteSpace:"nowrap",zIndex:1e3,boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},children:[je.reason,u.jsx("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"-4px",width:"0",height:"0",borderLeft:"4px solid transparent",borderRight:"4px solid transparent",borderTop:"4px solid var(--bg-popover, #333)"}})]})]})]}),uM&&u.jsx("button",{className:"btn btn-info",style:{padding:"2px 8px",fontSize:"11px"},onClick:()=>Z2(C.id),children:"恢复"})]})})()}),u.jsx("td",{children:C.tokenLimit||C.requestCountLimit?u.jsxs("div",{style:{fontSize:"13px"},children:[C.tokenLimit&&u.jsxs("div",{style:{whiteSpace:"nowrap"},children:[u.jsx("span",{style:{fontWeight:"bold",fontSize:"12px"},children:"Tokens:"}),u.jsxs(u.Fragment,{children:[u.jsxs("span",{style:{color:(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalTokensUsed)??C.totalTokensUsed;return je&&C.tokenLimit&&je>=C.tokenLimit*1e3?"red":"inherit"})()},children:[(((((Xt=t[C.id])==null?void 0:Xt.totalTokensUsed)??C.totalTokensUsed)||0)/1e3).toFixed(1),"K/",C.tokenLimit.toFixed(0),"K"]}),(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalTokensUsed)??C.totalTokensUsed;return je&&C.tokenLimit&&je>=C.tokenLimit*1e3?u.jsx("span",{style:{color:"red",marginLeft:"4px",fontWeight:"bold",fontSize:"11px"},children:"超限"}):null})()]})]}),C.requestCountLimit&&u.jsxs("div",{style:{marginTop:C.tokenLimit?"6px":0},children:[u.jsx("span",{style:{fontWeight:"bold",fontSize:"12px"},children:"次数:"}),u.jsxs(u.Fragment,{children:[u.jsxs("span",{style:{color:(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalRequestsUsed)??C.totalRequestsUsed;return je&&C.requestCountLimit&&je>=C.requestCountLimit?"red":"inherit"})()},children:[(((Ll=t[C.id])==null?void 0:Ll.totalRequestsUsed)??C.totalTokensUsed)||0,"/",C.requestCountLimit]}),(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalRequestsUsed)??C.totalRequestsUsed;return je&&C.requestCountLimit&&je>=C.requestCountLimit?u.jsx("span",{style:{color:"red",marginLeft:"4px",fontWeight:"bold",fontSize:"11px"},children:"超限"}):null})()]})]})]}):u.jsx("span",{style:{color:"#999",fontSize:"12px"},children:"不限制"})}),u.jsx("td",{children:u.jsxs("div",{className:"action-buttons",style:{justifyContent:"flex-end"},children:[u.jsx("button",{className:`btn ${C.isDisabled?"btn-success":"btn-warning"}`,onClick:()=>J2(C.id),title:C.isDisabled?"启用规则":"临时屏蔽规则",children:C.isDisabled?"启用":"屏蔽"}),u.jsx("button",{className:"btn btn-secondary",onClick:()=>oM(C),children:"编辑"}),u.jsx("button",{className:"btn btn-danger",onClick:()=>Q2(C.id),children:"删除"})]})})]},C.id)})})]}):u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"请先选择一个路由"})}),g&&i.length>0&&u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-info-box)",marginTop:"16px",padding:"12px",backgroundColor:"var(--bg-info-box)",borderRadius:"6px",border:"1px solid var(--border-info-box)",lineHeight:"1.6"},children:[u.jsx("strong",{children:"💡 智能故障切换机制"}),u.jsxs("div",{style:{marginTop:"6px"},children:["• 当同一请求类型配置多个规则时,系统会按排序优先使用第一个",u.jsx("br",{}),"• 如果某个服务报错(4xx/5xx)或请求超时,将自动切换到下一个可用服务",u.jsx("br",{}),"• 报错或超时的服务会被标记为不可用,有效期10分钟",u.jsx("br",{}),"• 10分钟后自动解除标记,如果再次报错或超时则重新标记",u.jsx("br",{}),"• 确保您的请求始终路由到稳定可用的服务",u.jsx("br",{}),"• 规则状态列会实时显示每个规则的可用性状态",u.jsx("br",{}),"• 如不需要此功能,可在",u.jsx("strong",{children:"设置"}),'页面关闭"启用智能故障切换"选项']})]})]}),g&&g.targetType==="claude-code"&&u.jsxs("div",{className:"card",children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"Claude Code 配置"})}),u.jsxs("div",{style:{padding:"20px"},children:[!B()&&((fb=Me==null?void 0:Me.claudeCode)==null?void 0:fb.version)&&u.jsxs("div",{style:{backgroundColor:"var(--bg-warning, #fff3cd)",border:"1px solid var(--border-warning, #ffc107)",borderRadius:"6px",padding:"12px",marginBottom:"12px",fontSize:"13px",color:"var(--text-warning, #856404)"},children:["⚠️ 当前 Claude Code 版本 (",Me.claudeCode.version,") 不支持 Agent Teams 功能。",u.jsx("br",{}),"Agent Teams 功能需要 Claude Code 版本 ≥ 2.1.32。请升级 Claude Code 后再使用此功能。"]}),u.jsxs("div",{style:{marginBottom:"20px"},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("input",{type:"checkbox",id:"agent-teams-toggle",checked:g.enableAgentTeams||!1,onChange:C=>nM(C.target.checked),disabled:!B(),style:{cursor:B()?"pointer":"not-allowed",width:"16px",height:"16px"}}),u.jsx("label",{htmlFor:"agent-teams-toggle",style:{cursor:B()?"pointer":"not-allowed",fontSize:"14px",userSelect:"none",color:B()?"inherit":"var(--text-muted)"},children:"开启 Agent Teams 功能"})]}),u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:B()?g.isActive?"开启后将启用 Agent Teams 实验性功能,可在重启claude code后立即生效。":"开启后将在激活此路由时启用 Agent Teams 实验性功能。":"Agent Teams 功能需要 Claude Code 版本 ≥ 2.1.32。请升级 Claude Code 后再使用此功能。"})]}),u.jsxs("div",{children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("input",{type:"checkbox",id:"bypass-permissions-support-toggle",checked:g.enableBypassPermissionsSupport||!1,onChange:C=>rM(C.target.checked),style:{cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("label",{htmlFor:"bypass-permissions-support-toggle",style:{cursor:"pointer",fontSize:"14px",userSelect:"none"},children:"开启对 bypassPermissions 的支持"})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:["开启后默认编辑跳过危险模式权限提示,你可以切换到其他模式",g.isActive?"。开启后立即写入配置文件,可在重启claude code后立即生效。":"。开启后将在激活此路由时写入配置文件。"]})]})]})]}),g&&g.targetType==="codex"&&u.jsxs("div",{className:"card",children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"Codex 配置"})}),u.jsxs("div",{style:{padding:"20px"},children:[u.jsxs("div",{className:"form-group",style:{marginBottom:"0",maxWidth:"420px",display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("label",{htmlFor:"codex-reasoning-effort",style:{marginBottom:0,minWidth:"120px",whiteSpace:"nowrap"},children:"Reasoning Effort"}),u.jsx("select",{id:"codex-reasoning-effort",value:Tw(g),onChange:C=>iM(C.target.value),disabled:Rl,style:{flex:1,minWidth:0},children:YO.map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:g.isActive?"修改后会立即覆盖写入 ~/.codex/config.toml 的 model_reasoning_effort。":"该设置会在激活此路由时写入 ~/.codex/config.toml。"})]})]})]})]})}),u.jsxs("div",{className:"card",style:{marginTop:"20px"},children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"📝 配置文件自动管理"})}),u.jsxs("div",{style:{padding:"20px",lineHeight:"1.8"},children:[u.jsxs("div",{style:{background:"var(--bg-info-blue)",padding:"15px",borderRadius:"8px",marginBottom:"15px",borderLeft:"4px solid var(--border-info-blue)"},children:[u.jsx("strong",{children:"💡 工作原理"}),u.jsx("p",{style:{marginTop:"8px",marginBottom:"0"},children:"激活路由时,系统会自动修改编程工具的配置文件,使其通过本代理服务器访问AI服务。 停用路由时,系统会自动恢复原始配置。"})]}),u.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"15px"},children:[u.jsxs("div",{style:{background:"var(--bg-info-green)",padding:"15px",borderRadius:"8px",borderLeft:"4px solid var(--border-info-green)"},children:[u.jsx("strong",{children:"✓ 激活路由"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsx("li",{children:"首次激活:自动备份并覆盖配置文件"}),u.jsx("li",{children:"再次激活:仅切换路由,不重复覆盖"})]})]}),u.jsxs("div",{style:{background:"var(--bg-info-orange)",padding:"15px",borderRadius:"8px",borderLeft:"4px solid var(--border-info-orange)"},children:[u.jsx("strong",{children:"○ 停用路由"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsx("li",{children:"自动恢复原始配置文件"}),u.jsx("li",{children:"删除备份文件"})]})]})]}),u.jsxs("div",{style:{marginTop:"15px",padding:"12px 15px",background:"var(--bg-info-yellow)",borderRadius:"8px",borderLeft:"4px solid var(--border-info-yellow)"},children:[u.jsx("strong",{children:"⚠️ 重要提示"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsxs("li",{children:["激活(首次)/停用路由后,",u.jsx("strong",{children:"必须重启对应的编程工具"}),"才能使配置生效"]}),u.jsx("li",{children:"操作前建议关闭编程工具,避免配置冲突"})]})]}),u.jsxs("details",{style:{marginTop:"15px",cursor:"pointer"},children:[u.jsx("summary",{style:{fontWeight:"bold",color:"#666"},children:"📂 配置文件位置(点击展开)"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",color:"#666"},children:[u.jsxs("li",{children:[u.jsx("strong",{children:"Claude Code:"})," ~/.claude/settings.json, ~/.claude.json"]}),u.jsxs("li",{children:[u.jsx("strong",{children:"Codex:"})," ~/.codex/config.toml, ~/.codex/auth.json"]})]})]})]})]}),x&&u.jsxs("div",{className:"modal-overlay",children:[u.jsx("button",{type:"button",className:"modal-close-btn",onClick:()=>v(!1),"aria-label":"关闭",children:"×"}),u.jsx("div",{className:"modal",children:u.jsxs("div",{className:"modal-container",children:[u.jsx("div",{className:"modal-header",children:u.jsx("h2",{children:S?"编辑路由":"新建路由"})}),u.jsxs("form",{onSubmit:Y2,children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"路由名称"}),u.jsx("input",{type:"text",name:"name",defaultValue:S?S.name:"",required:!0})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"描述"}),u.jsx("textarea",{name:"description",rows:3,defaultValue:S?S.description:""})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"客户端工具"}),u.jsx("select",{name:"targetType",defaultValue:S?S.targetType:"claude-code",required:!0,children:rm.map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),u.jsxs("div",{className:"modal-footer",children:[u.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>v(!1),children:"取消"}),u.jsx("button",{type:"submit",className:"btn btn-primary",children:"保存"})]})]})]})})]}),b&&u.jsxs("div",{className:"modal-overlay",children:[u.jsx("button",{type:"button",className:"modal-close-btn",onClick:()=>w(!1),"aria-label":"关闭",children:"×"}),u.jsx("div",{className:"modal",children:u.jsxs("div",{className:"modal-container",children:[u.jsx("div",{className:"modal-header",children:u.jsx("h2",{children:j?"编辑规则":"新建规则"})}),u.jsxs("form",{onSubmit:X2,children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"对象请求类型"}),u.jsx("select",{name:"contentType",value:R,required:!0,onChange:C=>{z(C.target.value)},children:aM().map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),R==="high-iq"&&u.jsxs("div",{style:{background:"var(--bg-info-blue)",padding:"12px",borderRadius:"6px",borderLeft:"4px solid var(--border-info-blue)",marginBottom:"16px"},children:[u.jsx("div",{style:{fontSize:"13px",fontWeight:"bold",marginBottom:"6px"},children:"💡 高智商请求使用方法"}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",lineHeight:"1.6"},children:["在编程工具中输入提示词时:",u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",lineHeight:"1.8"},children:[u.jsxs("li",{children:["使用 ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!!"})," 开启高智商模式(整个会话持续使用)"]}),u.jsxs("li",{children:["使用 ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!x"})," 关闭高智商模式"]})]})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"8px",lineHeight:"1.6"},children:[u.jsx("strong",{children:"示例:"}),u.jsx("br",{}),"• ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!! 重构A模块"}),u.jsx("br",{}),"• ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!x 继续正常对话"})]})]}),R==="model-mapping"&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{children:["被顶替模型 ",u.jsx("small",{children:"(可在日志中找出想要顶替的模型名)"})]}),u.jsx("input",{type:"text",value:D,onChange:C=>O(C.target.value),placeholder:"例如:gpt-4"})]}),R==="image-understanding"&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:"pointer"},children:[u.jsx("input",{type:"checkbox",checked:be,onChange:C=>F(C.target.checked),style:{marginRight:"8px",cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"使用MCP"})]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"开启后,将使用MCP工具处理图像理解请求,而不是直接调用API服务"})]}),R==="image-understanding"&&be&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{children:["选择MCP工具 ",u.jsx("span",{className:"required",children:"*"})]}),u.jsx("div",{style:{maxHeight:"300px",overflowY:"auto",border:"1px solid var(--border-primary)",borderRadius:"6px",padding:"8px"},children:p.length===0?u.jsx("div",{style:{padding:"12px",textAlign:"center",color:"var(--text-muted)"},children:"暂无MCP工具,请先在MCP管理页面添加"}):p.map(C=>u.jsxs("div",{onClick:()=>oe(C.id),style:{padding:"12px",marginBottom:"8px",border:`2px solid ${le===C.id?"var(--primary-color)":"var(--border-primary)"}`,borderRadius:"6px",cursor:"pointer",backgroundColor:le===C.id?"var(--bg-info-blue)":"var(--bg-card)",transition:"all 0.2s ease"},children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[u.jsx("div",{style:{fontWeight:600,fontSize:"14px"},children:C.name}),u.jsx("div",{className:"badge badge-secondary",style:{fontSize:"11px"},children:C.type==="stdio"?"命令行":C.type.toUpperCase()})]}),C.description&&u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"4px"},children:C.description})]},C.id))})]}),!be&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商"}),u.jsxs("select",{value:T,onChange:C=>M(C.target.value),required:!0,children:[u.jsx("option",{value:"",disabled:!0,children:"请选择供应商"}),o.map(C=>u.jsx("option",{value:C.id,children:C.name},C.id))]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商API服务"}),u.jsxs("select",{value:A,onChange:C=>{const Q=C.target.value;_(Q),H("");const me=s.find(ye=>ye.id===Q);me&&(me.enableTokenLimit&&me.tokenLimit?(X(me.tokenLimit),I(me.tokenResetInterval),ge(me.tokenResetBaseTime?new Date(me.tokenResetBaseTime):void 0),Yt(me.tokenLimit),Bt(!0),Be(!0)):(Yt(void 0),Bt(!1),Be(!1)),me.enableRequestLimit&&me.requestCountLimit?(Y(me.requestCountLimit),ue(me.requestResetInterval),_e(me.requestResetBaseTime?new Date(me.requestResetBaseTime):void 0),ee(me.requestCountLimit),wt(!0),qe(!0)):(ee(void 0),wt(!1),qe(!1)))},required:!0,disabled:!T,children:[u.jsx("option",{value:"",disabled:!0,children:"请选择API服务"}),d.map(C=>u.jsx("option",{value:C.id,children:C.name},C.id))]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商模型"}),u.jsxs("select",{value:N,onChange:C=>H(C.target.value),disabled:!A,children:[u.jsx("option",{value:"",children:"透传模型名"}),(hb=(pb=s.find(C=>C.id===A))==null?void 0:pb.supportedModels)==null?void 0:hb.map(C=>u.jsx("option",{value:C,children:C},C))]})]}),u.jsx("div",{className:"form-group",children:u.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:xt?"not-allowed":"pointer"},children:[u.jsx("input",{type:"checkbox",checked:Se,onChange:C=>Be(C.target.checked),disabled:xt,style:{marginRight:"8px",cursor:xt?"not-allowed":"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用Tokens超量限制"}),xt&&u.jsx("small",{style:{color:"#999",fontSize:"12px",marginLeft:"8px"},children:"(从API服务继承)"})]}),xt&&u.jsx("button",{type:"button",className:"btn btn-sm btn-secondary",onClick:()=>Bt(!1),style:{padding:"4px 12px",fontSize:"12px"},children:"自定义限制"})]})}),Se&&!xt&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Tokens超量(单位:k)"}),u.jsx("input",{type:"number",value:P||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;if(Q!==void 0&&It!==void 0&&Q>It){te.warning(`Token超量值不能超过API服务的限制 (${It}k)`);return}X(Q),xt&&Q!==It&&Bt(!1)},min:"0",max:It,placeholder:It?`最大 ${It}k`:"不限制",disabled:xt}),It&&u.jsxs("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:["⚠️ API服务限制:最大 ",It,"k,当前值不能超过此限制"]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"当编程工具的请求tokens达到这个量时,在配置了其他规则的情况下,本条规则将失效,从而保护你的余额。例如:输入100表示100k即100,000个tokens"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Tokens超量自动重置间隔(小时)"}),u.jsx("input",{type:"number",value:Z||"",onChange:C=>{I(C.target.value?parseInt(C.target.value):void 0),xt&&Bt(!1)},min:"1",placeholder:"不自动重置",disabled:xt}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置后,系统将每隔指定小时数自动重置token计数。例如设置5小时,则每5小时重置一次"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Token下一次重置时间基点"}),u.jsx("input",{type:"datetime-local",value:ce?Iw(ce):"",onChange:C=>{C.target.value?ge(new Date(C.target.value)):ge(void 0),xt&&Bt(!1)},disabled:!Z||xt,className:"datetime-picker-input"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:'配合"Tokens超量自动重置间隔"使用,设置下一次重置的精确时间点。例如,每月1日0点重置(间隔720小时),或每周一0点重置(间隔168小时)。设置后,系统会基于此时间点自动计算后续重置周期'})]})]}),u.jsx("div",{className:"form-group",children:u.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:bt?"not-allowed":"pointer"},children:[u.jsx("input",{type:"checkbox",checked:Ne,onChange:C=>qe(C.target.checked),disabled:bt,style:{marginRight:"8px",cursor:bt?"not-allowed":"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用请求次数超量限制"}),bt&&u.jsx("small",{style:{color:"#999",fontSize:"12px",marginLeft:"8px"},children:"(从API服务继承)"})]}),bt&&u.jsx("button",{type:"button",className:"btn btn-sm btn-secondary",onClick:()=>wt(!1),style:{padding:"4px 12px",fontSize:"12px"},children:"自定义限制"})]})}),Ne&&!bt&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"请求次数超量"}),u.jsx("input",{type:"number",value:se||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;if(Q!==void 0&&W!==void 0&&Q>W){te.warning(`请求次数超量值不能超过API服务的限制 (${W})`);return}Y(Q),bt&&Q!==W&&wt(!1)},min:"0",max:W,placeholder:W?`最大 ${W}`:"不限制",disabled:bt}),W&&u.jsxs("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:["⚠️ API服务限制:最大 ",W,",当前值不能超过此限制"]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"当请求次数达到这个量时,在配置了其他规则的情况下,本条规则将失效"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"请求次数自动重置间隔(小时)"}),u.jsx("input",{type:"number",value:V||"",onChange:C=>{ue(C.target.value?parseInt(C.target.value):void 0),bt&&wt(!1)},min:"1",placeholder:"不自动重置",disabled:bt}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置后,系统将每隔指定小时数自动重置请求次数计数。例如设置24小时,则每24小时重置一次"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"下一次重置时间基点"}),u.jsx("input",{type:"datetime-local",value:q?Iw(q):"",onChange:C=>{C.target.value?_e(new Date(C.target.value)):_e(void 0),bt&&wt(!1)},disabled:!V||bt,className:"datetime-picker-input"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:'配合"请求次数自动重置间隔"使用,设置下一次重置的精确时间点。例如,每月1日0点重置(间隔720小时),或每周一0点重置(间隔168小时)。设置后,系统会基于此时间点自动计算后续重置周期'})]})]})]}),u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:"pointer"},children:[u.jsx("input",{type:"checkbox",checked:!!Ce,onChange:C=>{C.target.checked?(ve(10),Pe(0)):(ve(void 0),Pe(void 0))},style:{marginRight:"8px",cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用请求频率限制"})]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"启用后,当同一内容类型的请求频率超过限制时,系统会自动切换到其他同类型规则"})]}),Ce&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"频率限制次数(并发数)"}),u.jsx("input",{type:"number",value:Ce||"",onChange:C=>ve(C.target.value?parseInt(C.target.value):void 0),min:"1",placeholder:"例如: 10"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"在指定时间窗口内允许的最大请求次数"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"频率限制时间窗口(秒,0=同一时刻)"}),u.jsx("input",{type:"number",value:we===0?0:we||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;Pe(Q===0?0:Q)},min:"0",placeholder:"0 表示同一时刻"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"时间窗口大小。0 表示同一时刻(并发数),持续累积;设置为 60 则在 60 秒内最多允许 N 次请求"})]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"超时时间(秒)"}),u.jsx("input",{type:"number",value:K||"",onChange:C=>J(C.target.value?parseInt(C.target.value):void 0),min:"1",placeholder:"默认300秒"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置此规则的API请求超时时间。不设置则使用默认值300秒(5分钟)"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"排序(值越大优先级越高)"}),u.jsx("input",{type:"number",value:L,onChange:C=>U(parseInt(C.target.value)||0),min:"0",max:"1000"})]}),u.jsxs("div",{className:"modal-footer",children:[u.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>w(!1),children:"取消"}),u.jsx("button",{type:"submit",className:"btn btn-primary",children:"保存"})]})]})]})})]})]})}var GO={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(il,function(){var n=1e3,r=6e4,i=36e5,a="millisecond",o="second",l="minute",s="hour",c="day",d="week",f="month",p="quarter",h="year",g="date",y="Invalid Date",x=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,v=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,b={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(D){var O=["th","st","nd","rd"],L=D%100;return"["+D+(O[(L-20)%10]||O[L]||O[0])+"]"}},w=function(D,O,L){var U=String(D);return!U||U.length>=O?D:""+Array(O+1-U.length).join(L)+D},S={s:w,z:function(D){var O=-D.utcOffset(),L=Math.abs(O),U=Math.floor(L/60),R=L%60;return(O<=0?"+":"-")+w(U,2,"0")+":"+w(R,2,"0")},m:function D(O,L){if(O.date()<L.date())return-D(L,O);var U=12*(L.year()-O.year())+(L.month()-O.month()),R=O.clone().add(U,f),z=L-R<0,P=O.clone().add(U+(z?-1:1),f);return+(-(U+(L-R)/(z?R-P:P-R))||0)},a:function(D){return D<0?Math.ceil(D)||0:Math.floor(D)},p:function(D){return{M:f,y:h,w:d,d:c,D:g,h:s,m:l,s:o,ms:a,Q:p}[D]||String(D||"").toLowerCase().replace(/s$/,"")},u:function(D){return D===void 0}},k="en",j={};j[k]=b;var E="$isDayjsObject",T=function(D){return D instanceof N||!(!D||!D[E])},M=function D(O,L,U){var R;if(!O)return k;if(typeof O=="string"){var z=O.toLowerCase();j[z]&&(R=z),L&&(j[z]=L,R=z);var P=O.split("-");if(!R&&P.length>1)return D(P[0])}else{var X=O.name;j[X]=O,R=X}return!U&&R&&(k=R),R||!U&&k},A=function(D,O){if(T(D))return D.clone();var L=typeof O=="object"?O:{};return L.date=D,L.args=arguments,new N(L)},_=S;_.l=M,_.i=T,_.w=function(D,O){return A(D,{locale:O.$L,utc:O.$u,x:O.$x,$offset:O.$offset})};var N=function(){function D(L){this.$L=M(L.locale,null,!0),this.parse(L),this.$x=this.$x||L.x||{},this[E]=!0}var O=D.prototype;return O.parse=function(L){this.$d=function(U){var R=U.date,z=U.utc;if(R===null)return new Date(NaN);if(_.u(R))return new Date;if(R instanceof Date)return new Date(R);if(typeof R=="string"&&!/Z$/i.test(R)){var P=R.match(x);if(P){var X=P[2]-1||0,Z=(P[7]||"0").substring(0,3);return z?new Date(Date.UTC(P[1],X,P[3]||1,P[4]||0,P[5]||0,P[6]||0,Z)):new Date(P[1],X,P[3]||1,P[4]||0,P[5]||0,P[6]||0,Z)}}return new Date(R)}(L),this.init()},O.init=function(){var L=this.$d;this.$y=L.getFullYear(),this.$M=L.getMonth(),this.$D=L.getDate(),this.$W=L.getDay(),this.$H=L.getHours(),this.$m=L.getMinutes(),this.$s=L.getSeconds(),this.$ms=L.getMilliseconds()},O.$utils=function(){return _},O.isValid=function(){return this.$d.toString()!==y},O.isSame=function(L,U){var R=A(L);return this.startOf(U)<=R&&R<=this.endOf(U)},O.isAfter=function(L,U){return A(L)<this.startOf(U)},O.isBefore=function(L,U){return this.endOf(U)<A(L)},O.$g=function(L,U,R){return _.u(L)?this[U]:this.set(R,L)},O.unix=function(){return Math.floor(this.valueOf()/1e3)},O.valueOf=function(){return this.$d.getTime()},O.startOf=function(L,U){var R=this,z=!!_.u(U)||U,P=_.p(L),X=function(Y,V){var ue=_.w(R.$u?Date.UTC(R.$y,V,Y):new Date(R.$y,V,Y),R);return z?ue:ue.endOf(c)},Z=function(Y,V){return _.w(R.toDate()[Y].apply(R.toDate("s"),(z?[0,0,0,0]:[23,59,59,999]).slice(V)),R)},I=this.$W,ce=this.$M,ge=this.$D,K="set"+(this.$u?"UTC":"");switch(P){case h:return z?X(1,0):X(31,11);case f:return z?X(1,ce):X(0,ce+1);case d:var J=this.$locale().weekStart||0,se=(I<J?I+7:I)-J;return X(z?ge-se:ge+(6-se),ce);case c:case g:return Z(K+"Hours",0);case s:return Z(K+"Minutes",1);case l:return Z(K+"Seconds",2);case o:return Z(K+"Milliseconds",3);default:return this.clone()}},O.endOf=function(L){return this.startOf(L,!1)},O.$set=function(L,U){var R,z=_.p(L),P="set"+(this.$u?"UTC":""),X=(R={},R[c]=P+"Date",R[g]=P+"Date",R[f]=P+"Month",R[h]=P+"FullYear",R[s]=P+"Hours",R[l]=P+"Minutes",R[o]=P+"Seconds",R[a]=P+"Milliseconds",R)[z],Z=z===c?this.$D+(U-this.$W):U;if(z===f||z===h){var I=this.clone().set(g,1);I.$d[X](Z),I.init(),this.$d=I.set(g,Math.min(this.$D,I.daysInMonth())).$d}else X&&this.$d[X](Z);return this.init(),this},O.set=function(L,U){return this.clone().$set(L,U)},O.get=function(L){return this[_.p(L)]()},O.add=function(L,U){var R,z=this;L=Number(L);var P=_.p(U),X=function(ce){var ge=A(z);return _.w(ge.date(ge.date()+Math.round(ce*L)),z)};if(P===f)return this.set(f,this.$M+L);if(P===h)return this.set(h,this.$y+L);if(P===c)return X(1);if(P===d)return X(7);var Z=(R={},R[l]=r,R[s]=i,R[o]=n,R)[P]||1,I=this.$d.getTime()+L*Z;return _.w(I,this)},O.subtract=function(L,U){return this.add(-1*L,U)},O.format=function(L){var U=this,R=this.$locale();if(!this.isValid())return R.invalidDate||y;var z=L||"YYYY-MM-DDTHH:mm:ssZ",P=_.z(this),X=this.$H,Z=this.$m,I=this.$M,ce=R.weekdays,ge=R.months,K=R.meridiem,J=function(V,ue,q,_e){return V&&(V[ue]||V(U,z))||q[ue].slice(0,_e)},se=function(V){return _.s(X%12||12,V,"0")},Y=K||function(V,ue,q){var _e=V<12?"AM":"PM";return q?_e.toLowerCase():_e};return z.replace(v,function(V,ue){return ue||function(q){switch(q){case"YY":return String(U.$y).slice(-2);case"YYYY":return _.s(U.$y,4,"0");case"M":return I+1;case"MM":return _.s(I+1,2,"0");case"MMM":return J(R.monthsShort,I,ge,3);case"MMMM":return J(ge,I);case"D":return U.$D;case"DD":return _.s(U.$D,2,"0");case"d":return String(U.$W);case"dd":return J(R.weekdaysMin,U.$W,ce,2);case"ddd":return J(R.weekdaysShort,U.$W,ce,3);case"dddd":return ce[U.$W];case"H":return String(X);case"HH":return _.s(X,2,"0");case"h":return se(1);case"hh":return se(2);case"a":return Y(X,Z,!0);case"A":return Y(X,Z,!1);case"m":return String(Z);case"mm":return _.s(Z,2,"0");case"s":return String(U.$s);case"ss":return _.s(U.$s,2,"0");case"SSS":return _.s(U.$ms,3,"0");case"Z":return P}return null}(V)||P.replace(":","")})},O.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},O.diff=function(L,U,R){var z,P=this,X=_.p(U),Z=A(L),I=(Z.utcOffset()-this.utcOffset())*r,ce=this-Z,ge=function(){return _.m(P,Z)};switch(X){case h:z=ge()/12;break;case f:z=ge();break;case p:z=ge()/3;break;case d:z=(ce-I)/6048e5;break;case c:z=(ce-I)/864e5;break;case s:z=ce/i;break;case l:z=ce/r;break;case o:z=ce/n;break;default:z=ce}return R?z:_.a(z)},O.daysInMonth=function(){return this.endOf(f).$D},O.$locale=function(){return j[this.$L]},O.locale=function(L,U){if(!L)return this.$L;var R=this.clone(),z=M(L,U,!0);return z&&(R.$L=z),R},O.clone=function(){return _.w(this.$d,this)},O.toDate=function(){return new Date(this.valueOf())},O.toJSON=function(){return this.isValid()?this.toISOString():null},O.toISOString=function(){return this.$d.toISOString()},O.toString=function(){return this.$d.toUTCString()},D}(),H=N.prototype;return A.prototype=H,[["$ms",a],["$s",o],["$m",l],["$H",s],["$W",c],["$M",f],["$y",h],["$D",g]].forEach(function(D){H[D[1]]=function(O){return this.$g(O,D[0],D[1])}}),A.extend=function(D,O){return D.$i||(D(O,N,A),D.$i=!0),A},A.locale=M,A.isDayjs=T,A.unix=function(D){return A(1e3*D)},A.en=j[k],A.Ls=j,A.p={},A})})(GO);var qB=GO.exports;const ln=fr(qB);var XO={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(il,function(){return function(n,r,i){n=n||{};var a=r.prototype,o={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function l(c,d,f,p){return a.fromToBase(c,d,f,p)}i.en.relativeTime=o,a.fromToBase=function(c,d,f,p,h){for(var g,y,x,v=f.$locale().relativeTime||o,b=n.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],w=b.length,S=0;S<w;S+=1){var k=b[S];k.d&&(g=p?i(c).diff(f,k.d,!0):f.diff(c,k.d,!0));var j=(n.rounding||Math.round)(Math.abs(g));if(x=g>0,j<=k.r||!k.r){j<=1&&S>0&&(k=b[S-1]);var E=v[k.l];h&&(j=h(""+j)),y=typeof E=="string"?E.replace("%d",j):E(j,d,k.l,x);break}}if(d)return y;var T=x?v.future:v.past;return typeof T=="function"?T(y):T.replace("%s",y)},a.to=function(c,d){return l(c,d,this,!0)},a.from=function(c,d){return l(c,d,this)};var s=function(c){return c.$u?i.utc():i()};a.toNow=function(c){return this.to(s(this),c)},a.fromNow=function(c){return this.from(s(this),c)}}})})(XO);var YB=XO.exports;const GB=fr(YB),XB=["authorization","x-api-key","api-key","apikey","x-auth-token","auth-token","secret","password","api_secret","jwt","csrf_token","xsrf_token","auth_token","session_token","private_key","client_secret"],QB=e=>{const t=e.toLowerCase();return!!(XB.some(n=>t===n)||t.startsWith("api_")&&(t.endsWith("_key")||t.endsWith("_secret"))||(t.endsWith("_token")||t.endsWith("_key")||t.endsWith("_secret"))&&!["max_tokens","input_tokens","output_tokens","completion_tokens","prompt_tokens","cachereadinputtokens","totaltokens"].some(r=>t.replace(/_/g,"").includes(r.replace(/_/g,""))))},ZB=e=>!e||e.length<=8?"***":`${e.slice(0,4)}${"*".repeat(Math.min(e.length-8,20))}${e.slice(-4)}`,Bg=e=>{if(e==null)return e;if(Array.isArray(e))return e.map(t=>Bg(t));if(typeof e=="object"){const t={};for(const[n,r]of Object.entries(e))QB(n)?t[n]=typeof r=="string"?ZB(r):"***":typeof r=="object"?t[n]=Bg(r):t[n]=r;return t}return e},gr=({data:e,title:t,collapsed:n=!1})=>{const[r,i]=m.useState(!n),[a,o]=m.useState(!1),l=d=>{try{let f;typeof d=="string"?f=JSON.parse(d):f=d;const p=Bg(f);return JSON.stringify(p,null,2)}catch{return typeof d=="string"?d:String(d)}},s=()=>{const d=l(e);navigator.clipboard.writeText(d).then(()=>{o(!0),setTimeout(()=>o(!1),2e3)}).catch(f=>{console.error("Failed to copy JSON:",f)})},c=l(e);return u.jsxs("div",{className:"json-viewer",children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"},children:[t&&u.jsx("h4",{style:{margin:0,fontSize:"14px",color:"var(--text-primary)"},children:t}),u.jsxs("div",{style:{display:"flex",gap:"8px"},children:[u.jsx("button",{onClick:()=>i(!r),className:"btn btn-sm btn-secondary",style:{fontSize:"12px",padding:"2px 8px"},children:r?"折叠":"展开"}),u.jsx("button",{onClick:s,className:"btn btn-sm btn-primary",style:{fontSize:"12px",padding:"2px 8px"},children:a?"已复制":"复制"})]})]}),r&&u.jsx("pre",{style:{background:"var(--bg-code)",border:"1px solid var(--border-primary)",borderRadius:"8px",padding:"12px",overflowX:"auto",fontSize:"12px",lineHeight:"1.4",color:"var(--text-primary)",maxHeight:"400px",overflowY:"auto",margin:0},children:u.jsx("code",{children:c})})]})},im=({currentPage:e,totalItems:t,pageSize:n,onPageChange:r,onPageSizeChange:i,pageSizeOptions:a=[10,20,50,100]})=>{const o=Math.max(1,Math.ceil(t/n)),l=e===1,s=e>=o,c=()=>{l||r(1)},d=()=>{l||r(e-1)},f=()=>{s||r(e+1)},p=()=>{s||r(o)},h=g=>{const y=parseInt(g.target.value,10);i(y)};return u.jsxs("div",{className:"pagination",children:[u.jsxs("div",{className:"pagination-info",children:["共 ",t," 条"]}),u.jsxs("div",{className:"pagination-controls",children:[u.jsx("button",{className:"pagination-btn",onClick:c,disabled:l,children:"首页"}),u.jsx("button",{className:"pagination-btn",onClick:d,disabled:l,children:"上一页"}),u.jsxs("span",{className:"pagination-info",children:["第 ",e," / ",o," 页"]}),u.jsx("button",{className:"pagination-btn",onClick:f,disabled:s,children:"下一页"}),u.jsx("button",{className:"pagination-btn",onClick:p,disabled:s,children:"尾页"})]}),u.jsx("div",{className:"pagination-size",children:u.jsxs("label",{children:["每页显示",u.jsx("select",{className:"pagination-select",value:n,onChange:h,children:a.map(g=>u.jsx("option",{value:g,children:g},g))}),"条"]})})]})};ln.extend(GB);function JB(e){const t=[];let n={dataLines:[],rawLines:[]};for(const r of e){const i=r.split(`
|
|
122
|
+
请刷新页面后重试。`)}}catch(ye){console.error("停用路由失败:",ye),te.error(ye.message)}finally{ka(null)}},Y2=async C=>{C.preventDefault();const Q=new FormData(C.currentTarget),me={name:Q.get("name"),description:Q.get("description"),targetType:Q.get("targetType"),isActive:!1};S?await G.updateRoute(S.id,me):await G.createRoute(me),v(!1),_r()},G2=async C=>{await e({message:"确定要删除此路由吗?",title:"确认删除",type:"danger",confirmText:"删除",cancelText:"取消"})&&(await G.deleteRoute(C),_r(),g&&g.id===C&&(y(null),a([])),te.success("路由已删除"))},X2=async C=>{if(C.preventDefault(),R==="image-understanding"&&be&&!le){te.warning("请选择一个MCP工具");return}if(!be&&!A){te.warning("请选择供应商API服务");return}if(!be&&P!==void 0&&It!==void 0&&P>It){te.warning(`Token超量值 (${P}k) 不能超过API服务的限制 (${It}k)`);return}if(!be&&se!==void 0&&W!==void 0&&se>W){te.warning(`请求次数超量值 (${se}) 不能超过API服务的限制 (${W})`);return}const Q=new FormData(C.currentTarget),me={routeId:g.id,contentType:Q.get("contentType"),targetServiceId:be?"":A,targetModel:be?void 0:N||void 0,replacedModel:D||void 0,sortOrder:L,timeout:K?K*1e3:void 0,tokenLimit:be?void 0:P||void 0,resetInterval:be?void 0:Z,tokenResetBaseTime:be?void 0:ce?ce.getTime():void 0,requestCountLimit:be?void 0:se,requestResetInterval:be?void 0:V,requestResetBaseTime:be?void 0:q?q.getTime():void 0,frequencyLimit:Ce,frequencyWindow:we,useMCP:R==="image-understanding"?be:!1,mcpId:R==="image-understanding"&&be?le:void 0};j?await G.updateRule(j.id,me):await G.createRule(me),w(!1),g&&Ee(g.id)},Q2=async C=>{await e({message:"确定要删除此路由吗?",title:"确认删除",type:"danger",confirmText:"删除",cancelText:"取消"})&&(await G.deleteRule(C),g&&Ee(g.id),te.success("规则已删除"))},Z2=async C=>{try{await G.clearRuleBlacklist(C),g&&Ee(g.id),te.success("已恢复")}catch(Q){te.error("恢复失败: "+Q.message)}},J2=async C=>{try{const Q=await G.toggleRuleDisable(C);g&&Ee(g.id),te.success(Q.isDisabled?"规则已屏蔽":"规则已启用")}catch(Q){te.error("操作失败: "+Q.message)}},eM=async C=>{try{const Q=i.find(ye=>ye.id===C);if(!Q)return;const me=(Q.sortOrder||0)+1;await G.updateRule(C,{sortOrder:me}),g&&Ee(g.id),te.success("优先级已提升")}catch(Q){te.error("操作失败: "+Q.message)}},tM=async C=>{try{const Q=i.find(ye=>ye.id===C);if(!Q)return;const me=Math.max(0,(Q.sortOrder||0)-1);await G.updateRule(C,{sortOrder:me}),g&&Ee(g.id),te.success("优先级已降低")}catch(Q){te.error("操作失败: "+Q.message)}},nM=async C=>{if(g){if(C&&!B()){te.error("当前 Claude Code 版本不支持 Agent Teams 功能,需要版本 ≥ 2.1.32");return}try{g.isActive?(await G.updateClaudeAgentTeams(C),await G.updateRoute(g.id,{enableAgentTeams:C}),te.success(C?"Agent Teams 功能已开启":"Agent Teams 功能已关闭")):(await G.updateRoute(g.id,{enableAgentTeams:C}),te.success(C?"Agent Teams 设置已保存(将在激活时生效)":"Agent Teams 设置已取消")),y({...g,enableAgentTeams:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}}},rM=async C=>{if(g)try{g.isActive?(await G.updateClaudeBypassPermissionsSupport(C),await G.updateRoute(g.id,{enableBypassPermissionsSupport:C}),te.success(C?"对bypassPermissions的支持已开启":"对bypassPermissions的支持已关闭")):(await G.updateRoute(g.id,{enableBypassPermissionsSupport:C}),te.success(C?"对bypassPermissions的支持设置已保存(将在激活时生效)":"对bypassPermissions的支持设置已取消")),y({...g,enableBypassPermissionsSupport:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}},iM=async C=>{if(!(!g||g.targetType!=="codex"))try{if(Gt(!0),g.isActive){if(!await G.updateCodexReasoningEffort(C))throw new Error("Codex 配置文件未处于代理状态,请先重新激活路由");await G.updateRoute(g.id,{codexModelReasoningEffort:C}),te.success("Reasoning Effort 已更新,Codex 配置已立即生效")}else await G.updateRoute(g.id,{codexModelReasoningEffort:C}),te.success("Reasoning Effort 设置已保存(将在激活时生效)");y({...g,codexModelReasoningEffort:C}),await _r()}catch(Q){te.error("更新失败: "+Q.message)}finally{Gt(!1)}},aM=()=>Ew,oM=C=>{E(C),z(C.contentType),F(C.useMCP||!1),oe(C.mcpId||"");const Q=s.find(me=>me.id===C.targetServiceId);Q?(Q.vendorId&&(M(Q.vendorId),f(s.filter(me=>me.vendorId===Q.vendorId))),setTimeout(()=>{if(_(Q.id),H(C.targetModel||""),O(C.replacedModel||""),U(C.sortOrder||0),J(C.timeout?C.timeout/1e3:void 0),X(C.tokenLimit||void 0),I(C.resetInterval),ge(C.tokenResetBaseTime?new Date(C.tokenResetBaseTime):void 0),Y(C.requestCountLimit),ue(C.requestResetInterval),_e(C.requestResetBaseTime?new Date(C.requestResetBaseTime):void 0),ve(C.frequencyLimit),Pe(C.frequencyWindow),Q.enableTokenLimit&&Q.tokenLimit){Yt(Q.tokenLimit);const me=C.tokenLimit===Q.tokenLimit&&C.resetInterval===(Q.tokenResetInterval||void 0)&&C.tokenLimit!==null&&C.resetInterval!==null;Bt(me)}else Yt(void 0),Bt(!1);if(Q.enableRequestLimit&&Q.requestCountLimit){ee(Q.requestCountLimit);const me=C.requestCountLimit===Q.requestCountLimit&&C.requestResetInterval===(Q.requestResetInterval||void 0)&&C.requestCountLimit!==null&&C.requestResetInterval!==null;wt(me)}else ee(void 0),wt(!1);Be(!!C.tokenLimit),qe(!!C.requestCountLimit)},0)):C.useMCP&&(M(""),_(""),H(""),O(""),U(C.sortOrder||0),J(C.timeout?C.timeout/1e3:void 0),Be(!1),qe(!1)),w(!0)},lM=C=>{var Ll;const Q=xe[C.id],me=[],ye=t[C.id];if((ye==null?void 0:ye.status)==="in_use")return{status:"in_use",label:"使用中",reason:"正在处理请求"};if(Q!=null&&Q.isBlacklisted){const je=Q.blacklistEntry;(je==null?void 0:je.errorType)==="timeout"?me.push("请求超时"):je!=null&&je.lastStatusCode&&me.push(`HTTP ${je.lastStatusCode}错误`)}const pt=(ye==null?void 0:ye.totalTokensUsed)!==void 0?ye.totalTokensUsed:C.totalTokensUsed;C.tokenLimit&&pt!==void 0&&pt>=C.tokenLimit*1e3&&me.push("Token超限");const Le=(ye==null?void 0:ye.totalRequestsUsed)!==void 0?ye.totalRequestsUsed:C.totalRequestsUsed;if(C.requestCountLimit&&Le!==void 0&&Le>=C.requestCountLimit&&me.push("次数超限"),me.length>0)return{status:"error",label:Q!=null&&Q.isBlacklisted?((Ll=Q.blacklistEntry)==null?void 0:Ll.errorType)==="timeout"?"超时":"服务错误":me[0],reason:me.join(", ")};const Xt=[];if(C.tokenLimit&&pt!==void 0){const je=pt/(C.tokenLimit*1e3)*100;je>=80&&Xt.push(`Token ${je.toFixed(0)}%`)}if(C.requestCountLimit&&Le!==void 0){const je=Le/C.requestCountLimit*100;je>=80&&Xt.push(`次数 ${je.toFixed(0)}%`)}return Xt.length>0?{status:"warning",label:"接近限制",reason:Xt.join(", ")}:{status:"success",label:"正常",reason:""}},sM=()=>{E(null),z("default"),M(""),_(""),H(""),O(""),U(0),J(void 0),X(void 0),I(void 0),ge(void 0),Y(void 0),ue(void 0),_e(void 0),Bt(!1),wt(!1),Yt(void 0),ee(void 0),Be(!1),qe(!1),F(!1),oe(""),w(!0)};return u.jsxs("div",{className:"routes-page",children:[u.jsxs("div",{className:"page-header",children:[u.jsx("h1",{children:"路由管理"}),u.jsx("p",{children:"管理API路由和路由配置"})]}),u.jsx("div",{style:{display:"flex",flexDirection:"column"},children:u.jsxs("div",{style:{display:"flex",gap:"20px"},children:[u.jsxs("div",{className:"card",style:{flex:"0 0 25%",minWidth:300},children:[u.jsxs("div",{className:"toolbar",children:[u.jsx("h3",{children:"路由"}),u.jsx("button",{className:"btn btn-primary",onClick:()=>v(!0),children:"新建"})]}),n.length===0?u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"暂无路由"})}):u.jsx("div",{style:{marginTop:"10px"},children:n.map(C=>{var Q,me;return u.jsx("div",{ref:ye=>{ye?Qn.current.set(C.id,ye):Qn.current.delete(C.id)},onClick:()=>y(C),style:{padding:"12px",marginBottom:"8px",backgroundColor:g&&g.id===C.id?"var(--bg-route-item-selected)":"var(--bg-route-item)",borderRadius:"8px",cursor:"pointer",border:"1px solid var(--border-primary)",position:"relative"},children:u.jsxs("div",{children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[u.jsx("div",{style:{fontWeight:500},children:C.name}),C.isActive&&u.jsxs("span",{className:`badge ${C.targetType==="claude-code"?"badge-claude-code":"badge-codex"}`,style:{position:"absolute",top:-16,right:-8},children:[(Q=rm.find(ye=>ye.value===C.targetType))==null?void 0:Q.label," 已激活"]})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-route-muted)",marginTop:"2px"},children:["客户端工具: ",(me=rm.find(ye=>ye.value===C.targetType))==null?void 0:me.label]}),u.jsxs("div",{className:"action-buttons",style:{marginTop:"8px"},children:[C.isActive?u.jsx("button",{className:"btn btn-warning",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),q2(C.id)},disabled:Xn!==null,children:Xn===C.id?"处理中...":"停用"}):u.jsx("button",{className:"btn btn-success",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),V2(C.id)},disabled:Xn!==null,children:Xn===C.id?"处理中...":"激活"}),u.jsx("button",{className:"btn btn-secondary",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),k(C),v(!0)},children:"编辑"}),u.jsx("button",{className:"btn btn-danger",style:{padding:"4px 8px",fontSize:"12px"},onClick:ye=>{ye.stopPropagation(),G2(C.id)},disabled:C.isActive,children:"删除"})]})]})},C.id)})})]}),u.jsxs("div",{style:{flex:1,display:"flex",flexDirection:"column"},children:[u.jsxs("div",{className:"card",style:{flex:1},children:[u.jsxs("div",{className:"toolbar",children:[u.jsx("h3",{children:"规则列表"}),g&&u.jsx("button",{className:"btn btn-primary",onClick:sM,children:"新建规则"})]}),g?i.length===0?u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"暂无路由"})}):u.jsxs("table",{className:"rules-table",children:[u.jsx("thead",{children:u.jsxs("tr",{children:[u.jsx("th",{className:"col-priority",children:"优先级"}),u.jsx("th",{children:"类型"}),u.jsx("th",{children:"API服务"}),u.jsx("th",{children:"状态"}),u.jsx("th",{children:"用量情况"}),u.jsx("th",{children:"操作"})]})}),u.jsx("tbody",{children:[...i].sort((C,Q)=>{const me=C.sortOrder||0,ye=Q.sortOrder||0;if(me!==ye)return ye-me;const pt=Ow[C.contentType]??999,Le=Ow[Q.contentType]??999;return pt-Le}).map(C=>{var pt,Le,Xt,Ll;const Q=s.find(je=>je.id===C.targetServiceId),me=o.find(je=>je.id===(Q==null?void 0:Q.vendorId)),ye=(pt=Ew.find(je=>je.value===C.contentType))==null?void 0:pt.label;return u.jsxs("tr",{children:[u.jsx("td",{className:"col-priority",children:u.jsxs("div",{className:"col-priority-box",children:[u.jsx("span",{children:C.sortOrder||0}),u.jsx("button",{className:"priority-arrow-btn",onClick:()=>tM(C.id),title:"降低优先级",children:"↓"}),u.jsx("button",{className:"priority-arrow-btn",onClick:()=>eM(C.id),title:"提升优先级",children:"↑"})]})}),u.jsx("td",{children:u.jsxs("div",{style:{fontSize:"12px",whiteSpace:"nowrap"},children:[C.contentType!=="default"&&Aw[C.contentType]&&u.jsx("span",{style:{fontSize:"14px"},children:Aw[C.contentType]}),u.jsx("span",{children:ye}),C.contentType==="model-mapping"&&C.replacedModel&&u.jsxs("div",{style:{position:"relative",display:"inline-block"},onMouseEnter:()=>Pt(C.id),onMouseLeave:()=>Pt(null),children:[u.jsx("span",{style:{cursor:"help",fontSize:"14px",color:"var(--text-info)",fontWeight:"bold"},children:"ⓘ"}),Dn===C.id&&u.jsxs("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"calc(100% + 8px)",backgroundColor:"var(--bg-popover, #333)",color:"var(--text-popover, #fff)",padding:"6px 10px",borderRadius:"4px",fontSize:"12px",whiteSpace:"nowrap",zIndex:1e3,boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},children:["被顶替的模型是: ",C.replacedModel,u.jsx("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"-4px",width:"0",height:"0",borderLeft:"4px solid transparent",borderRight:"4px solid transparent",borderTop:"4px solid var(--bg-popover, #333)"}})]})]})]})}),u.jsx("td",{children:u.jsx("div",{className:"vendor-sevices-col",style:{fontSize:"0.6em"},children:C.useMCP?u.jsxs(u.Fragment,{children:[u.jsxs("div",{children:["MCP:",((Le=p.find(je=>je.id===C.mcpId))==null?void 0:Le.name)||"Unknown"]}),u.jsx("div",{style:{fontSize:"11px",color:"var(--text-muted)"},children:"使用MCP工具"})]}):u.jsxs(u.Fragment,{children:[u.jsxs("div",{children:["供应商:",me?me.name:"Unknown"]}),u.jsxs("div",{children:["服务:",Q?Q.name:"Unknown"]}),u.jsxs("div",{children:["模型:",C.targetModel||"透传模型"]})]})})}),u.jsx("td",{style:{whiteSpace:"nowrap"},children:(()=>{var mb,gb;const je=lM(C),mn=xe[C.id],uM=(mn==null?void 0:mn.isBlacklisted)&&!((mb=je.reason)!=null&&mb.includes("Token超限"))&&!((gb=je.reason)!=null&&gb.includes("次数超限"));return C.isDisabled?u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px"},children:[u.jsx("span",{style:{color:"#6c757d",fontWeight:"bold",fontSize:"14px"},children:"⊘"}),u.jsx("span",{style:{fontSize:"13px",color:"#6c757d",fontWeight:"bold"},children:"已屏蔽"})]}):u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",flexWrap:"wrap"},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px"},children:[je.status==="success"&&u.jsx("span",{style:{color:"#28a745",fontWeight:"bold",fontSize:"14px"},children:"✓"}),je.status==="warning"&&u.jsx("span",{style:{color:"#ffc107",fontWeight:"bold",fontSize:"14px"},children:"⚠"}),je.status==="error"&&u.jsx("span",{style:{color:"#dc3545",fontWeight:"bold",fontSize:"14px"},children:"✗"}),je.status==="in_use"&&u.jsx(u.Fragment,{children:u.jsx("span",{style:{color:"#007bff",fontWeight:"bold",fontSize:"14px",animation:"pulse 1.5s ease-in-out infinite"},children:"●"})}),u.jsx("span",{style:{fontSize:"13px",color:je.status==="success"?"#28a745":je.status==="warning"?"#ffc107":je.status==="in_use"?"#007bff":"#dc3545",fontWeight:je.status!=="success"?"bold":"normal"},children:je.label}),je.reason&&u.jsxs("div",{style:{position:"relative",display:"inline-block",cursor:"help"},onMouseEnter:()=>Pt(C.id+"-status"),onMouseLeave:()=>Pt(null),children:[u.jsx("span",{style:{fontSize:"12px",color:"#999",marginLeft:"4px"},children:" ⓘ"}),Dn===C.id+"-status"&&u.jsxs("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"calc(100% + 8px)",backgroundColor:"var(--bg-popover, #333)",color:"var(--text-popover, #fff)",padding:"6px 10px",borderRadius:"4px",fontSize:"12px",whiteSpace:"nowrap",zIndex:1e3,boxShadow:"0 2px 8px rgba(0,0,0,0.15)"},children:[je.reason,u.jsx("div",{style:{position:"absolute",left:"50%",transform:"translateX(-50%)",bottom:"-4px",width:"0",height:"0",borderLeft:"4px solid transparent",borderRight:"4px solid transparent",borderTop:"4px solid var(--bg-popover, #333)"}})]})]})]}),uM&&u.jsx("button",{className:"btn btn-info",style:{padding:"2px 8px",fontSize:"11px"},onClick:()=>Z2(C.id),children:"恢复"})]})})()}),u.jsx("td",{children:C.tokenLimit||C.requestCountLimit?u.jsxs("div",{style:{fontSize:"13px"},children:[C.tokenLimit&&u.jsxs("div",{style:{whiteSpace:"nowrap"},children:[u.jsx("span",{style:{fontWeight:"bold",fontSize:"12px"},children:"Tokens:"}),u.jsxs(u.Fragment,{children:[u.jsxs("span",{style:{color:(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalTokensUsed)??C.totalTokensUsed;return je&&C.tokenLimit&&je>=C.tokenLimit*1e3?"red":"inherit"})()},children:[(((((Xt=t[C.id])==null?void 0:Xt.totalTokensUsed)??C.totalTokensUsed)||0)/1e3).toFixed(1),"K/",C.tokenLimit.toFixed(0),"K"]}),(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalTokensUsed)??C.totalTokensUsed;return je&&C.tokenLimit&&je>=C.tokenLimit*1e3?u.jsx("span",{style:{color:"red",marginLeft:"4px",fontWeight:"bold",fontSize:"11px"},children:"超限"}):null})()]})]}),C.requestCountLimit&&u.jsxs("div",{style:{marginTop:C.tokenLimit?"6px":0},children:[u.jsx("span",{style:{fontWeight:"bold",fontSize:"12px"},children:"次数:"}),u.jsxs(u.Fragment,{children:[u.jsxs("span",{style:{color:(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalRequestsUsed)??C.totalRequestsUsed;return je&&C.requestCountLimit&&je>=C.requestCountLimit?"red":"inherit"})()},children:[(((Ll=t[C.id])==null?void 0:Ll.totalRequestsUsed)??C.totalTokensUsed)||0,"/",C.requestCountLimit]}),(()=>{var mn;const je=((mn=t[C.id])==null?void 0:mn.totalRequestsUsed)??C.totalRequestsUsed;return je&&C.requestCountLimit&&je>=C.requestCountLimit?u.jsx("span",{style:{color:"red",marginLeft:"4px",fontWeight:"bold",fontSize:"11px"},children:"超限"}):null})()]})]})]}):u.jsx("span",{style:{color:"#999",fontSize:"12px"},children:"不限制"})}),u.jsx("td",{children:u.jsxs("div",{className:"action-buttons",style:{justifyContent:"flex-end"},children:[u.jsx("button",{className:`btn ${C.isDisabled?"btn-success":"btn-warning"}`,onClick:()=>J2(C.id),title:C.isDisabled?"启用规则":"临时屏蔽规则",children:C.isDisabled?"启用":"屏蔽"}),u.jsx("button",{className:"btn btn-secondary",onClick:()=>oM(C),children:"编辑"}),u.jsx("button",{className:"btn btn-danger",onClick:()=>Q2(C.id),children:"删除"})]})})]},C.id)})})]}):u.jsx("div",{className:"empty-state",children:u.jsx("p",{children:"请先选择一个路由"})}),g&&i.length>0&&u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-info-box)",marginTop:"16px",padding:"12px",backgroundColor:"var(--bg-info-box)",borderRadius:"6px",border:"1px solid var(--border-info-box)",lineHeight:"1.6"},children:[u.jsx("strong",{children:"💡 智能故障切换机制"}),u.jsxs("div",{style:{marginTop:"6px"},children:["• 当同一请求类型配置多个规则时,系统会按排序优先使用第一个",u.jsx("br",{}),"• 如果某个服务报错(4xx/5xx)或请求超时,将自动切换到下一个可用服务",u.jsx("br",{}),"• 报错或超时的服务会被标记为不可用,有效期10分钟",u.jsx("br",{}),"• 10分钟后自动解除标记,如果再次报错或超时则重新标记",u.jsx("br",{}),"• 确保您的请求始终路由到稳定可用的服务",u.jsx("br",{}),"• 规则状态列会实时显示每个规则的可用性状态",u.jsx("br",{}),"• 如不需要此功能,可在",u.jsx("strong",{children:"设置"}),'页面关闭"启用智能故障切换"选项']})]})]}),g&&g.targetType==="claude-code"&&u.jsxs("div",{className:"card",children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"Claude Code 配置"})}),u.jsxs("div",{style:{padding:"20px"},children:[!B()&&((fb=Me==null?void 0:Me.claudeCode)==null?void 0:fb.version)&&u.jsxs("div",{style:{backgroundColor:"var(--bg-warning, #fff3cd)",border:"1px solid var(--border-warning, #ffc107)",borderRadius:"6px",padding:"12px",marginBottom:"12px",fontSize:"13px",color:"var(--text-warning, #856404)"},children:["⚠️ 当前 Claude Code 版本 (",Me.claudeCode.version,") 不支持 Agent Teams 功能。",u.jsx("br",{}),"Agent Teams 功能需要 Claude Code 版本 ≥ 2.1.32。请升级 Claude Code 后再使用此功能。"]}),u.jsxs("div",{style:{marginBottom:"20px"},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("input",{type:"checkbox",id:"agent-teams-toggle",checked:g.enableAgentTeams||!1,onChange:C=>nM(C.target.checked),disabled:!B(),style:{cursor:B()?"pointer":"not-allowed",width:"16px",height:"16px"}}),u.jsx("label",{htmlFor:"agent-teams-toggle",style:{cursor:B()?"pointer":"not-allowed",fontSize:"14px",userSelect:"none",color:B()?"inherit":"var(--text-muted)"},children:"开启 Agent Teams 功能"})]}),u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:B()?g.isActive?"开启后将启用 Agent Teams 实验性功能,可在重启claude code后立即生效。":"开启后将在激活此路由时启用 Agent Teams 实验性功能。":"Agent Teams 功能需要 Claude Code 版本 ≥ 2.1.32。请升级 Claude Code 后再使用此功能。"})]}),u.jsxs("div",{children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("input",{type:"checkbox",id:"bypass-permissions-support-toggle",checked:g.enableBypassPermissionsSupport||!1,onChange:C=>rM(C.target.checked),style:{cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("label",{htmlFor:"bypass-permissions-support-toggle",style:{cursor:"pointer",fontSize:"14px",userSelect:"none"},children:"开启对 bypassPermissions 的支持"})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:["开启后默认编辑跳过危险模式权限提示,你可以切换到其他模式",g.isActive?"。开启后立即写入配置文件,可在重启claude code后立即生效。":"。开启后将在激活此路由时写入配置文件。"]})]})]})]}),g&&g.targetType==="codex"&&u.jsxs("div",{className:"card",children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"Codex 配置"})}),u.jsxs("div",{style:{padding:"20px"},children:[u.jsxs("div",{className:"form-group",style:{marginBottom:"0",maxWidth:"420px",display:"flex",alignItems:"center",gap:"12px"},children:[u.jsx("label",{htmlFor:"codex-reasoning-effort",style:{marginBottom:0,minWidth:"120px",whiteSpace:"nowrap"},children:"Reasoning Effort"}),u.jsx("select",{id:"codex-reasoning-effort",value:Tw(g),onChange:C=>iM(C.target.value),disabled:Rl,style:{flex:1,minWidth:0},children:YO.map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"12px"},children:g.isActive?"修改后会立即覆盖写入 ~/.codex/config.toml 的 model_reasoning_effort。":"该设置会在激活此路由时写入 ~/.codex/config.toml。"})]})]})]})]})}),u.jsxs("div",{className:"card",style:{marginTop:"20px"},children:[u.jsx("div",{className:"toolbar",children:u.jsx("h3",{children:"📝 配置文件自动管理"})}),u.jsxs("div",{style:{padding:"20px",lineHeight:"1.8"},children:[u.jsxs("div",{style:{background:"var(--bg-info-blue)",padding:"15px",borderRadius:"8px",marginBottom:"15px",borderLeft:"4px solid var(--border-info-blue)"},children:[u.jsx("strong",{children:"💡 工作原理"}),u.jsx("p",{style:{marginTop:"8px",marginBottom:"0"},children:"激活路由时,系统会自动修改编程工具的配置文件,使其通过本代理服务器访问AI服务。 停用路由时,系统会自动恢复原始配置。"})]}),u.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"15px"},children:[u.jsxs("div",{style:{background:"var(--bg-info-green)",padding:"15px",borderRadius:"8px",borderLeft:"4px solid var(--border-info-green)"},children:[u.jsx("strong",{children:"✓ 激活路由"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsx("li",{children:"首次激活:自动备份并覆盖配置文件"}),u.jsx("li",{children:"再次激活:仅切换路由,不重复覆盖"})]})]}),u.jsxs("div",{style:{background:"var(--bg-info-orange)",padding:"15px",borderRadius:"8px",borderLeft:"4px solid var(--border-info-orange)"},children:[u.jsx("strong",{children:"○ 停用路由"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsx("li",{children:"自动恢复原始配置文件"}),u.jsx("li",{children:"删除备份文件"})]})]})]}),u.jsxs("div",{style:{marginTop:"15px",padding:"12px 15px",background:"var(--bg-info-yellow)",borderRadius:"8px",borderLeft:"4px solid var(--border-info-yellow)"},children:[u.jsx("strong",{children:"⚠️ 重要提示"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",marginBottom:"0"},children:[u.jsxs("li",{children:["激活(首次)/停用路由后,",u.jsx("strong",{children:"必须重启对应的编程工具"}),"才能使配置生效"]}),u.jsx("li",{children:"操作前建议关闭编程工具,避免配置冲突"})]})]}),u.jsxs("details",{style:{marginTop:"15px",cursor:"pointer"},children:[u.jsx("summary",{style:{fontWeight:"bold",color:"#666"},children:"📂 配置文件位置(点击展开)"}),u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",color:"#666"},children:[u.jsxs("li",{children:[u.jsx("strong",{children:"Claude Code:"})," ~/.claude/settings.json, ~/.claude.json"]}),u.jsxs("li",{children:[u.jsx("strong",{children:"Codex:"})," ~/.codex/config.toml, ~/.codex/auth.json"]})]})]})]})]}),x&&u.jsxs("div",{className:"modal-overlay",children:[u.jsx("button",{type:"button",className:"modal-close-btn",onClick:()=>v(!1),"aria-label":"关闭",children:"×"}),u.jsx("div",{className:"modal",children:u.jsxs("div",{className:"modal-container",children:[u.jsx("div",{className:"modal-header",children:u.jsx("h2",{children:S?"编辑路由":"新建路由"})}),u.jsxs("form",{onSubmit:Y2,children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"路由名称"}),u.jsx("input",{type:"text",name:"name",defaultValue:S?S.name:"",required:!0})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"描述"}),u.jsx("textarea",{name:"description",rows:3,defaultValue:S?S.description:""})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"客户端工具"}),u.jsx("select",{name:"targetType",defaultValue:S?S.targetType:"claude-code",required:!0,children:rm.map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),u.jsxs("div",{className:"modal-footer",children:[u.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>v(!1),children:"取消"}),u.jsx("button",{type:"submit",className:"btn btn-primary",children:"保存"})]})]})]})})]}),b&&u.jsxs("div",{className:"modal-overlay",children:[u.jsx("button",{type:"button",className:"modal-close-btn",onClick:()=>w(!1),"aria-label":"关闭",children:"×"}),u.jsx("div",{className:"modal",children:u.jsxs("div",{className:"modal-container",children:[u.jsx("div",{className:"modal-header",children:u.jsx("h2",{children:j?"编辑规则":"新建规则"})}),u.jsxs("form",{onSubmit:X2,children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"对象请求类型"}),u.jsx("select",{name:"contentType",value:R,required:!0,onChange:C=>{z(C.target.value)},children:aM().map(C=>u.jsx("option",{value:C.value,children:C.label},C.value))})]}),R==="high-iq"&&u.jsxs("div",{style:{background:"var(--bg-info-blue)",padding:"12px",borderRadius:"6px",borderLeft:"4px solid var(--border-info-blue)",marginBottom:"16px"},children:[u.jsx("div",{style:{fontSize:"13px",fontWeight:"bold",marginBottom:"6px"},children:"💡 高智商请求使用方法"}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",lineHeight:"1.6"},children:["在编程工具中输入提示词时:",u.jsxs("ul",{style:{marginTop:"8px",paddingLeft:"20px",lineHeight:"1.8"},children:[u.jsxs("li",{children:["使用 ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!!"})," 标记高智商请求(仅在“最近一条真实用户输入”生效)"]}),u.jsx("li",{children:"系统会自动忽略工具构造的 user 消息(如 tool_result),按对话上下文推断是否继续走高智商规则"})]})]}),u.jsxs("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"8px",lineHeight:"1.6"},children:[u.jsx("strong",{children:"示例:"}),u.jsx("br",{}),"• ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"!! 重构A模块"}),u.jsx("br",{}),"• ",u.jsx("code",{style:{background:"var(--bg-code-inline, #f5f5f5)",padding:"2px 6px",borderRadius:"3px",fontFamily:"monospace",fontSize:"12px"},children:"继续正常对话(不加 !!)"})]})]}),R==="model-mapping"&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{children:["被顶替模型 ",u.jsx("small",{children:"(可在日志中找出想要顶替的模型名)"})]}),u.jsx("input",{type:"text",value:D,onChange:C=>O(C.target.value),placeholder:"例如:gpt-4"})]}),R==="image-understanding"&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:"pointer"},children:[u.jsx("input",{type:"checkbox",checked:be,onChange:C=>F(C.target.checked),style:{marginRight:"8px",cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"使用MCP"})]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"开启后,将使用MCP工具处理图像理解请求,而不是直接调用API服务"})]}),R==="image-understanding"&&be&&u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{children:["选择MCP工具 ",u.jsx("span",{className:"required",children:"*"})]}),u.jsx("div",{style:{maxHeight:"300px",overflowY:"auto",border:"1px solid var(--border-primary)",borderRadius:"6px",padding:"8px"},children:p.length===0?u.jsx("div",{style:{padding:"12px",textAlign:"center",color:"var(--text-muted)"},children:"暂无MCP工具,请先在MCP管理页面添加"}):p.map(C=>u.jsxs("div",{onClick:()=>oe(C.id),style:{padding:"12px",marginBottom:"8px",border:`2px solid ${le===C.id?"var(--primary-color)":"var(--border-primary)"}`,borderRadius:"6px",cursor:"pointer",backgroundColor:le===C.id?"var(--bg-info-blue)":"var(--bg-card)",transition:"all 0.2s ease"},children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[u.jsx("div",{style:{fontWeight:600,fontSize:"14px"},children:C.name}),u.jsx("div",{className:"badge badge-secondary",style:{fontSize:"11px"},children:C.type==="stdio"?"命令行":C.type.toUpperCase()})]}),C.description&&u.jsx("div",{style:{fontSize:"12px",color:"var(--text-muted)",marginTop:"4px"},children:C.description})]},C.id))})]}),!be&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商"}),u.jsxs("select",{value:T,onChange:C=>M(C.target.value),required:!0,children:[u.jsx("option",{value:"",disabled:!0,children:"请选择供应商"}),o.map(C=>u.jsx("option",{value:C.id,children:C.name},C.id))]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商API服务"}),u.jsxs("select",{value:A,onChange:C=>{const Q=C.target.value;_(Q),H("");const me=s.find(ye=>ye.id===Q);me&&(me.enableTokenLimit&&me.tokenLimit?(X(me.tokenLimit),I(me.tokenResetInterval),ge(me.tokenResetBaseTime?new Date(me.tokenResetBaseTime):void 0),Yt(me.tokenLimit),Bt(!0),Be(!0)):(Yt(void 0),Bt(!1),Be(!1)),me.enableRequestLimit&&me.requestCountLimit?(Y(me.requestCountLimit),ue(me.requestResetInterval),_e(me.requestResetBaseTime?new Date(me.requestResetBaseTime):void 0),ee(me.requestCountLimit),wt(!0),qe(!0)):(ee(void 0),wt(!1),qe(!1)))},required:!0,disabled:!T,children:[u.jsx("option",{value:"",disabled:!0,children:"请选择API服务"}),d.map(C=>u.jsx("option",{value:C.id,children:C.name},C.id))]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"供应商模型"}),u.jsxs("select",{value:N,onChange:C=>H(C.target.value),disabled:!A,children:[u.jsx("option",{value:"",children:"透传模型名"}),(hb=(pb=s.find(C=>C.id===A))==null?void 0:pb.supportedModels)==null?void 0:hb.map(C=>u.jsx("option",{value:C,children:C},C))]})]}),u.jsx("div",{className:"form-group",children:u.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:xt?"not-allowed":"pointer"},children:[u.jsx("input",{type:"checkbox",checked:Se,onChange:C=>Be(C.target.checked),disabled:xt,style:{marginRight:"8px",cursor:xt?"not-allowed":"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用Tokens超量限制"}),xt&&u.jsx("small",{style:{color:"#999",fontSize:"12px",marginLeft:"8px"},children:"(从API服务继承)"})]}),xt&&u.jsx("button",{type:"button",className:"btn btn-sm btn-secondary",onClick:()=>Bt(!1),style:{padding:"4px 12px",fontSize:"12px"},children:"自定义限制"})]})}),Se&&!xt&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Tokens超量(单位:k)"}),u.jsx("input",{type:"number",value:P||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;if(Q!==void 0&&It!==void 0&&Q>It){te.warning(`Token超量值不能超过API服务的限制 (${It}k)`);return}X(Q),xt&&Q!==It&&Bt(!1)},min:"0",max:It,placeholder:It?`最大 ${It}k`:"不限制",disabled:xt}),It&&u.jsxs("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:["⚠️ API服务限制:最大 ",It,"k,当前值不能超过此限制"]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"当编程工具的请求tokens达到这个量时,在配置了其他规则的情况下,本条规则将失效,从而保护你的余额。例如:输入100表示100k即100,000个tokens"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Tokens超量自动重置间隔(小时)"}),u.jsx("input",{type:"number",value:Z||"",onChange:C=>{I(C.target.value?parseInt(C.target.value):void 0),xt&&Bt(!1)},min:"1",placeholder:"不自动重置",disabled:xt}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置后,系统将每隔指定小时数自动重置token计数。例如设置5小时,则每5小时重置一次"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"Token下一次重置时间基点"}),u.jsx("input",{type:"datetime-local",value:ce?Iw(ce):"",onChange:C=>{C.target.value?ge(new Date(C.target.value)):ge(void 0),xt&&Bt(!1)},disabled:!Z||xt,className:"datetime-picker-input"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:'配合"Tokens超量自动重置间隔"使用,设置下一次重置的精确时间点。例如,每月1日0点重置(间隔720小时),或每周一0点重置(间隔168小时)。设置后,系统会基于此时间点自动计算后续重置周期'})]})]}),u.jsx("div",{className:"form-group",children:u.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"},children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:bt?"not-allowed":"pointer"},children:[u.jsx("input",{type:"checkbox",checked:Ne,onChange:C=>qe(C.target.checked),disabled:bt,style:{marginRight:"8px",cursor:bt?"not-allowed":"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用请求次数超量限制"}),bt&&u.jsx("small",{style:{color:"#999",fontSize:"12px",marginLeft:"8px"},children:"(从API服务继承)"})]}),bt&&u.jsx("button",{type:"button",className:"btn btn-sm btn-secondary",onClick:()=>wt(!1),style:{padding:"4px 12px",fontSize:"12px"},children:"自定义限制"})]})}),Ne&&!bt&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"请求次数超量"}),u.jsx("input",{type:"number",value:se||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;if(Q!==void 0&&W!==void 0&&Q>W){te.warning(`请求次数超量值不能超过API服务的限制 (${W})`);return}Y(Q),bt&&Q!==W&&wt(!1)},min:"0",max:W,placeholder:W?`最大 ${W}`:"不限制",disabled:bt}),W&&u.jsxs("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:["⚠️ API服务限制:最大 ",W,",当前值不能超过此限制"]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"当请求次数达到这个量时,在配置了其他规则的情况下,本条规则将失效"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"请求次数自动重置间隔(小时)"}),u.jsx("input",{type:"number",value:V||"",onChange:C=>{ue(C.target.value?parseInt(C.target.value):void 0),bt&&wt(!1)},min:"1",placeholder:"不自动重置",disabled:bt}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置后,系统将每隔指定小时数自动重置请求次数计数。例如设置24小时,则每24小时重置一次"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"下一次重置时间基点"}),u.jsx("input",{type:"datetime-local",value:q?Iw(q):"",onChange:C=>{C.target.value?_e(new Date(C.target.value)):_e(void 0),bt&&wt(!1)},disabled:!V||bt,className:"datetime-picker-input"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:'配合"请求次数自动重置间隔"使用,设置下一次重置的精确时间点。例如,每月1日0点重置(间隔720小时),或每周一0点重置(间隔168小时)。设置后,系统会基于此时间点自动计算后续重置周期'})]})]})]}),u.jsxs("div",{className:"form-group",children:[u.jsxs("label",{style:{display:"flex",alignItems:"center",cursor:"pointer"},children:[u.jsx("input",{type:"checkbox",checked:!!Ce,onChange:C=>{C.target.checked?(ve(10),Pe(0)):(ve(void 0),Pe(void 0))},style:{marginRight:"8px",cursor:"pointer",width:"16px",height:"16px"}}),u.jsx("span",{children:"启用请求频率限制"})]}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"启用后,当同一内容类型的请求频率超过限制时,系统会自动切换到其他同类型规则"})]}),Ce&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"频率限制次数(并发数)"}),u.jsx("input",{type:"number",value:Ce||"",onChange:C=>ve(C.target.value?parseInt(C.target.value):void 0),min:"1",placeholder:"例如: 10"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"在指定时间窗口内允许的最大请求次数"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"频率限制时间窗口(秒,0=同一时刻)"}),u.jsx("input",{type:"number",value:we===0?0:we||"",onChange:C=>{const Q=C.target.value?parseInt(C.target.value):void 0;Pe(Q===0?0:Q)},min:"0",placeholder:"0 表示同一时刻"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"时间窗口大小。0 表示同一时刻(并发数),持续累积;设置为 60 则在 60 秒内最多允许 N 次请求"})]})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"超时时间(秒)"}),u.jsx("input",{type:"number",value:K||"",onChange:C=>J(C.target.value?parseInt(C.target.value):void 0),min:"1",placeholder:"默认300秒"}),u.jsx("small",{style:{color:"#666",fontSize:"12px",marginTop:"4px",display:"block"},children:"设置此规则的API请求超时时间。不设置则使用默认值300秒(5分钟)"})]}),u.jsxs("div",{className:"form-group",children:[u.jsx("label",{children:"排序(值越大优先级越高)"}),u.jsx("input",{type:"number",value:L,onChange:C=>U(parseInt(C.target.value)||0),min:"0",max:"1000"})]}),u.jsxs("div",{className:"modal-footer",children:[u.jsx("button",{type:"button",className:"btn btn-secondary",onClick:()=>w(!1),children:"取消"}),u.jsx("button",{type:"submit",className:"btn btn-primary",children:"保存"})]})]})]})})]})]})}var GO={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(il,function(){var n=1e3,r=6e4,i=36e5,a="millisecond",o="second",l="minute",s="hour",c="day",d="week",f="month",p="quarter",h="year",g="date",y="Invalid Date",x=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,v=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,b={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(D){var O=["th","st","nd","rd"],L=D%100;return"["+D+(O[(L-20)%10]||O[L]||O[0])+"]"}},w=function(D,O,L){var U=String(D);return!U||U.length>=O?D:""+Array(O+1-U.length).join(L)+D},S={s:w,z:function(D){var O=-D.utcOffset(),L=Math.abs(O),U=Math.floor(L/60),R=L%60;return(O<=0?"+":"-")+w(U,2,"0")+":"+w(R,2,"0")},m:function D(O,L){if(O.date()<L.date())return-D(L,O);var U=12*(L.year()-O.year())+(L.month()-O.month()),R=O.clone().add(U,f),z=L-R<0,P=O.clone().add(U+(z?-1:1),f);return+(-(U+(L-R)/(z?R-P:P-R))||0)},a:function(D){return D<0?Math.ceil(D)||0:Math.floor(D)},p:function(D){return{M:f,y:h,w:d,d:c,D:g,h:s,m:l,s:o,ms:a,Q:p}[D]||String(D||"").toLowerCase().replace(/s$/,"")},u:function(D){return D===void 0}},k="en",j={};j[k]=b;var E="$isDayjsObject",T=function(D){return D instanceof N||!(!D||!D[E])},M=function D(O,L,U){var R;if(!O)return k;if(typeof O=="string"){var z=O.toLowerCase();j[z]&&(R=z),L&&(j[z]=L,R=z);var P=O.split("-");if(!R&&P.length>1)return D(P[0])}else{var X=O.name;j[X]=O,R=X}return!U&&R&&(k=R),R||!U&&k},A=function(D,O){if(T(D))return D.clone();var L=typeof O=="object"?O:{};return L.date=D,L.args=arguments,new N(L)},_=S;_.l=M,_.i=T,_.w=function(D,O){return A(D,{locale:O.$L,utc:O.$u,x:O.$x,$offset:O.$offset})};var N=function(){function D(L){this.$L=M(L.locale,null,!0),this.parse(L),this.$x=this.$x||L.x||{},this[E]=!0}var O=D.prototype;return O.parse=function(L){this.$d=function(U){var R=U.date,z=U.utc;if(R===null)return new Date(NaN);if(_.u(R))return new Date;if(R instanceof Date)return new Date(R);if(typeof R=="string"&&!/Z$/i.test(R)){var P=R.match(x);if(P){var X=P[2]-1||0,Z=(P[7]||"0").substring(0,3);return z?new Date(Date.UTC(P[1],X,P[3]||1,P[4]||0,P[5]||0,P[6]||0,Z)):new Date(P[1],X,P[3]||1,P[4]||0,P[5]||0,P[6]||0,Z)}}return new Date(R)}(L),this.init()},O.init=function(){var L=this.$d;this.$y=L.getFullYear(),this.$M=L.getMonth(),this.$D=L.getDate(),this.$W=L.getDay(),this.$H=L.getHours(),this.$m=L.getMinutes(),this.$s=L.getSeconds(),this.$ms=L.getMilliseconds()},O.$utils=function(){return _},O.isValid=function(){return this.$d.toString()!==y},O.isSame=function(L,U){var R=A(L);return this.startOf(U)<=R&&R<=this.endOf(U)},O.isAfter=function(L,U){return A(L)<this.startOf(U)},O.isBefore=function(L,U){return this.endOf(U)<A(L)},O.$g=function(L,U,R){return _.u(L)?this[U]:this.set(R,L)},O.unix=function(){return Math.floor(this.valueOf()/1e3)},O.valueOf=function(){return this.$d.getTime()},O.startOf=function(L,U){var R=this,z=!!_.u(U)||U,P=_.p(L),X=function(Y,V){var ue=_.w(R.$u?Date.UTC(R.$y,V,Y):new Date(R.$y,V,Y),R);return z?ue:ue.endOf(c)},Z=function(Y,V){return _.w(R.toDate()[Y].apply(R.toDate("s"),(z?[0,0,0,0]:[23,59,59,999]).slice(V)),R)},I=this.$W,ce=this.$M,ge=this.$D,K="set"+(this.$u?"UTC":"");switch(P){case h:return z?X(1,0):X(31,11);case f:return z?X(1,ce):X(0,ce+1);case d:var J=this.$locale().weekStart||0,se=(I<J?I+7:I)-J;return X(z?ge-se:ge+(6-se),ce);case c:case g:return Z(K+"Hours",0);case s:return Z(K+"Minutes",1);case l:return Z(K+"Seconds",2);case o:return Z(K+"Milliseconds",3);default:return this.clone()}},O.endOf=function(L){return this.startOf(L,!1)},O.$set=function(L,U){var R,z=_.p(L),P="set"+(this.$u?"UTC":""),X=(R={},R[c]=P+"Date",R[g]=P+"Date",R[f]=P+"Month",R[h]=P+"FullYear",R[s]=P+"Hours",R[l]=P+"Minutes",R[o]=P+"Seconds",R[a]=P+"Milliseconds",R)[z],Z=z===c?this.$D+(U-this.$W):U;if(z===f||z===h){var I=this.clone().set(g,1);I.$d[X](Z),I.init(),this.$d=I.set(g,Math.min(this.$D,I.daysInMonth())).$d}else X&&this.$d[X](Z);return this.init(),this},O.set=function(L,U){return this.clone().$set(L,U)},O.get=function(L){return this[_.p(L)]()},O.add=function(L,U){var R,z=this;L=Number(L);var P=_.p(U),X=function(ce){var ge=A(z);return _.w(ge.date(ge.date()+Math.round(ce*L)),z)};if(P===f)return this.set(f,this.$M+L);if(P===h)return this.set(h,this.$y+L);if(P===c)return X(1);if(P===d)return X(7);var Z=(R={},R[l]=r,R[s]=i,R[o]=n,R)[P]||1,I=this.$d.getTime()+L*Z;return _.w(I,this)},O.subtract=function(L,U){return this.add(-1*L,U)},O.format=function(L){var U=this,R=this.$locale();if(!this.isValid())return R.invalidDate||y;var z=L||"YYYY-MM-DDTHH:mm:ssZ",P=_.z(this),X=this.$H,Z=this.$m,I=this.$M,ce=R.weekdays,ge=R.months,K=R.meridiem,J=function(V,ue,q,_e){return V&&(V[ue]||V(U,z))||q[ue].slice(0,_e)},se=function(V){return _.s(X%12||12,V,"0")},Y=K||function(V,ue,q){var _e=V<12?"AM":"PM";return q?_e.toLowerCase():_e};return z.replace(v,function(V,ue){return ue||function(q){switch(q){case"YY":return String(U.$y).slice(-2);case"YYYY":return _.s(U.$y,4,"0");case"M":return I+1;case"MM":return _.s(I+1,2,"0");case"MMM":return J(R.monthsShort,I,ge,3);case"MMMM":return J(ge,I);case"D":return U.$D;case"DD":return _.s(U.$D,2,"0");case"d":return String(U.$W);case"dd":return J(R.weekdaysMin,U.$W,ce,2);case"ddd":return J(R.weekdaysShort,U.$W,ce,3);case"dddd":return ce[U.$W];case"H":return String(X);case"HH":return _.s(X,2,"0");case"h":return se(1);case"hh":return se(2);case"a":return Y(X,Z,!0);case"A":return Y(X,Z,!1);case"m":return String(Z);case"mm":return _.s(Z,2,"0");case"s":return String(U.$s);case"ss":return _.s(U.$s,2,"0");case"SSS":return _.s(U.$ms,3,"0");case"Z":return P}return null}(V)||P.replace(":","")})},O.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},O.diff=function(L,U,R){var z,P=this,X=_.p(U),Z=A(L),I=(Z.utcOffset()-this.utcOffset())*r,ce=this-Z,ge=function(){return _.m(P,Z)};switch(X){case h:z=ge()/12;break;case f:z=ge();break;case p:z=ge()/3;break;case d:z=(ce-I)/6048e5;break;case c:z=(ce-I)/864e5;break;case s:z=ce/i;break;case l:z=ce/r;break;case o:z=ce/n;break;default:z=ce}return R?z:_.a(z)},O.daysInMonth=function(){return this.endOf(f).$D},O.$locale=function(){return j[this.$L]},O.locale=function(L,U){if(!L)return this.$L;var R=this.clone(),z=M(L,U,!0);return z&&(R.$L=z),R},O.clone=function(){return _.w(this.$d,this)},O.toDate=function(){return new Date(this.valueOf())},O.toJSON=function(){return this.isValid()?this.toISOString():null},O.toISOString=function(){return this.$d.toISOString()},O.toString=function(){return this.$d.toUTCString()},D}(),H=N.prototype;return A.prototype=H,[["$ms",a],["$s",o],["$m",l],["$H",s],["$W",c],["$M",f],["$y",h],["$D",g]].forEach(function(D){H[D[1]]=function(O){return this.$g(O,D[0],D[1])}}),A.extend=function(D,O){return D.$i||(D(O,N,A),D.$i=!0),A},A.locale=M,A.isDayjs=T,A.unix=function(D){return A(1e3*D)},A.en=j[k],A.Ls=j,A.p={},A})})(GO);var qB=GO.exports;const ln=fr(qB);var XO={exports:{}};(function(e,t){(function(n,r){e.exports=r()})(il,function(){return function(n,r,i){n=n||{};var a=r.prototype,o={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function l(c,d,f,p){return a.fromToBase(c,d,f,p)}i.en.relativeTime=o,a.fromToBase=function(c,d,f,p,h){for(var g,y,x,v=f.$locale().relativeTime||o,b=n.thresholds||[{l:"s",r:44,d:"second"},{l:"m",r:89},{l:"mm",r:44,d:"minute"},{l:"h",r:89},{l:"hh",r:21,d:"hour"},{l:"d",r:35},{l:"dd",r:25,d:"day"},{l:"M",r:45},{l:"MM",r:10,d:"month"},{l:"y",r:17},{l:"yy",d:"year"}],w=b.length,S=0;S<w;S+=1){var k=b[S];k.d&&(g=p?i(c).diff(f,k.d,!0):f.diff(c,k.d,!0));var j=(n.rounding||Math.round)(Math.abs(g));if(x=g>0,j<=k.r||!k.r){j<=1&&S>0&&(k=b[S-1]);var E=v[k.l];h&&(j=h(""+j)),y=typeof E=="string"?E.replace("%d",j):E(j,d,k.l,x);break}}if(d)return y;var T=x?v.future:v.past;return typeof T=="function"?T(y):T.replace("%s",y)},a.to=function(c,d){return l(c,d,this,!0)},a.from=function(c,d){return l(c,d,this)};var s=function(c){return c.$u?i.utc():i()};a.toNow=function(c){return this.to(s(this),c)},a.fromNow=function(c){return this.from(s(this),c)}}})})(XO);var YB=XO.exports;const GB=fr(YB),XB=["authorization","x-api-key","api-key","apikey","x-auth-token","auth-token","secret","password","api_secret","jwt","csrf_token","xsrf_token","auth_token","session_token","private_key","client_secret"],QB=e=>{const t=e.toLowerCase();return!!(XB.some(n=>t===n)||t.startsWith("api_")&&(t.endsWith("_key")||t.endsWith("_secret"))||(t.endsWith("_token")||t.endsWith("_key")||t.endsWith("_secret"))&&!["max_tokens","input_tokens","output_tokens","completion_tokens","prompt_tokens","cachereadinputtokens","totaltokens"].some(r=>t.replace(/_/g,"").includes(r.replace(/_/g,""))))},ZB=e=>!e||e.length<=8?"***":`${e.slice(0,4)}${"*".repeat(Math.min(e.length-8,20))}${e.slice(-4)}`,Bg=e=>{if(e==null)return e;if(Array.isArray(e))return e.map(t=>Bg(t));if(typeof e=="object"){const t={};for(const[n,r]of Object.entries(e))QB(n)?t[n]=typeof r=="string"?ZB(r):"***":typeof r=="object"?t[n]=Bg(r):t[n]=r;return t}return e},gr=({data:e,title:t,collapsed:n=!1})=>{const[r,i]=m.useState(!n),[a,o]=m.useState(!1),l=d=>{try{let f;typeof d=="string"?f=JSON.parse(d):f=d;const p=Bg(f);return JSON.stringify(p,null,2)}catch{return typeof d=="string"?d:String(d)}},s=()=>{const d=l(e);navigator.clipboard.writeText(d).then(()=>{o(!0),setTimeout(()=>o(!1),2e3)}).catch(f=>{console.error("Failed to copy JSON:",f)})},c=l(e);return u.jsxs("div",{className:"json-viewer",children:[u.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"},children:[t&&u.jsx("h4",{style:{margin:0,fontSize:"14px",color:"var(--text-primary)"},children:t}),u.jsxs("div",{style:{display:"flex",gap:"8px"},children:[u.jsx("button",{onClick:()=>i(!r),className:"btn btn-sm btn-secondary",style:{fontSize:"12px",padding:"2px 8px"},children:r?"折叠":"展开"}),u.jsx("button",{onClick:s,className:"btn btn-sm btn-primary",style:{fontSize:"12px",padding:"2px 8px"},children:a?"已复制":"复制"})]})]}),r&&u.jsx("pre",{style:{background:"var(--bg-code)",border:"1px solid var(--border-primary)",borderRadius:"8px",padding:"12px",overflowX:"auto",fontSize:"12px",lineHeight:"1.4",color:"var(--text-primary)",maxHeight:"400px",overflowY:"auto",margin:0},children:u.jsx("code",{children:c})})]})},im=({currentPage:e,totalItems:t,pageSize:n,onPageChange:r,onPageSizeChange:i,pageSizeOptions:a=[10,20,50,100]})=>{const o=Math.max(1,Math.ceil(t/n)),l=e===1,s=e>=o,c=()=>{l||r(1)},d=()=>{l||r(e-1)},f=()=>{s||r(e+1)},p=()=>{s||r(o)},h=g=>{const y=parseInt(g.target.value,10);i(y)};return u.jsxs("div",{className:"pagination",children:[u.jsxs("div",{className:"pagination-info",children:["共 ",t," 条"]}),u.jsxs("div",{className:"pagination-controls",children:[u.jsx("button",{className:"pagination-btn",onClick:c,disabled:l,children:"首页"}),u.jsx("button",{className:"pagination-btn",onClick:d,disabled:l,children:"上一页"}),u.jsxs("span",{className:"pagination-info",children:["第 ",e," / ",o," 页"]}),u.jsx("button",{className:"pagination-btn",onClick:f,disabled:s,children:"下一页"}),u.jsx("button",{className:"pagination-btn",onClick:p,disabled:s,children:"尾页"})]}),u.jsx("div",{className:"pagination-size",children:u.jsxs("label",{children:["每页显示",u.jsx("select",{className:"pagination-select",value:n,onChange:h,children:a.map(g=>u.jsx("option",{value:g,children:g},g))}),"条"]})})]})};ln.extend(GB);function JB(e){const t=[];let n={dataLines:[],rawLines:[]};for(const r of e){const i=r.split(`
|
|
123
123
|
`);for(const a of i){if(n.rawLines.push(a),!a.trim()){if(n.event||n.dataLines.length>0){const o=n.dataLines.length>0?n.dataLines.join(`
|
|
124
124
|
`):void 0,l={event:n.event,raw:n.rawLines.join(`
|
|
125
125
|
`)};if(o)try{l.data=JSON.parse(o)}catch{l.data=o}t.push(l)}n={dataLines:[],rawLines:[]};continue}a.startsWith("event:")?n.event=a.slice(6).trim():a.startsWith("data:")&&n.dataLines.push(a.slice(5).trim())}}if(n.event||n.dataLines.length>0){const r=n.dataLines.length>0?n.dataLines.join(`
|
package/dist/ui/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>AI Code Switch</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-COkJEguF.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="./assets/index-C7G0whng.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aicodeswitch",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.2",
|
|
4
4
|
"description": "A tool to help you manage AI programming tools to access large language models locally. It allows your Claude Code, Codex and other tools to no longer be limited to official models.",
|
|
5
5
|
"author": "tangshuang",
|
|
6
6
|
"license": "GPL-3.0",
|