aicodeswitch 5.2.12 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/UPGRADE.md +5 -4
- package/bin/utils/get-server.js +3 -3
- package/dist/server/access-keys/index.js +2 -2
- package/dist/server/access-keys/key-logger.js +63 -309
- package/dist/server/agent-map/activity-extractor.js +383 -0
- package/dist/server/agent-map/agent-map-service.js +1011 -0
- package/dist/server/agent-map/index.js +10 -0
- package/dist/server/agent-map/routes.js +88 -0
- package/dist/server/agent-map/session-meta.js +300 -0
- package/dist/server/conversions/index.js +10 -2
- package/dist/server/conversions/thinking/providers.js +12 -7
- package/dist/server/fs-database.js +169 -926
- package/dist/server/log-store/index.js +21 -0
- package/dist/server/log-store/log-store.js +1367 -0
- package/dist/server/log-store/types.js +2 -0
- package/dist/server/main.js +141 -46
- package/dist/server/notifier.js +100 -0
- package/dist/server/performance-tracker.js +78 -8
- package/dist/server/proxy-server.js +173 -56
- package/dist/server/transformers/chunk-collector.js +112 -25
- package/dist/ui/assets/index-CQVhBlBB.css +1 -0
- package/dist/ui/assets/index-QZBX5HHX.js +1186 -0
- package/dist/ui/assets/three-CFpmPosW.js +3802 -0
- package/dist/ui/index.html +3 -2
- package/package.json +4 -2
- package/scripts/dev.js +283 -0
- package/dist/server/tools-service.js +0 -203
- package/dist/server/websocket-service.js +0 -148
- package/dist/ui/assets/index-BFVjD9Y2.js +0 -799
- package/dist/ui/assets/index-Dm34-4zP.css +0 -1
|
@@ -54,6 +54,7 @@ const model_rewrite_transform_1 = require("./transformers/model-rewrite-transfor
|
|
|
54
54
|
const chunk_collector_1 = require("./transformers/chunk-collector");
|
|
55
55
|
const stream_timing_transform_1 = require("./transformers/stream-timing-transform");
|
|
56
56
|
const rules_status_service_1 = require("./rules-status-service");
|
|
57
|
+
const agent_map_1 = require("./agent-map");
|
|
57
58
|
const index_1 = require("./conversions/index");
|
|
58
59
|
const stream_converter_adapter_1 = require("./conversions/stream-converter-adapter");
|
|
59
60
|
const types_1 = require("../types");
|
|
@@ -66,6 +67,13 @@ const coding_plan_1 = require("./coding-plan");
|
|
|
66
67
|
const coding_plan_headers_1 = require("./coding-plan-headers");
|
|
67
68
|
const auth_1 = require("./auth");
|
|
68
69
|
const SUPPORTED_TARGETS = ['claude-code', 'codex'];
|
|
70
|
+
/**
|
|
71
|
+
* Fallback(回退原始配置)路径的虚拟供应商归属。
|
|
72
|
+
* 该路径转发的请求不属于任何用户配置的供应商/服务,故用一组固定 ID + 名称
|
|
73
|
+
* 把它纳入服务性能统计(service-performance.json),便于在测速面板单独呈现。
|
|
74
|
+
*/
|
|
75
|
+
const FALLBACK_VENDOR_ID = 'fallback-vendor';
|
|
76
|
+
const FALLBACK_VENDOR_NAME = '原始配置 / 直连';
|
|
69
77
|
/** 默认模型列表 */
|
|
70
78
|
const DEFAULT_MODELS = [
|
|
71
79
|
{ id: 'claude-sonnet-4-20250514', owned_by: 'anthropic' },
|
|
@@ -274,12 +282,16 @@ class ProxyServer {
|
|
|
274
282
|
* 流式:依据 streamTiming 精确计算 TTFT 与生成阶段吞吐;非流式:端到端估算(estimated)。
|
|
275
283
|
*/
|
|
276
284
|
emitPerformance(params) {
|
|
285
|
+
var _a;
|
|
277
286
|
const tracker = this.performanceTracker;
|
|
278
287
|
if (!tracker)
|
|
279
288
|
return;
|
|
280
289
|
const { statusCode, startTime, usage, streamTiming, service, vendorId, vendorName, model } = params;
|
|
281
290
|
const isError = statusCode >= 400;
|
|
291
|
+
const inputTokens = usage === null || usage === void 0 ? void 0 : usage.inputTokens;
|
|
282
292
|
const outputTokens = usage === null || usage === void 0 ? void 0 : usage.outputTokens;
|
|
293
|
+
const computedTotal = (inputTokens || 0) + (outputTokens || 0);
|
|
294
|
+
const totalTokens = (_a = usage === null || usage === void 0 ? void 0 : usage.totalTokens) !== null && _a !== void 0 ? _a : (computedTotal > 0 ? computedTotal : undefined);
|
|
283
295
|
const responseMs = Date.now() - startTime;
|
|
284
296
|
let ttftMs;
|
|
285
297
|
let tokensPerSecond;
|
|
@@ -295,7 +307,11 @@ class ProxyServer {
|
|
|
295
307
|
else if (outputTokens && responseMs > 0) {
|
|
296
308
|
tokensPerSecond = outputTokens / (responseMs / 1000);
|
|
297
309
|
}
|
|
298
|
-
|
|
310
|
+
// 解析最终归属:Fallback 临时服务没有真实 vendor,service.vendorId 兜底为虚拟供应商;
|
|
311
|
+
// 此时 vendorName 也为空,补上虚拟供应商名,确保不被 recordPerformance 的三元组校验丢弃。
|
|
312
|
+
const effectiveVendorId = vendorId !== null && vendorId !== void 0 ? vendorId : service.vendorId;
|
|
313
|
+
const effectiveVendorName = vendorName !== null && vendorName !== void 0 ? vendorName : (effectiveVendorId === FALLBACK_VENDOR_ID ? FALLBACK_VENDOR_NAME : undefined);
|
|
314
|
+
tracker.recordPerformance(effectiveVendorId, effectiveVendorName, service.id, service.name, model, { ttftMs, tokensPerSecond, outputTokens, inputTokens, totalTokens, timingAccuracy, isError });
|
|
299
315
|
}
|
|
300
316
|
/**
|
|
301
317
|
* 从请求中提取 API Key(支持三种 Header,按优先级依次尝试)
|
|
@@ -749,6 +765,7 @@ class ProxyServer {
|
|
|
749
765
|
responseTime: Date.now() - requestStartAt,
|
|
750
766
|
// 添加最后失败的服务信息
|
|
751
767
|
ruleId: lastFailedRule === null || lastFailedRule === void 0 ? void 0 : lastFailedRule.id,
|
|
768
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
752
769
|
targetServiceId: lastFailedService === null || lastFailedService === void 0 ? void 0 : lastFailedService.id,
|
|
753
770
|
targetServiceName: lastFailedService === null || lastFailedService === void 0 ? void 0 : lastFailedService.name,
|
|
754
771
|
targetModel: (lastFailedRule === null || lastFailedRule === void 0 ? void 0 : lastFailedRule.targetModel) || ((_e = req.body) === null || _e === void 0 ? void 0 : _e.model),
|
|
@@ -1258,6 +1275,7 @@ class ProxyServer {
|
|
|
1258
1275
|
const tempService = {
|
|
1259
1276
|
id: 'fallback-service',
|
|
1260
1277
|
name: 'Original Config',
|
|
1278
|
+
vendorId: FALLBACK_VENDOR_ID,
|
|
1261
1279
|
apiUrl: originalConfig.apiUrl,
|
|
1262
1280
|
apiKey: originalConfig.apiKey,
|
|
1263
1281
|
authType: originalConfig.authType,
|
|
@@ -3345,8 +3363,28 @@ class ProxyServer {
|
|
|
3345
3363
|
});
|
|
3346
3364
|
return { converter: adapter, extractUsage };
|
|
3347
3365
|
}
|
|
3366
|
+
/**
|
|
3367
|
+
* 将 SSEEventCollector 归一化后的 usage({input_tokens, output_tokens, total_tokens, cache_read_input_tokens})
|
|
3368
|
+
* 映射为 TokenUsage。collector 已遍历全部事件并合并 Anthropic message_start/message_delta + OpenAI/Gemini 字段,
|
|
3369
|
+
* 因此这里无需再区分上游格式。
|
|
3370
|
+
*/
|
|
3371
|
+
tokenUsageFromCollected(extracted) {
|
|
3372
|
+
var _a;
|
|
3373
|
+
if (!extracted)
|
|
3374
|
+
return undefined;
|
|
3375
|
+
const inputTokens = extracted.input_tokens || 0;
|
|
3376
|
+
const outputTokens = extracted.output_tokens || 0;
|
|
3377
|
+
const computedTotal = inputTokens + outputTokens;
|
|
3378
|
+
const totalTokens = (_a = extracted.total_tokens) !== null && _a !== void 0 ? _a : (computedTotal > 0 ? computedTotal : undefined);
|
|
3379
|
+
return {
|
|
3380
|
+
inputTokens,
|
|
3381
|
+
outputTokens,
|
|
3382
|
+
totalTokens,
|
|
3383
|
+
cacheReadInputTokens: extracted.cache_read_input_tokens || 0,
|
|
3384
|
+
};
|
|
3385
|
+
}
|
|
3348
3386
|
extractTokenUsageFromResponse(responseData, sourceType) {
|
|
3349
|
-
var _a, _b, _c, _d, _e, _f;
|
|
3387
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
3350
3388
|
if (!responseData)
|
|
3351
3389
|
return undefined;
|
|
3352
3390
|
const format = (0, source_type_mapping_1.sourceTypeToFormat)(sourceType);
|
|
@@ -3362,14 +3400,15 @@ class ProxyServer {
|
|
|
3362
3400
|
};
|
|
3363
3401
|
}
|
|
3364
3402
|
if (format === 'completions' || format === 'responses') {
|
|
3365
|
-
|
|
3403
|
+
// 标准 Responses 非流式 usage 在顶层;个别上游/中转会嵌在 response.usage 下,做兜底
|
|
3404
|
+
const usage = (_a = responseData === null || responseData === void 0 ? void 0 : responseData.usage) !== null && _a !== void 0 ? _a : (_b = responseData === null || responseData === void 0 ? void 0 : responseData.response) === null || _b === void 0 ? void 0 : _b.usage;
|
|
3366
3405
|
if (!usage)
|
|
3367
3406
|
return undefined;
|
|
3368
3407
|
return {
|
|
3369
3408
|
inputTokens: (usage === null || usage === void 0 ? void 0 : usage.input_tokens) || (usage === null || usage === void 0 ? void 0 : usage.prompt_tokens) || 0,
|
|
3370
3409
|
outputTokens: (usage === null || usage === void 0 ? void 0 : usage.output_tokens) || (usage === null || usage === void 0 ? void 0 : usage.completion_tokens) || 0,
|
|
3371
3410
|
totalTokens: (usage === null || usage === void 0 ? void 0 : usage.total_tokens) || 0,
|
|
3372
|
-
cacheReadInputTokens: (usage === null || usage === void 0 ? void 0 : usage.cached_tokens) || (usage === null || usage === void 0 ? void 0 : usage.cache_read_input_tokens) || 0,
|
|
3411
|
+
cacheReadInputTokens: (usage === null || usage === void 0 ? void 0 : usage.cached_tokens) || (usage === null || usage === void 0 ? void 0 : usage.cache_read_input_tokens) || ((_c = usage === null || usage === void 0 ? void 0 : usage.input_tokens_details) === null || _c === void 0 ? void 0 : _c.cached_tokens) || 0,
|
|
3373
3412
|
};
|
|
3374
3413
|
}
|
|
3375
3414
|
if (format === 'claude') {
|
|
@@ -3377,7 +3416,7 @@ class ProxyServer {
|
|
|
3377
3416
|
return {
|
|
3378
3417
|
inputTokens: (responseData === null || responseData === void 0 ? void 0 : responseData.input_tokens) || 0,
|
|
3379
3418
|
outputTokens: (responseData === null || responseData === void 0 ? void 0 : responseData.output_tokens) || 0,
|
|
3380
|
-
totalTokens: ((
|
|
3419
|
+
totalTokens: ((_d = responseData === null || responseData === void 0 ? void 0 : responseData.input_tokens) !== null && _d !== void 0 ? _d : 0) + ((_e = responseData === null || responseData === void 0 ? void 0 : responseData.output_tokens) !== null && _e !== void 0 ? _e : 0) || undefined,
|
|
3381
3420
|
cacheReadInputTokens: (responseData === null || responseData === void 0 ? void 0 : responseData.cache_read_input_tokens) || 0,
|
|
3382
3421
|
};
|
|
3383
3422
|
}
|
|
@@ -3387,7 +3426,7 @@ class ProxyServer {
|
|
|
3387
3426
|
return {
|
|
3388
3427
|
inputTokens: (usage === null || usage === void 0 ? void 0 : usage.input_tokens) || 0,
|
|
3389
3428
|
outputTokens: (usage === null || usage === void 0 ? void 0 : usage.output_tokens) || 0,
|
|
3390
|
-
totalTokens: ((
|
|
3429
|
+
totalTokens: ((_f = usage === null || usage === void 0 ? void 0 : usage.input_tokens) !== null && _f !== void 0 ? _f : 0) + ((_g = usage === null || usage === void 0 ? void 0 : usage.output_tokens) !== null && _g !== void 0 ? _g : 0) || undefined,
|
|
3391
3430
|
cacheReadInputTokens: (usage === null || usage === void 0 ? void 0 : usage.cache_read_input_tokens) || 0,
|
|
3392
3431
|
};
|
|
3393
3432
|
}
|
|
@@ -3407,7 +3446,7 @@ class ProxyServer {
|
|
|
3407
3446
|
return {
|
|
3408
3447
|
inputTokens: (usage === null || usage === void 0 ? void 0 : usage.input_tokens) || 0,
|
|
3409
3448
|
outputTokens: (usage === null || usage === void 0 ? void 0 : usage.output_tokens) || 0,
|
|
3410
|
-
totalTokens: ((
|
|
3449
|
+
totalTokens: ((_h = usage === null || usage === void 0 ? void 0 : usage.input_tokens) !== null && _h !== void 0 ? _h : 0) + ((_j = usage === null || usage === void 0 ? void 0 : usage.output_tokens) !== null && _j !== void 0 ? _j : 0) || undefined,
|
|
3411
3450
|
cacheReadInputTokens: (usage === null || usage === void 0 ? void 0 : usage.cache_read_input_tokens) || 0,
|
|
3412
3451
|
};
|
|
3413
3452
|
}
|
|
@@ -3415,7 +3454,7 @@ class ProxyServer {
|
|
|
3415
3454
|
}
|
|
3416
3455
|
proxyRequest(req, res, route, rule, service, options) {
|
|
3417
3456
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3418
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
3457
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
3419
3458
|
res.locals.skipLog = true;
|
|
3420
3459
|
const startTime = Date.now();
|
|
3421
3460
|
const rawSourceType = service.sourceType || 'openai-chat';
|
|
@@ -3423,8 +3462,42 @@ class ProxyServer {
|
|
|
3423
3462
|
const sourceType = (0, type_migration_1.normalizeSourceType)(rawSourceType);
|
|
3424
3463
|
const targetType = this.inferToolFromRequest(req);
|
|
3425
3464
|
const sessionId = this.defaultExtractSessionId(req, targetType) || '-';
|
|
3465
|
+
// Agent Map:在途请求注册(active 状态判定依据)
|
|
3466
|
+
const _accessKeyCtxAtStart = req._accessKeyCtx;
|
|
3467
|
+
// 后台类请求(count_tokens / compact / background 规则)不重置「本轮通知标记」,避免主任务结束后的
|
|
3468
|
+
// 续发请求重复触发结束通知
|
|
3469
|
+
const _isBgRequest = rule.contentType === 'background'
|
|
3470
|
+
|| rule.contentType === 'compact'
|
|
3471
|
+
|| this.isCountTokensPath(req.path)
|
|
3472
|
+
|| this.isCountTokensPath(req.originalUrl);
|
|
3473
|
+
// 思考类请求:复用路由同款识别(rule.contentType==='thinking' 或请求体带 thinking/reasoning 信号)。
|
|
3474
|
+
// 思考期间用更宽的静默上限,避免思考静默被误判为「上游停滞」而弹通知。
|
|
3475
|
+
const _isThinking = rule.contentType === 'thinking' || this.hasThinkingSignal(req.body);
|
|
3476
|
+
res.locals._agentMapThinking = _isThinking;
|
|
3477
|
+
agent_map_1.agentMapService.startRequest(sessionId, targetType, {
|
|
3478
|
+
source: _accessKeyCtxAtStart ? 'access-key' : 'global',
|
|
3479
|
+
keyId: (_a = _accessKeyCtxAtStart === null || _accessKeyCtxAtStart === void 0 ? void 0 : _accessKeyCtxAtStart.accessKey) === null || _a === void 0 ? void 0 : _a.id,
|
|
3480
|
+
keyName: (_b = _accessKeyCtxAtStart === null || _accessKeyCtxAtStart === void 0 ? void 0 : _accessKeyCtxAtStart.accessKey) === null || _b === void 0 ? void 0 : _b.name,
|
|
3481
|
+
background: _isBgRequest,
|
|
3482
|
+
thinking: _isThinking,
|
|
3483
|
+
});
|
|
3484
|
+
// 安全网:无论走哪条分支(含编程套餐拒绝、配额拦截、异常等早退,导致 finalizeLog 未被调用),
|
|
3485
|
+
// 都在响应关闭时确保 endRequest 配对执行一次,杜绝在途计数泄漏(「永远卡在进行中」)。
|
|
3486
|
+
res.on('close', () => {
|
|
3487
|
+
// 仅保证 endRequest 配对执行一次(防在途计数泄漏)。用独立标记 _agentMapEnded,
|
|
3488
|
+
// 不再与 finalizeLog 的 onFinalized 共用标记 —— 否则 res 'close' 先于 finalizeLog 触发时
|
|
3489
|
+
// 会把标记置位,导致 finalizeLog 跳过 onFinalized(requestCount / model / token 永不更新)。
|
|
3490
|
+
if (res.locals._agentMapEnded)
|
|
3491
|
+
return;
|
|
3492
|
+
res.locals._agentMapEnded = true;
|
|
3493
|
+
agent_map_1.agentMapService.endRequest(sessionId, {
|
|
3494
|
+
isStream: !!res.locals._agentMapStream,
|
|
3495
|
+
thinking: !!res.locals._agentMapThinking,
|
|
3496
|
+
});
|
|
3497
|
+
agent_map_1.agentMapService.reevaluate(sessionId);
|
|
3498
|
+
});
|
|
3426
3499
|
const vendor = this.dbManager.getVendorByServiceId(service.id);
|
|
3427
|
-
console.log(`\x1b[32m[Request Start]\x1b[0m client=${targetType}, session=${sessionId}, rule=${rule.id}(${rule.contentType}), vendor=${(vendor === null || vendor === void 0 ? void 0 : vendor.name) || '-'}, service=${service.name}, model=${rule.targetModel || ((
|
|
3500
|
+
console.log(`\x1b[32m[Request Start]\x1b[0m client=${targetType}, session=${sessionId}, rule=${rule.id}(${rule.contentType}), vendor=${(vendor === null || vendor === void 0 ? void 0 : vendor.name) || '-'}, service=${service.name}, model=${rule.targetModel || ((_c = req.body) === null || _c === void 0 ? void 0 : _c.model) || '-'}`);
|
|
3428
3501
|
const failoverEnabled = (options === null || options === void 0 ? void 0 : options.failoverEnabled) === true;
|
|
3429
3502
|
const forwardedToServiceName = options === null || options === void 0 ? void 0 : options.forwardedToServiceName;
|
|
3430
3503
|
const useOriginalConfig = (options === null || options === void 0 ? void 0 : options.useOriginalConfig) === true;
|
|
@@ -3593,15 +3666,52 @@ class ProxyServer {
|
|
|
3593
3666
|
// 标记规则正在使用
|
|
3594
3667
|
rules_status_service_1.rulesStatusBroadcaster.markRuleInUse(route.id, rule.id);
|
|
3595
3668
|
const finalizeLog = (statusCode, error) => __awaiter(this, void 0, void 0, function* () {
|
|
3596
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3669
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
3597
3670
|
if (logged)
|
|
3598
3671
|
return;
|
|
3599
3672
|
// 服务性能数据点采集(全局,与 AUTH 无关;独立于 enableLogging 开关)
|
|
3600
3673
|
this.emitPerformance({
|
|
3601
3674
|
statusCode, startTime, usage: usageForLog, streamTiming,
|
|
3602
3675
|
service, vendorId: vendor === null || vendor === void 0 ? void 0 : vendor.id, vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
3603
|
-
model:
|
|
3676
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_a = req.body) === null || _a === void 0 ? void 0 : _a.model),
|
|
3604
3677
|
});
|
|
3678
|
+
// Agent Map:在途请求注销 + 活动/状态采集广播(独立于 enableLogging)
|
|
3679
|
+
// 注意:endRequest 与 onFinalized 用各自独立的标记,二者解耦。
|
|
3680
|
+
// 这样即便 res 'close' 安全网已先执行 endRequest(_agentMapEnded=true),onFinalized 仍会在此执行 ——
|
|
3681
|
+
// 修复「requestCount / model / token 不更新」:旧实现二者共用 _agentMapRecorded,'close' 抢先置位会让此处整块跳过。
|
|
3682
|
+
if (!res.locals._agentMapEnded) {
|
|
3683
|
+
res.locals._agentMapEnded = true;
|
|
3684
|
+
agent_map_1.agentMapService.endRequest(sessionId, {
|
|
3685
|
+
isStream: !!res.locals._agentMapStream,
|
|
3686
|
+
thinking: !!res.locals._agentMapThinking,
|
|
3687
|
+
});
|
|
3688
|
+
}
|
|
3689
|
+
if (!res.locals._agentMapFinalized) {
|
|
3690
|
+
res.locals._agentMapFinalized = true;
|
|
3691
|
+
const _akCtx = req._accessKeyCtx;
|
|
3692
|
+
const _tokensDelta = (usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.totalTokens) ||
|
|
3693
|
+
(((usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.inputTokens) || 0) + ((usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.outputTokens) || 0));
|
|
3694
|
+
agent_map_1.agentMapService.onFinalized({
|
|
3695
|
+
sessionId,
|
|
3696
|
+
agent: targetType,
|
|
3697
|
+
source: _akCtx ? 'access-key' : 'global',
|
|
3698
|
+
keyId: (_b = _akCtx === null || _akCtx === void 0 ? void 0 : _akCtx.accessKey) === null || _b === void 0 ? void 0 : _b.id,
|
|
3699
|
+
keyName: (_c = _akCtx === null || _akCtx === void 0 ? void 0 : _akCtx.accessKey) === null || _c === void 0 ? void 0 : _c.name,
|
|
3700
|
+
title: this.defaultExtractSessionTitle(req, sessionId),
|
|
3701
|
+
timestamp: Date.now(),
|
|
3702
|
+
statusCode,
|
|
3703
|
+
// 采用真正转发给上游的模型(转换+覆盖后的 requestBody.model),而非 rule.targetModel 预测值,
|
|
3704
|
+
// 避免规则未配置 targetModel 时回退成编程工具提交的 req.body.model
|
|
3705
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_d = req.body) === null || _d === void 0 ? void 0 : _d.model),
|
|
3706
|
+
tokensDelta: _tokensDelta,
|
|
3707
|
+
// 输入/输出拆分(3D 连线两段用);usageForLog 已规范化为驼峰字段
|
|
3708
|
+
inputTokensDelta: (usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.inputTokens) || 0,
|
|
3709
|
+
outputTokensDelta: (usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.outputTokens) || 0,
|
|
3710
|
+
body: req.body,
|
|
3711
|
+
downstreamResponseBody: downstreamResponseBodyForLog !== null && downstreamResponseBodyForLog !== void 0 ? downstreamResponseBodyForLog : responseBodyForLog,
|
|
3712
|
+
responseBody: responseBodyForLog,
|
|
3713
|
+
});
|
|
3714
|
+
}
|
|
3605
3715
|
const isError = statusCode >= 400;
|
|
3606
3716
|
if (isError) {
|
|
3607
3717
|
console.log(`\x1b[31m[Request Error]\x1b[0m client=${targetType}, session=${sessionId}, rule=${rule.id}(${rule.contentType}), vendor=${(vendor === null || vendor === void 0 ? void 0 : vendor.name) || '-'}, service=${service.name}, status=${statusCode}, time=${Date.now() - startTime}ms${error ? `, error=${error}` : ''}`);
|
|
@@ -3610,7 +3720,7 @@ class ProxyServer {
|
|
|
3610
3720
|
console.log(`\x1b[33m[Request End]\x1b[0m client=${targetType}, session=${sessionId}, rule=${rule.id}(${rule.contentType}), vendor=${(vendor === null || vendor === void 0 ? void 0 : vendor.name) || '-'}, service=${service.name}, status=${statusCode}, time=${Date.now() - startTime}ms`);
|
|
3611
3721
|
}
|
|
3612
3722
|
// 检查是否启用日志记录(默认启用)
|
|
3613
|
-
const enableLogging = ((
|
|
3723
|
+
const enableLogging = ((_e = this.config) === null || _e === void 0 ? void 0 : _e.enableLogging) !== false; // 默认为 true
|
|
3614
3724
|
if (!enableLogging) {
|
|
3615
3725
|
return;
|
|
3616
3726
|
}
|
|
@@ -3634,13 +3744,14 @@ class ProxyServer {
|
|
|
3634
3744
|
error,
|
|
3635
3745
|
contentType: rule.contentType,
|
|
3636
3746
|
ruleId: rule.id,
|
|
3747
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
3637
3748
|
targetType,
|
|
3638
3749
|
targetServiceId: service.id,
|
|
3639
3750
|
targetServiceName: service.name,
|
|
3640
|
-
targetModel:
|
|
3751
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_f = req.body) === null || _f === void 0 ? void 0 : _f.model),
|
|
3641
3752
|
vendorId: service.vendorId,
|
|
3642
3753
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
3643
|
-
requestModel: (
|
|
3754
|
+
requestModel: (_g = req.body) === null || _g === void 0 ? void 0 : _g.model,
|
|
3644
3755
|
tags: this.buildRelayTags(relayedForLog, useOriginalConfig),
|
|
3645
3756
|
responseHeaders: responseHeadersForLog,
|
|
3646
3757
|
responseBody: responseBodyForLog,
|
|
@@ -3674,7 +3785,7 @@ class ProxyServer {
|
|
|
3674
3785
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
3675
3786
|
serviceId: service.id,
|
|
3676
3787
|
serviceName: service.name,
|
|
3677
|
-
model:
|
|
3788
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_h = req.body) === null || _h === void 0 ? void 0 : _h.model),
|
|
3678
3789
|
totalTokens: sessionTokens,
|
|
3679
3790
|
}).catch(err => console.error('[KeySession] upsert error:', err));
|
|
3680
3791
|
}
|
|
@@ -3698,13 +3809,14 @@ class ProxyServer {
|
|
|
3698
3809
|
error,
|
|
3699
3810
|
contentType: rule.contentType,
|
|
3700
3811
|
ruleId: rule.id,
|
|
3812
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
3701
3813
|
targetType,
|
|
3702
3814
|
targetServiceId: service.id,
|
|
3703
3815
|
targetServiceName: service.name,
|
|
3704
|
-
targetModel:
|
|
3816
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_j = req.body) === null || _j === void 0 ? void 0 : _j.model),
|
|
3705
3817
|
vendorId: service.vendorId,
|
|
3706
3818
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
3707
|
-
requestModel: (
|
|
3819
|
+
requestModel: (_k = req.body) === null || _k === void 0 ? void 0 : _k.model,
|
|
3708
3820
|
tags: this.buildRelayTags(relayedForLog, useOriginalConfig),
|
|
3709
3821
|
});
|
|
3710
3822
|
}
|
|
@@ -3717,7 +3829,7 @@ class ProxyServer {
|
|
|
3717
3829
|
const vendors = this.dbManager.getVendors();
|
|
3718
3830
|
const vendorForLog = vendors.find(v => v.id === service.vendorId);
|
|
3719
3831
|
// 从请求体中提取模型信息
|
|
3720
|
-
const requestModel = (
|
|
3832
|
+
const requestModel = (_l = req.body) === null || _l === void 0 ? void 0 : _l.model;
|
|
3721
3833
|
const tagsForLog = this.buildRelayTags(relayedForLog, useOriginalConfig);
|
|
3722
3834
|
if (extraTagsForLog.length > 0) {
|
|
3723
3835
|
tagsForLog.push(...extraTagsForLog);
|
|
@@ -3736,10 +3848,11 @@ class ProxyServer {
|
|
|
3736
3848
|
// 新增字段
|
|
3737
3849
|
contentType: rule.contentType,
|
|
3738
3850
|
ruleId: rule.id,
|
|
3851
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
3739
3852
|
targetType,
|
|
3740
3853
|
targetServiceId: service.id,
|
|
3741
3854
|
targetServiceName: service.name,
|
|
3742
|
-
targetModel:
|
|
3855
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_m = req.body) === null || _m === void 0 ? void 0 : _m.model),
|
|
3743
3856
|
vendorId: service.vendorId,
|
|
3744
3857
|
vendorName: vendorForLog === null || vendorForLog === void 0 ? void 0 : vendorForLog.name,
|
|
3745
3858
|
requestModel,
|
|
@@ -3767,8 +3880,11 @@ class ProxyServer {
|
|
|
3767
3880
|
vendorName: vendorForLog === null || vendorForLog === void 0 ? void 0 : vendorForLog.name,
|
|
3768
3881
|
serviceId: service.id,
|
|
3769
3882
|
serviceName: service.name,
|
|
3770
|
-
model:
|
|
3883
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_o = req.body) === null || _o === void 0 ? void 0 : _o.model),
|
|
3771
3884
|
totalTokens,
|
|
3885
|
+
// 输入/输出拆分持久化(与 totalTokens 同口径),供 Agent Map 重启后恢复
|
|
3886
|
+
inputTokens: (usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.inputTokens) || 0,
|
|
3887
|
+
outputTokens: (usageForLog === null || usageForLog === void 0 ? void 0 : usageForLog.outputTokens) || 0,
|
|
3772
3888
|
highIqMode: rule.contentType === 'high-iq' ? true : existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqMode,
|
|
3773
3889
|
highIqRuleId: rule.contentType === 'high-iq' ? rule.id : existingSession === null || existingSession === void 0 ? void 0 : existingSession.highIqRuleId,
|
|
3774
3890
|
highIqEnabledAt: rule.contentType === 'high-iq'
|
|
@@ -3868,7 +3984,7 @@ class ProxyServer {
|
|
|
3868
3984
|
targetType,
|
|
3869
3985
|
targetServiceId: service.id,
|
|
3870
3986
|
targetServiceName: service.name,
|
|
3871
|
-
targetModel:
|
|
3987
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_a = req.body) === null || _a === void 0 ? void 0 : _a.model),
|
|
3872
3988
|
vendorId: service.vendorId,
|
|
3873
3989
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
3874
3990
|
requestModel: (_b = req.body) === null || _b === void 0 ? void 0 : _b.model,
|
|
@@ -3934,7 +4050,7 @@ class ProxyServer {
|
|
|
3934
4050
|
// responses→responses 直连非 OpenAI 官方端点时,需降级兼容(剥离 custom/namespace 等私有工具与非标准字段)
|
|
3935
4051
|
const sanitizeBody = clientFormat === 'responses' && (0, source_type_mapping_1.sourceTypeToFormat)(sourceType) === 'responses' && !(0, index_1.isOfficialOpenAiApi)(effectiveApiUrl || '');
|
|
3936
4052
|
const transformedRequestBody = this.transformRequestToUpstream(targetType, sourceType, payloadForTransform, rule.targetModel, providerConfig, serverToolConfig, sanitizeBody);
|
|
3937
|
-
requestBody = (
|
|
4053
|
+
requestBody = (_d = transformedRequestBody !== null && transformedRequestBody !== void 0 ? transformedRequestBody : this.cloneRequestBody(originalToolRequestBody)) !== null && _d !== void 0 ? _d : {};
|
|
3938
4054
|
// 对最终即将发送到上游的 Claude compact 请求再做一次兜底清理,
|
|
3939
4055
|
// 避免中间转换/覆盖步骤重新引入未配对的 tool_use。
|
|
3940
4056
|
if (rule.contentType === 'compact' && targetType === 'claude-code' && Array.isArray(requestBody === null || requestBody === void 0 ? void 0 : requestBody.messages)) {
|
|
@@ -4040,7 +4156,7 @@ class ProxyServer {
|
|
|
4040
4156
|
let errorResponseData = response.data;
|
|
4041
4157
|
if (streamRequested && response.data && typeof response.data.on === 'function') {
|
|
4042
4158
|
const raw = yield this.readStreamBody(response.data);
|
|
4043
|
-
errorResponseData = (
|
|
4159
|
+
errorResponseData = (_e = this.safeJsonParse(raw)) !== null && _e !== void 0 ? _e : raw;
|
|
4044
4160
|
}
|
|
4045
4161
|
responseHeadersForLog = this.normalizeResponseHeaders(responseHeaders);
|
|
4046
4162
|
yield handleUpstreamHttpError(response.status, errorResponseData, responseHeaders, contentType);
|
|
@@ -4078,10 +4194,10 @@ class ProxyServer {
|
|
|
4078
4194
|
targetType,
|
|
4079
4195
|
targetServiceId: service.id,
|
|
4080
4196
|
targetServiceName: service.name,
|
|
4081
|
-
targetModel:
|
|
4197
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_f = req.body) === null || _f === void 0 ? void 0 : _f.model),
|
|
4082
4198
|
vendorId: service.vendorId,
|
|
4083
4199
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4084
|
-
requestModel: (
|
|
4200
|
+
requestModel: (_g = req.body) === null || _g === void 0 ? void 0 : _g.model,
|
|
4085
4201
|
responseTime: Date.now() - startTime,
|
|
4086
4202
|
});
|
|
4087
4203
|
}
|
|
@@ -4112,18 +4228,28 @@ class ProxyServer {
|
|
|
4112
4228
|
const serializer = new streaming_1.SSESerializerTransform();
|
|
4113
4229
|
const downstreamChunkCollector = new chunk_collector_1.ChunkCollectorTransform(() => {
|
|
4114
4230
|
rules_status_service_1.rulesStatusBroadcaster.refreshRuleInUse(route.id, rule.id);
|
|
4231
|
+
// Agent Map 心跳:每个流经的下游 chunk 都视为「会话仍活跃」,刷新活动时钟(节流由 ChunkCollector 内部 5s 上限控制)
|
|
4232
|
+
// 同时把当前流式请求的实时累计 usage(input/output)一并推送,使前端节点在流式过程中随 token 增长实时上移
|
|
4233
|
+
const u = eventCollector.extractUsage();
|
|
4234
|
+
agent_map_1.agentMapService.heartbeat(sessionId, u ? {
|
|
4235
|
+
inputTokens: u.input_tokens || 0,
|
|
4236
|
+
outputTokens: u.output_tokens || 0,
|
|
4237
|
+
} : undefined);
|
|
4115
4238
|
});
|
|
4116
4239
|
// 服务性能打点:记录首/末 SSE 事件时间,用于 TTFT 与生成阶段吞吐
|
|
4117
4240
|
streamTiming = new stream_timing_transform_1.StreamTimingTransform(startTime);
|
|
4241
|
+
// Agent Map:SSE 流已建立 —— 记一个在途流,状态机据此区分「同步/流式」活跃判定
|
|
4242
|
+
res.locals._agentMapStream = true;
|
|
4243
|
+
agent_map_1.agentMapService.markStreaming(sessionId);
|
|
4118
4244
|
const compactResponseSanitizer = rule.contentType === 'compact' && targetType === 'claude-code'
|
|
4119
4245
|
? new ClaudeCompactResponseSanitizer()
|
|
4120
4246
|
: null;
|
|
4121
4247
|
// 流式 model 回写:将上游返回的 model 改写为客户端请求时的原始模型名
|
|
4122
|
-
const originalModel = (
|
|
4248
|
+
const originalModel = (_h = req.body) === null || _h === void 0 ? void 0 : _h.model;
|
|
4123
4249
|
const modelRewriter = originalModel ? new model_rewrite_transform_1.ModelRewriteTransform(originalModel) : null;
|
|
4124
4250
|
responseHeadersForLog = this.normalizeResponseHeaders(responseHeaders);
|
|
4125
4251
|
// 使用 transformSSEToTool 方法选择转换器
|
|
4126
|
-
const { converter
|
|
4252
|
+
const { converter } = this.transformSSEToTool(targetType, sourceType);
|
|
4127
4253
|
this.copyResponseHeaders(responseHeaders, res);
|
|
4128
4254
|
// 收集日志:responseBody/streamChunks 记录上游原始响应;downstreamResponseBody 记录实际下发内容
|
|
4129
4255
|
const finalizeChunks = () => {
|
|
@@ -4140,13 +4266,7 @@ class ProxyServer {
|
|
|
4140
4266
|
extractedUsage = converterUsage || extractedUsage;
|
|
4141
4267
|
}
|
|
4142
4268
|
}
|
|
4143
|
-
|
|
4144
|
-
if (extractUsage && extractedUsage) {
|
|
4145
|
-
usageForLog = extractUsage(extractedUsage);
|
|
4146
|
-
}
|
|
4147
|
-
else if (extractedUsage) {
|
|
4148
|
-
usageForLog = this.extractTokenUsageFromResponse(extractedUsage, sourceType);
|
|
4149
|
-
}
|
|
4269
|
+
usageForLog = this.tokenUsageFromCollected(extractedUsage);
|
|
4150
4270
|
};
|
|
4151
4271
|
// 监听 res 的错误事件
|
|
4152
4272
|
res.on('error', (err) => {
|
|
@@ -4219,10 +4339,10 @@ class ProxyServer {
|
|
|
4219
4339
|
targetType,
|
|
4220
4340
|
targetServiceId: service.id,
|
|
4221
4341
|
targetServiceName: service.name,
|
|
4222
|
-
targetModel:
|
|
4342
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_j = req.body) === null || _j === void 0 ? void 0 : _j.model),
|
|
4223
4343
|
vendorId: service.vendorId,
|
|
4224
4344
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4225
|
-
requestModel: (
|
|
4345
|
+
requestModel: (_k = req.body) === null || _k === void 0 ? void 0 : _k.model,
|
|
4226
4346
|
responseTime: Date.now() - startTime,
|
|
4227
4347
|
});
|
|
4228
4348
|
}
|
|
@@ -4266,10 +4386,10 @@ class ProxyServer {
|
|
|
4266
4386
|
targetType,
|
|
4267
4387
|
targetServiceId: service.id,
|
|
4268
4388
|
targetServiceName: service.name,
|
|
4269
|
-
targetModel:
|
|
4389
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_l = req.body) === null || _l === void 0 ? void 0 : _l.model),
|
|
4270
4390
|
vendorId: service.vendorId,
|
|
4271
4391
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4272
|
-
requestModel: (
|
|
4392
|
+
requestModel: (_m = req.body) === null || _m === void 0 ? void 0 : _m.model,
|
|
4273
4393
|
responseTime: Date.now() - startTime,
|
|
4274
4394
|
});
|
|
4275
4395
|
}
|
|
@@ -4288,7 +4408,7 @@ class ProxyServer {
|
|
|
4288
4408
|
let responseData = response.data;
|
|
4289
4409
|
if (streamRequested && response.data && typeof response.data.on === 'function' && !isEventStream) {
|
|
4290
4410
|
const raw = yield this.readStreamBody(response.data);
|
|
4291
|
-
responseData = (
|
|
4411
|
+
responseData = (_o = this.safeJsonParse(raw)) !== null && _o !== void 0 ? _o : raw;
|
|
4292
4412
|
}
|
|
4293
4413
|
// 收集响应头
|
|
4294
4414
|
responseHeadersForLog = this.normalizeResponseHeaders(responseHeaders);
|
|
@@ -4310,7 +4430,7 @@ class ProxyServer {
|
|
|
4310
4430
|
usageForLog = this.extractTokenUsageFromResponse(responseData, sourceType);
|
|
4311
4431
|
console.log('[Proxy] Non-stream response: extracted usageForLog:', usageForLog);
|
|
4312
4432
|
// 回写 model 字段:将上游返回的 model 改写为客户端请求时的原始模型名
|
|
4313
|
-
const originalModel = (
|
|
4433
|
+
const originalModel = (_p = req.body) === null || _p === void 0 ? void 0 : _p.model;
|
|
4314
4434
|
(0, model_rewrite_transform_1.rewriteResponseModel)(normalizedConverted, originalModel);
|
|
4315
4435
|
(0, model_rewrite_transform_1.rewriteResponseModel)(responseData, originalModel);
|
|
4316
4436
|
this.copyResponseHeaders(responseHeaders, res);
|
|
@@ -4375,10 +4495,10 @@ class ProxyServer {
|
|
|
4375
4495
|
targetType,
|
|
4376
4496
|
targetServiceId: service.id,
|
|
4377
4497
|
targetServiceName: service.name,
|
|
4378
|
-
targetModel:
|
|
4498
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_q = req.body) === null || _q === void 0 ? void 0 : _q.model),
|
|
4379
4499
|
vendorId: service.vendorId,
|
|
4380
4500
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4381
|
-
requestModel: (
|
|
4501
|
+
requestModel: (_r = req.body) === null || _r === void 0 ? void 0 : _r.model,
|
|
4382
4502
|
upstreamRequest: upstreamRequestForLog,
|
|
4383
4503
|
responseTime: Date.now() - startTime,
|
|
4384
4504
|
});
|
|
@@ -4393,7 +4513,7 @@ class ProxyServer {
|
|
|
4393
4513
|
console.error('Proxy error:', error);
|
|
4394
4514
|
// 检测是否是 timeout 错误
|
|
4395
4515
|
const isTimeout = error.code === 'ECONNABORTED' ||
|
|
4396
|
-
((
|
|
4516
|
+
((_s = error.message) === null || _s === void 0 ? void 0 : _s.toLowerCase().includes('timeout')) ||
|
|
4397
4517
|
(error.errno && error.errno === 'ETIMEDOUT');
|
|
4398
4518
|
const statusCode = isTimeout ? 504 : this.getErrorStatusCode(error, 500);
|
|
4399
4519
|
const baseErrorMessage = isTimeout
|
|
@@ -4419,10 +4539,10 @@ class ProxyServer {
|
|
|
4419
4539
|
targetType,
|
|
4420
4540
|
targetServiceId: service.id,
|
|
4421
4541
|
targetServiceName: service.name,
|
|
4422
|
-
targetModel:
|
|
4542
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_t = req.body) === null || _t === void 0 ? void 0 : _t.model),
|
|
4423
4543
|
vendorId: service.vendorId,
|
|
4424
4544
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4425
|
-
requestModel: (
|
|
4545
|
+
requestModel: (_u = req.body) === null || _u === void 0 ? void 0 : _u.model,
|
|
4426
4546
|
upstreamRequest: upstreamRequestForLog,
|
|
4427
4547
|
responseHeaders: responseHeadersForLog,
|
|
4428
4548
|
responseTime: Date.now() - startTime,
|
|
@@ -4693,7 +4813,7 @@ class ProxyServer {
|
|
|
4693
4813
|
this.emitPerformance({
|
|
4694
4814
|
statusCode, startTime, usage: usageForLog, streamTiming,
|
|
4695
4815
|
service, vendorId: vendor === null || vendor === void 0 ? void 0 : vendor.id, vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4696
|
-
model:
|
|
4816
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_a = req.body) === null || _a === void 0 ? void 0 : _a.model),
|
|
4697
4817
|
});
|
|
4698
4818
|
// AccessKey 独立日志处理
|
|
4699
4819
|
const accessKeyCtx = req._accessKeyCtx;
|
|
@@ -4711,9 +4831,10 @@ class ProxyServer {
|
|
|
4711
4831
|
error,
|
|
4712
4832
|
contentType: rule.contentType,
|
|
4713
4833
|
ruleId: rule.id,
|
|
4834
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
4714
4835
|
targetServiceId: service.id,
|
|
4715
4836
|
targetServiceName: service.name,
|
|
4716
|
-
targetModel:
|
|
4837
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_b = req.body) === null || _b === void 0 ? void 0 : _b.model),
|
|
4717
4838
|
vendorId: service.vendorId,
|
|
4718
4839
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4719
4840
|
requestModel: (_c = req.body) === null || _c === void 0 ? void 0 : _c.model,
|
|
@@ -4742,7 +4863,7 @@ class ProxyServer {
|
|
|
4742
4863
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4743
4864
|
serviceId: service.id,
|
|
4744
4865
|
serviceName: service.name,
|
|
4745
|
-
model:
|
|
4866
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_d = req.body) === null || _d === void 0 ? void 0 : _d.model),
|
|
4746
4867
|
totalTokens: sessionTokens,
|
|
4747
4868
|
}).catch(err => console.error('[KeySession] upsert error:', err));
|
|
4748
4869
|
}
|
|
@@ -4764,9 +4885,10 @@ class ProxyServer {
|
|
|
4764
4885
|
error,
|
|
4765
4886
|
contentType: rule.contentType,
|
|
4766
4887
|
ruleId: rule.id,
|
|
4888
|
+
routeId: route === null || route === void 0 ? void 0 : route.id,
|
|
4767
4889
|
targetServiceId: service.id,
|
|
4768
4890
|
targetServiceName: service.name,
|
|
4769
|
-
targetModel:
|
|
4891
|
+
targetModel: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || ((_e = req.body) === null || _e === void 0 ? void 0 : _e.model),
|
|
4770
4892
|
vendorId: service.vendorId,
|
|
4771
4893
|
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
4772
4894
|
requestModel: (_f = req.body) === null || _f === void 0 ? void 0 : _f.model,
|
|
@@ -4945,7 +5067,7 @@ class ProxyServer {
|
|
|
4945
5067
|
// 流式 model 回写:将上游返回的 model 改写为客户端请求时的原始模型名
|
|
4946
5068
|
const originalModel = (_d = req.body) === null || _d === void 0 ? void 0 : _d.model;
|
|
4947
5069
|
const modelRewriter = originalModel ? new model_rewrite_transform_1.ModelRewriteTransform(originalModel) : null;
|
|
4948
|
-
const { converter
|
|
5070
|
+
const { converter } = this.transformSSEByFormat(clientFormat, sourceType);
|
|
4949
5071
|
this.copyResponseHeaders(responseHeaders, res);
|
|
4950
5072
|
res.status(response.status);
|
|
4951
5073
|
const finalizeStreamChunks = () => {
|
|
@@ -4958,12 +5080,7 @@ class ProxyServer {
|
|
|
4958
5080
|
if (converterUsage)
|
|
4959
5081
|
extractedUsage = converterUsage;
|
|
4960
5082
|
}
|
|
4961
|
-
|
|
4962
|
-
usageForLog = extractUsage(extractedUsage);
|
|
4963
|
-
}
|
|
4964
|
-
else if (extractedUsage) {
|
|
4965
|
-
usageForLog = this.extractTokenUsageFromResponse(extractedUsage, sourceType);
|
|
4966
|
-
}
|
|
5083
|
+
usageForLog = this.tokenUsageFromCollected(extractedUsage);
|
|
4967
5084
|
};
|
|
4968
5085
|
try {
|
|
4969
5086
|
yield new Promise((resolve, reject) => {
|