aicodeswitch 1.7.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/proxy-server.js +86 -25
- package/package.json +1 -1
|
@@ -228,10 +228,24 @@ class ProxyServer {
|
|
|
228
228
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
229
229
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
230
230
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
// 根据路径判断目标类型并返回适当的错误格式
|
|
232
|
+
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
233
|
+
if (isClaudeCode) {
|
|
234
|
+
const claudeError = {
|
|
235
|
+
type: 'error',
|
|
236
|
+
error: {
|
|
237
|
+
type: 'api_error',
|
|
238
|
+
message: 'All API services failed. Please try again later.'
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
res.status(503).json(claudeError);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
res.status(503).json({
|
|
245
|
+
error: 'All services failed',
|
|
246
|
+
details: lastError === null || lastError === void 0 ? void 0 : lastError.message
|
|
247
|
+
});
|
|
248
|
+
}
|
|
235
249
|
}
|
|
236
250
|
catch (error) {
|
|
237
251
|
console.error('Proxy error:', error);
|
|
@@ -256,7 +270,21 @@ class ProxyServer {
|
|
|
256
270
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
257
271
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
258
272
|
});
|
|
259
|
-
|
|
273
|
+
// 根据路径判断目标类型并返回适当的错误格式
|
|
274
|
+
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
275
|
+
if (isClaudeCode) {
|
|
276
|
+
const claudeError = {
|
|
277
|
+
type: 'error',
|
|
278
|
+
error: {
|
|
279
|
+
type: 'api_error',
|
|
280
|
+
message: error.message || 'Internal server error'
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
res.status(500).json(claudeError);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
res.status(500).json({ error: error.message });
|
|
287
|
+
}
|
|
260
288
|
}
|
|
261
289
|
}));
|
|
262
290
|
}
|
|
@@ -350,10 +378,24 @@ class ProxyServer {
|
|
|
350
378
|
requestHeaders: this.normalizeHeaders(req.headers),
|
|
351
379
|
requestBody: req.body ? JSON.stringify(req.body) : undefined,
|
|
352
380
|
});
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
381
|
+
// 根据路径判断目标类型并返回适当的错误格式
|
|
382
|
+
const isClaudeCode = req.path.startsWith('/claude-code/');
|
|
383
|
+
if (isClaudeCode) {
|
|
384
|
+
const claudeError = {
|
|
385
|
+
type: 'error',
|
|
386
|
+
error: {
|
|
387
|
+
type: 'api_error',
|
|
388
|
+
message: 'All API services failed. Please try again later.'
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
res.status(503).json(claudeError);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
res.status(503).json({
|
|
395
|
+
error: 'All services failed',
|
|
396
|
+
details: lastError === null || lastError === void 0 ? void 0 : lastError.message
|
|
397
|
+
});
|
|
398
|
+
}
|
|
357
399
|
}
|
|
358
400
|
catch (error) {
|
|
359
401
|
console.error(`Fixed route error for ${targetType}:`, error);
|
|
@@ -873,7 +915,7 @@ class ProxyServer {
|
|
|
873
915
|
}
|
|
874
916
|
proxyRequest(req, res, route, rule, service) {
|
|
875
917
|
return __awaiter(this, void 0, void 0, function* () {
|
|
876
|
-
var _a;
|
|
918
|
+
var _a, _b;
|
|
877
919
|
res.locals.skipLog = true;
|
|
878
920
|
const startTime = Date.now();
|
|
879
921
|
const sourceType = (service.sourceType || 'openai-chat');
|
|
@@ -1118,25 +1160,44 @@ class ProxyServer {
|
|
|
1118
1160
|
}
|
|
1119
1161
|
catch (error) {
|
|
1120
1162
|
console.error('Proxy error:', error);
|
|
1121
|
-
|
|
1163
|
+
// 检测是否是 timeout 错误
|
|
1164
|
+
const isTimeout = error.code === 'ECONNABORTED' ||
|
|
1165
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.toLowerCase().includes('timeout')) ||
|
|
1166
|
+
(error.errno && error.errno === 'ETIMEDOUT');
|
|
1167
|
+
const errorMessage = isTimeout
|
|
1168
|
+
? 'Request timeout - the upstream API took too long to respond'
|
|
1169
|
+
: (error.message || 'Internal server error');
|
|
1170
|
+
yield finalizeLog(500, errorMessage);
|
|
1122
1171
|
// 根据请求类型返回适当格式的错误响应
|
|
1123
1172
|
const streamRequested = this.isStreamRequested(req, req.body || {});
|
|
1124
|
-
if (
|
|
1125
|
-
// 对于 Claude Code
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1173
|
+
if (route.targetType === 'claude-code') {
|
|
1174
|
+
// 对于 Claude Code,返回符合 Claude API 标准的错误响应
|
|
1175
|
+
const claudeError = {
|
|
1176
|
+
type: 'error',
|
|
1177
|
+
error: {
|
|
1178
|
+
type: isTimeout ? 'api_error' : 'api_error',
|
|
1179
|
+
message: errorMessage
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
if (streamRequested) {
|
|
1183
|
+
// 流式请求:使用 SSE 格式
|
|
1184
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
1185
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
1186
|
+
res.setHeader('Connection', 'keep-alive');
|
|
1187
|
+
res.status(200);
|
|
1188
|
+
// 发送错误事件(使用 Claude API 的标准格式)
|
|
1189
|
+
const errorEvent = `event: error\ndata: ${JSON.stringify(claudeError)}\n\n`;
|
|
1190
|
+
res.write(errorEvent);
|
|
1191
|
+
res.end();
|
|
1192
|
+
}
|
|
1193
|
+
else {
|
|
1194
|
+
// 非流式请求:返回 JSON 格式
|
|
1195
|
+
res.status(500).json(claudeError);
|
|
1196
|
+
}
|
|
1136
1197
|
}
|
|
1137
1198
|
else {
|
|
1138
|
-
//
|
|
1139
|
-
res.status(500).json({ error:
|
|
1199
|
+
// 对于 Codex,返回 JSON 格式的错误响应
|
|
1200
|
+
res.status(500).json({ error: errorMessage });
|
|
1140
1201
|
}
|
|
1141
1202
|
}
|
|
1142
1203
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aicodeswitch",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
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",
|