aicodeswitch 2.0.11 → 2.1.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/CHANGELOG.md +4 -0
- package/CLAUDE.md +38 -2
- package/TECH.md +292 -170
- package/dist/server/proxy-server.js +88 -13
- package/dist/server/transformers/claude-openai.js +554 -48
- package/dist/server/transformers/streaming.js +169 -2
- package/dist/ui/assets/index-B9EyKK90.js +452 -0
- package/dist/ui/assets/index-Bf2ZEtnh.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/schemes/claude.schema.md +945 -0
- package/schemes/openai.schema.md +2162 -0
- package/dist/ui/assets/index-BC_wSFXP.js +0 -452
- package/dist/ui/assets/index-DQ2LJr-O.css +0 -1
|
@@ -115,7 +115,7 @@ class ProxyServer {
|
|
|
115
115
|
initialize() {
|
|
116
116
|
// Dynamic proxy middleware
|
|
117
117
|
this.app.use((req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
118
|
-
var _a, _b, _c, _d, _e;
|
|
118
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
119
119
|
// 仅处理支持的目标路径
|
|
120
120
|
if (!SUPPORTED_TARGETS.some(target => req.path.startsWith(`/${target}/`))) {
|
|
121
121
|
return next();
|
|
@@ -201,7 +201,9 @@ class ProxyServer {
|
|
|
201
201
|
error: (lastError === null || lastError === void 0 ? void 0 : lastError.message) || 'All services failed',
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
|
-
//
|
|
204
|
+
// 确定目标类型
|
|
205
|
+
const targetType = req.path.startsWith('/claude-code/') ? 'claude-code' : 'codex';
|
|
206
|
+
// 记录错误日志 - 包含请求详情
|
|
205
207
|
yield this.dbManager.addErrorLog({
|
|
206
208
|
timestamp: Date.now(),
|
|
207
209
|
method: req.method,
|
|
@@ -211,6 +213,10 @@ class ProxyServer {
|
|
|
211
213
|
errorStack: lastError === null || lastError === void 0 ? void 0 : lastError.stack,
|
|
212
214
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
213
215
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
216
|
+
// 添加请求详情
|
|
217
|
+
targetType,
|
|
218
|
+
requestModel: (_e = req.body) === null || _e === void 0 ? void 0 : _e.model,
|
|
219
|
+
responseTime: 0,
|
|
214
220
|
});
|
|
215
221
|
// 根据路径判断目标类型并返回适当的错误格式
|
|
216
222
|
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
@@ -233,7 +239,7 @@ class ProxyServer {
|
|
|
233
239
|
}
|
|
234
240
|
catch (error) {
|
|
235
241
|
console.error('Proxy error:', error);
|
|
236
|
-
if (((
|
|
242
|
+
if (((_f = this.config) === null || _f === void 0 ? void 0 : _f.enableLogging) !== false && SUPPORTED_TARGETS.some(target => req.path.startsWith(`/${target}/`))) {
|
|
237
243
|
yield this.dbManager.addLog({
|
|
238
244
|
timestamp: Date.now(),
|
|
239
245
|
method: req.method,
|
|
@@ -243,7 +249,8 @@ class ProxyServer {
|
|
|
243
249
|
error: error.message,
|
|
244
250
|
});
|
|
245
251
|
}
|
|
246
|
-
// Add error log
|
|
252
|
+
// Add error log - 包含请求详情
|
|
253
|
+
const targetType = req.path.startsWith('/claude-code/') ? 'claude-code' : 'codex';
|
|
247
254
|
yield this.dbManager.addErrorLog({
|
|
248
255
|
timestamp: Date.now(),
|
|
249
256
|
method: req.method,
|
|
@@ -253,6 +260,10 @@ class ProxyServer {
|
|
|
253
260
|
errorStack: error.stack,
|
|
254
261
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
255
262
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
263
|
+
// 添加请求详情
|
|
264
|
+
targetType,
|
|
265
|
+
requestModel: (_g = req.body) === null || _g === void 0 ? void 0 : _g.model,
|
|
266
|
+
responseTime: 0,
|
|
256
267
|
});
|
|
257
268
|
// 根据路径判断目标类型并返回适当的错误格式
|
|
258
269
|
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
@@ -281,7 +292,7 @@ class ProxyServer {
|
|
|
281
292
|
}
|
|
282
293
|
createFixedRouteHandler(targetType) {
|
|
283
294
|
return (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
284
|
-
var _a, _b, _c, _d, _e;
|
|
295
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
285
296
|
try {
|
|
286
297
|
// 检查API Key验证
|
|
287
298
|
if (this.config.apiKey) {
|
|
@@ -371,7 +382,7 @@ class ProxyServer {
|
|
|
371
382
|
error: (lastError === null || lastError === void 0 ? void 0 : lastError.message) || 'All services failed',
|
|
372
383
|
});
|
|
373
384
|
}
|
|
374
|
-
// 记录错误日志
|
|
385
|
+
// 记录错误日志 - 包含请求详情(使用函数参数 targetType)
|
|
375
386
|
yield this.dbManager.addErrorLog({
|
|
376
387
|
timestamp: Date.now(),
|
|
377
388
|
method: req.method,
|
|
@@ -381,6 +392,10 @@ class ProxyServer {
|
|
|
381
392
|
errorStack: lastError === null || lastError === void 0 ? void 0 : lastError.stack,
|
|
382
393
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
383
394
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
395
|
+
// 添加请求详情
|
|
396
|
+
targetType,
|
|
397
|
+
requestModel: (_e = req.body) === null || _e === void 0 ? void 0 : _e.model,
|
|
398
|
+
responseTime: 0,
|
|
384
399
|
});
|
|
385
400
|
// 根据路径判断目标类型并返回适当的错误格式
|
|
386
401
|
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
@@ -403,7 +418,7 @@ class ProxyServer {
|
|
|
403
418
|
}
|
|
404
419
|
catch (error) {
|
|
405
420
|
console.error(`Fixed route error for ${targetType}:`, error);
|
|
406
|
-
if (((
|
|
421
|
+
if (((_f = this.config) === null || _f === void 0 ? void 0 : _f.enableLogging) !== false && SUPPORTED_TARGETS.some(target => req.path.startsWith(`/${target}/`))) {
|
|
407
422
|
yield this.dbManager.addLog({
|
|
408
423
|
timestamp: Date.now(),
|
|
409
424
|
method: req.method,
|
|
@@ -413,7 +428,7 @@ class ProxyServer {
|
|
|
413
428
|
error: error.message,
|
|
414
429
|
});
|
|
415
430
|
}
|
|
416
|
-
// Add error log
|
|
431
|
+
// Add error log - 包含请求详情(使用函数参数 targetType)
|
|
417
432
|
yield this.dbManager.addErrorLog({
|
|
418
433
|
timestamp: Date.now(),
|
|
419
434
|
method: req.method,
|
|
@@ -423,6 +438,10 @@ class ProxyServer {
|
|
|
423
438
|
errorStack: error.stack,
|
|
424
439
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
425
440
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
441
|
+
// 添加请求详情
|
|
442
|
+
targetType,
|
|
443
|
+
requestModel: (_g = req.body) === null || _g === void 0 ? void 0 : _g.model,
|
|
444
|
+
responseTime: 0,
|
|
426
445
|
});
|
|
427
446
|
res.status(500).json({ error: error.message });
|
|
428
447
|
}
|
|
@@ -1361,7 +1380,7 @@ class ProxyServer {
|
|
|
1361
1380
|
}
|
|
1362
1381
|
proxyRequest(req, res, route, rule, service) {
|
|
1363
1382
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1364
|
-
var _a, _b;
|
|
1383
|
+
var _a, _b, _c, _d;
|
|
1365
1384
|
res.locals.skipLog = true;
|
|
1366
1385
|
const startTime = Date.now();
|
|
1367
1386
|
const sourceType = (service.sourceType || 'openai-chat');
|
|
@@ -1608,10 +1627,14 @@ class ProxyServer {
|
|
|
1608
1627
|
console.error('[Proxy] Response stream error:', err);
|
|
1609
1628
|
});
|
|
1610
1629
|
(0, stream_1.pipeline)(response.data, parser, eventCollector, converter, serializer, res, (error) => __awaiter(this, void 0, void 0, function* () {
|
|
1630
|
+
var _a;
|
|
1611
1631
|
if (error) {
|
|
1612
1632
|
console.error('[Proxy] Pipeline error for claude-code:', error);
|
|
1613
|
-
// 记录到错误日志
|
|
1633
|
+
// 记录到错误日志 - 包含请求详情和实际转发信息
|
|
1614
1634
|
try {
|
|
1635
|
+
// 获取供应商信息
|
|
1636
|
+
const vendors = this.dbManager.getVendors();
|
|
1637
|
+
const vendor = vendors.find(v => v.id === service.vendorId);
|
|
1615
1638
|
yield this.dbManager.addErrorLog({
|
|
1616
1639
|
timestamp: Date.now(),
|
|
1617
1640
|
method: req.method,
|
|
@@ -1622,6 +1645,16 @@ class ProxyServer {
|
|
|
1622
1645
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
1623
1646
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
1624
1647
|
upstreamRequest: upstreamRequestForLog,
|
|
1648
|
+
// 添加请求详情
|
|
1649
|
+
ruleId: rule.id,
|
|
1650
|
+
targetType,
|
|
1651
|
+
targetServiceId: service.id,
|
|
1652
|
+
targetServiceName: service.name,
|
|
1653
|
+
targetModel: rule.targetModel,
|
|
1654
|
+
vendorId: service.vendorId,
|
|
1655
|
+
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
1656
|
+
requestModel: (_a = req.body) === null || _a === void 0 ? void 0 : _a.model,
|
|
1657
|
+
responseTime: Date.now() - startTime,
|
|
1625
1658
|
});
|
|
1626
1659
|
}
|
|
1627
1660
|
catch (logError) {
|
|
@@ -1679,10 +1712,14 @@ class ProxyServer {
|
|
|
1679
1712
|
console.error('[Proxy] Response stream error:', err);
|
|
1680
1713
|
});
|
|
1681
1714
|
(0, stream_1.pipeline)(response.data, parser, eventCollector, converter, serializer, res, (error) => __awaiter(this, void 0, void 0, function* () {
|
|
1715
|
+
var _a;
|
|
1682
1716
|
if (error) {
|
|
1683
1717
|
console.error('[Proxy] Pipeline error for codex:', error);
|
|
1684
|
-
// 记录到错误日志
|
|
1718
|
+
// 记录到错误日志 - 包含请求详情和实际转发信息
|
|
1685
1719
|
try {
|
|
1720
|
+
// 获取供应商信息
|
|
1721
|
+
const vendors = this.dbManager.getVendors();
|
|
1722
|
+
const vendor = vendors.find(v => v.id === service.vendorId);
|
|
1686
1723
|
yield this.dbManager.addErrorLog({
|
|
1687
1724
|
timestamp: Date.now(),
|
|
1688
1725
|
method: req.method,
|
|
@@ -1693,6 +1730,16 @@ class ProxyServer {
|
|
|
1693
1730
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
1694
1731
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
1695
1732
|
upstreamRequest: upstreamRequestForLog,
|
|
1733
|
+
// 添加请求详情
|
|
1734
|
+
ruleId: rule.id,
|
|
1735
|
+
targetType,
|
|
1736
|
+
targetServiceId: service.id,
|
|
1737
|
+
targetServiceName: service.name,
|
|
1738
|
+
targetModel: rule.targetModel,
|
|
1739
|
+
vendorId: service.vendorId,
|
|
1740
|
+
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
1741
|
+
requestModel: (_a = req.body) === null || _a === void 0 ? void 0 : _a.model,
|
|
1742
|
+
responseTime: Date.now() - startTime,
|
|
1696
1743
|
});
|
|
1697
1744
|
}
|
|
1698
1745
|
catch (logError) {
|
|
@@ -1784,6 +1831,9 @@ class ProxyServer {
|
|
|
1784
1831
|
else {
|
|
1785
1832
|
errorDetail = JSON.stringify(responseData);
|
|
1786
1833
|
}
|
|
1834
|
+
// 获取供应商信息
|
|
1835
|
+
const vendors = this.dbManager.getVendors();
|
|
1836
|
+
const vendor = vendors.find(v => v.id === service.vendorId);
|
|
1787
1837
|
yield this.dbManager.addErrorLog({
|
|
1788
1838
|
timestamp: Date.now(),
|
|
1789
1839
|
method: req.method,
|
|
@@ -1795,6 +1845,17 @@ class ProxyServer {
|
|
|
1795
1845
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
1796
1846
|
responseHeaders: responseHeadersForLog,
|
|
1797
1847
|
responseBody: responseBodyForLog,
|
|
1848
|
+
// 添加请求详情和实际转发信息
|
|
1849
|
+
ruleId: rule.id,
|
|
1850
|
+
targetType,
|
|
1851
|
+
targetServiceId: service.id,
|
|
1852
|
+
targetServiceName: service.name,
|
|
1853
|
+
targetModel: rule.targetModel,
|
|
1854
|
+
vendorId: service.vendorId,
|
|
1855
|
+
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
1856
|
+
requestModel: (_b = req.body) === null || _b === void 0 ? void 0 : _b.model,
|
|
1857
|
+
upstreamRequest: upstreamRequestForLog,
|
|
1858
|
+
responseTime: Date.now() - startTime,
|
|
1798
1859
|
});
|
|
1799
1860
|
this.copyResponseHeaders(responseHeaders, res);
|
|
1800
1861
|
if (contentType.includes('application/json')) {
|
|
@@ -1838,12 +1899,15 @@ class ProxyServer {
|
|
|
1838
1899
|
console.error('Proxy error:', error);
|
|
1839
1900
|
// 检测是否是 timeout 错误
|
|
1840
1901
|
const isTimeout = error.code === 'ECONNABORTED' ||
|
|
1841
|
-
((
|
|
1902
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.toLowerCase().includes('timeout')) ||
|
|
1842
1903
|
(error.errno && error.errno === 'ETIMEDOUT');
|
|
1843
1904
|
const errorMessage = isTimeout
|
|
1844
1905
|
? 'Request timeout - the upstream API took too long to respond'
|
|
1845
1906
|
: (error.message || 'Internal server error');
|
|
1846
|
-
// 将错误记录到错误日志
|
|
1907
|
+
// 将错误记录到错误日志 - 包含请求详情和实际转发信息
|
|
1908
|
+
// 获取供应商信息
|
|
1909
|
+
const vendors = this.dbManager.getVendors();
|
|
1910
|
+
const vendor = vendors.find(v => v.id === service.vendorId);
|
|
1847
1911
|
yield this.dbManager.addErrorLog({
|
|
1848
1912
|
timestamp: Date.now(),
|
|
1849
1913
|
method: req.method,
|
|
@@ -1853,6 +1917,17 @@ class ProxyServer {
|
|
|
1853
1917
|
errorStack: error.stack,
|
|
1854
1918
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
1855
1919
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
1920
|
+
// 添加请求详情和实际转发信息
|
|
1921
|
+
ruleId: rule.id,
|
|
1922
|
+
targetType,
|
|
1923
|
+
targetServiceId: service.id,
|
|
1924
|
+
targetServiceName: service.name,
|
|
1925
|
+
targetModel: rule.targetModel,
|
|
1926
|
+
vendorId: service.vendorId,
|
|
1927
|
+
vendorName: vendor === null || vendor === void 0 ? void 0 : vendor.name,
|
|
1928
|
+
requestModel: (_d = req.body) === null || _d === void 0 ? void 0 : _d.model,
|
|
1929
|
+
upstreamRequest: upstreamRequestForLog,
|
|
1930
|
+
responseTime: Date.now() - startTime,
|
|
1856
1931
|
});
|
|
1857
1932
|
yield finalizeLog(isTimeout ? 504 : 500, errorMessage);
|
|
1858
1933
|
// 根据请求类型返回适当格式的错误响应
|