aicodeswitch 1.5.0 → 1.6.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/dist/server/proxy-server.js +54 -1
- package/dist/ui/assets/index-Bw_1Ltv0.js +361 -0
- package/dist/ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/index-DJ5R6Vso.js +0 -360
- package/src/server/auth.ts +0 -79
- package/src/server/database.ts +0 -809
- package/src/server/main.ts +0 -514
- package/src/server/proxy-server.ts +0 -1301
- package/src/server/transformers/chunk-collector.ts +0 -202
- package/src/server/transformers/claude-openai.ts +0 -261
- package/src/server/transformers/openai-responses.ts +0 -440
- package/src/server/transformers/streaming.ts +0 -775
- package/src/server/version-check.ts +0 -108
- package/src/types/index.ts +0 -217
- package/src/ui/App.tsx +0 -342
- package/src/ui/api/client.ts +0 -179
- package/src/ui/components/JSONViewer.tsx +0 -89
- package/src/ui/constants/index.ts +0 -4
- package/src/ui/docs/vendors-recommand.md +0 -13
- package/src/ui/main.tsx +0 -10
- package/src/ui/pages/LogsPage.tsx +0 -702
- package/src/ui/pages/RoutesPage.tsx +0 -552
- package/src/ui/pages/SettingsPage.tsx +0 -206
- package/src/ui/pages/StatisticsPage.tsx +0 -620
- package/src/ui/pages/UsagePage.tsx +0 -13
- package/src/ui/pages/VendorsPage.tsx +0 -490
- package/src/ui/pages/WriteConfigPage.tsx +0 -198
- package/src/ui/styles/App.css +0 -831
- package/src/ui/styles/index.css +0 -137
|
@@ -702,6 +702,7 @@ class ProxyServer {
|
|
|
702
702
|
return sourceType === 'openai-responses';
|
|
703
703
|
}
|
|
704
704
|
applyModelOverride(body, rule) {
|
|
705
|
+
// 如果 targetModel 为空或不存在,保留原始 model(透传)
|
|
705
706
|
if (!rule.targetModel)
|
|
706
707
|
return body;
|
|
707
708
|
if (body && typeof body === 'object') {
|
|
@@ -813,6 +814,49 @@ class ProxyServer {
|
|
|
813
814
|
}
|
|
814
815
|
return undefined;
|
|
815
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
* 根据源工具类型和目标API类型,映射请求路径
|
|
819
|
+
* @param sourceTool 源工具类型 (claude-code 或 codex)
|
|
820
|
+
* @param targetSourceType 目标API的数据格式类型
|
|
821
|
+
* @param originalPath 原始请求路径(已去除工具前缀)
|
|
822
|
+
* @returns 映射后的目标路径
|
|
823
|
+
*/
|
|
824
|
+
mapRequestPath(sourceTool, targetSourceType, originalPath) {
|
|
825
|
+
// Claude Code 发起的请求
|
|
826
|
+
if (sourceTool === 'claude-code') {
|
|
827
|
+
// Claude Code 默认使用 Claude API 格式
|
|
828
|
+
if (this.isClaudeSource(targetSourceType)) {
|
|
829
|
+
// Claude → Claude: 直接透传路径
|
|
830
|
+
return originalPath;
|
|
831
|
+
}
|
|
832
|
+
else if (this.isOpenAIChatSource(targetSourceType)) {
|
|
833
|
+
// Claude → OpenAI Chat: /v1/messages → /v1/chat/completions
|
|
834
|
+
return originalPath.replace(/\/v1\/messages\b/, '/v1/chat/completions');
|
|
835
|
+
}
|
|
836
|
+
else if (this.isOpenAIResponsesSource(targetSourceType)) {
|
|
837
|
+
// Claude → OpenAI Responses: /v1/messages → /v1/responses/completions
|
|
838
|
+
return originalPath.replace(/\/v1\/messages\b/, '/v1/responses/completions');
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
// Codex 发起的请求
|
|
842
|
+
if (sourceTool === 'codex') {
|
|
843
|
+
// Codex 默认使用 OpenAI Responses API 格式
|
|
844
|
+
if (this.isOpenAIResponsesSource(targetSourceType)) {
|
|
845
|
+
// OpenAI Responses → OpenAI Responses: 直接透传路径
|
|
846
|
+
return originalPath;
|
|
847
|
+
}
|
|
848
|
+
else if (this.isOpenAIChatSource(targetSourceType)) {
|
|
849
|
+
// OpenAI Responses → OpenAI Chat: /v1/responses/completions → /v1/chat/completions
|
|
850
|
+
return originalPath.replace(/\/v1\/responses\/completions\b/, '/v1/chat/completions');
|
|
851
|
+
}
|
|
852
|
+
else if (this.isClaudeSource(targetSourceType)) {
|
|
853
|
+
// OpenAI Responses → Claude: /v1/responses/completions → /v1/messages
|
|
854
|
+
return originalPath.replace(/\/v1\/responses\/completions\b/, '/v1/messages');
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
// 默认:直接返回原始路径
|
|
858
|
+
return originalPath;
|
|
859
|
+
}
|
|
816
860
|
proxyRequest(req, res, route, rule, service) {
|
|
817
861
|
return __awaiter(this, void 0, void 0, function* () {
|
|
818
862
|
var _a;
|
|
@@ -827,6 +871,7 @@ class ProxyServer {
|
|
|
827
871
|
let responseHeadersForLog;
|
|
828
872
|
let responseBodyForLog;
|
|
829
873
|
let streamChunksForLog;
|
|
874
|
+
let upstreamRequestForLog;
|
|
830
875
|
const finalizeLog = (statusCode, error) => __awaiter(this, void 0, void 0, function* () {
|
|
831
876
|
var _a, _b;
|
|
832
877
|
if (logged || !((_a = this.config) === null || _a === void 0 ? void 0 : _a.enableLogging))
|
|
@@ -859,6 +904,7 @@ class ProxyServer {
|
|
|
859
904
|
responseHeaders: responseHeadersForLog,
|
|
860
905
|
responseBody: responseBodyForLog,
|
|
861
906
|
streamChunks: streamChunksForLog,
|
|
907
|
+
upstreamRequest: upstreamRequestForLog,
|
|
862
908
|
});
|
|
863
909
|
});
|
|
864
910
|
try {
|
|
@@ -903,9 +949,11 @@ class ProxyServer {
|
|
|
903
949
|
else if (route.targetType === 'codex' && req.path.startsWith('/codex')) {
|
|
904
950
|
pathToAppend = req.path.slice('/codex'.length);
|
|
905
951
|
}
|
|
952
|
+
// 根据源工具类型和目标API类型,映射请求路径
|
|
953
|
+
const mappedPath = this.mapRequestPath(route.targetType, sourceType, pathToAppend);
|
|
906
954
|
const config = {
|
|
907
955
|
method: req.method,
|
|
908
|
-
url: `${service.apiUrl}${
|
|
956
|
+
url: `${service.apiUrl}${mappedPath}`,
|
|
909
957
|
headers: this.buildUpstreamHeaders(req, service, sourceType, streamRequested),
|
|
910
958
|
timeout: service.timeout || 30000,
|
|
911
959
|
validateStatus: () => true,
|
|
@@ -917,6 +965,11 @@ class ProxyServer {
|
|
|
917
965
|
if (['POST', 'PUT', 'PATCH'].includes(req.method.toUpperCase())) {
|
|
918
966
|
config.data = requestBody;
|
|
919
967
|
}
|
|
968
|
+
// 记录实际发出的请求信息作为日志的一部分
|
|
969
|
+
upstreamRequestForLog = {
|
|
970
|
+
url: `${service.apiUrl}${mappedPath}`,
|
|
971
|
+
model: (requestBody === null || requestBody === void 0 ? void 0 : requestBody.model) || '',
|
|
972
|
+
};
|
|
920
973
|
const response = yield (0, axios_1.default)(config);
|
|
921
974
|
const responseHeaders = response.headers || {};
|
|
922
975
|
const contentType = typeof responseHeaders['content-type'] === 'string' ? responseHeaders['content-type'] : '';
|