@bman654/clodex 2.0.0 → 2.1.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/README.md +1 -1
- package/dist/{chunk-ZYGZ5GDI.js → chunk-QLGIKUKC.js} +47 -1
- package/dist/chunk-QLGIKUKC.js.map +1 -0
- package/dist/claude-wrapper.js +4 -27
- package/dist/claude-wrapper.js.map +1 -1
- package/dist/cli.js +250 -121
- package/dist/cli.js.map +1 -1
- package/docs/background-agents.md +3 -0
- package/package.json +1 -1
- package/dist/chunk-ZYGZ5GDI.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
loadRegistryStrict,
|
|
21
21
|
recordLaunchSelection,
|
|
22
22
|
registerServerRuntimeState,
|
|
23
|
+
removeAnthropicProxyBypass,
|
|
23
24
|
resolveBridgeMode,
|
|
24
25
|
savePreferences,
|
|
25
26
|
saveRegistry,
|
|
@@ -32,7 +33,7 @@ import {
|
|
|
32
33
|
withCredentialMutationLock,
|
|
33
34
|
withRegistryWriteLock,
|
|
34
35
|
withRegistryWriteLockSync
|
|
35
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-QLGIKUKC.js";
|
|
36
37
|
|
|
37
38
|
// src/cli.ts
|
|
38
39
|
import pc13 from "picocolors";
|
|
@@ -210,7 +211,7 @@ import { join } from "path";
|
|
|
210
211
|
// package.json
|
|
211
212
|
var package_default = {
|
|
212
213
|
name: "@bman654/clodex",
|
|
213
|
-
version: "2.
|
|
214
|
+
version: "2.1.1",
|
|
214
215
|
publishConfig: {
|
|
215
216
|
access: "public"
|
|
216
217
|
},
|
|
@@ -544,6 +545,10 @@ var ONE_M_CONTEXT_WINDOW = 1e6;
|
|
|
544
545
|
function stripOneMContextSuffix(modelId) {
|
|
545
546
|
return modelId.replace(/\[1m\]$/i, "");
|
|
546
547
|
}
|
|
548
|
+
function normalizeRouteLookupId(id) {
|
|
549
|
+
const bare = stripOneMContextSuffix(id);
|
|
550
|
+
return bare.startsWith("models/") ? bare.slice("models/".length) : bare;
|
|
551
|
+
}
|
|
547
552
|
function claudeCodeClientModelId(modelId, contextWindow) {
|
|
548
553
|
const bare = stripOneMContextSuffix(modelId);
|
|
549
554
|
const window = resolveContextWindow(bare, contextWindow);
|
|
@@ -552,19 +557,6 @@ function claudeCodeClientModelId(modelId, contextWindow) {
|
|
|
552
557
|
}
|
|
553
558
|
return bare;
|
|
554
559
|
}
|
|
555
|
-
function routeLookupIds(id) {
|
|
556
|
-
const bare = stripOneMContextSuffix(id);
|
|
557
|
-
const googleBare = bare.startsWith("models/") ? bare.slice("models/".length) : bare;
|
|
558
|
-
return [.../* @__PURE__ */ new Set([
|
|
559
|
-
id,
|
|
560
|
-
bare,
|
|
561
|
-
`${bare}${ONE_M_CONTEXT_SUFFIX}`,
|
|
562
|
-
googleBare,
|
|
563
|
-
`${googleBare}${ONE_M_CONTEXT_SUFFIX}`,
|
|
564
|
-
`models/${googleBare}`,
|
|
565
|
-
`models/${bare}`
|
|
566
|
-
])];
|
|
567
|
-
}
|
|
568
560
|
|
|
569
561
|
// src/oauth/types.ts
|
|
570
562
|
function oauthCredentialToKeychainJson(cred) {
|
|
@@ -830,24 +822,7 @@ function buildHttpProxyChildEnv(proxyPort, caCertPath) {
|
|
|
830
822
|
env["https_proxy"] = proxyUrl;
|
|
831
823
|
env["http_proxy"] = proxyUrl;
|
|
832
824
|
env["NODE_EXTRA_CA_CERTS"] = caCertPath;
|
|
833
|
-
|
|
834
|
-
if (noProxy !== void 0) {
|
|
835
|
-
const filtered = noProxy.split(",").map((value) => value.trim()).filter(Boolean).filter((value) => {
|
|
836
|
-
const entry = value.toLowerCase().replace(/^https?:\/\//, "");
|
|
837
|
-
const host = entry.replace(/:\d+$/, "");
|
|
838
|
-
if (host === "*") return false;
|
|
839
|
-
const suffix = host.startsWith("*.") ? host.slice(1) : host;
|
|
840
|
-
const bypassesAnthropic = suffix.startsWith(".") ? "api.anthropic.com".endsWith(suffix) : "api.anthropic.com" === suffix || "api.anthropic.com".endsWith(`.${suffix}`);
|
|
841
|
-
return !bypassesAnthropic;
|
|
842
|
-
}).join(",");
|
|
843
|
-
if (filtered) {
|
|
844
|
-
env["NO_PROXY"] = filtered;
|
|
845
|
-
env["no_proxy"] = filtered;
|
|
846
|
-
} else {
|
|
847
|
-
delete env["NO_PROXY"];
|
|
848
|
-
delete env["no_proxy"];
|
|
849
|
-
}
|
|
850
|
-
}
|
|
825
|
+
removeAnthropicProxyBypass(env);
|
|
851
826
|
return env;
|
|
852
827
|
}
|
|
853
828
|
function classifyKeyringError(err) {
|
|
@@ -2562,6 +2537,12 @@ function numericRetryAfterSeconds(inner) {
|
|
|
2562
2537
|
}
|
|
2563
2538
|
return void 0;
|
|
2564
2539
|
}
|
|
2540
|
+
function boundedTransportCode(data) {
|
|
2541
|
+
if (!data || typeof data !== "object") return void 0;
|
|
2542
|
+
const error = data.error;
|
|
2543
|
+
if (!error || typeof error !== "object") return void 0;
|
|
2544
|
+
return error.code === "websocket_transport_error" ? "websocket_transport_error" : void 0;
|
|
2545
|
+
}
|
|
2565
2546
|
function sdkUpstreamErrorDetails(err) {
|
|
2566
2547
|
const retry = RetryError.isInstance(err) ? err : void 0;
|
|
2567
2548
|
const inner = retry?.lastError ?? err;
|
|
@@ -2580,7 +2561,8 @@ function sdkUpstreamErrorDetails(err) {
|
|
|
2580
2561
|
errorContent: errorContent || inner.message,
|
|
2581
2562
|
isRetryable: inner.isRetryable,
|
|
2582
2563
|
attemptCount: retry?.errors.length ?? 1,
|
|
2583
|
-
...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
|
|
2564
|
+
...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {},
|
|
2565
|
+
transportCode: boundedTransportCode(inner.data)
|
|
2584
2566
|
};
|
|
2585
2567
|
}
|
|
2586
2568
|
function isContextLengthExceededError(err, formattedMessage = "") {
|
|
@@ -5062,6 +5044,7 @@ function nonNegativeInteger(value) {
|
|
|
5062
5044
|
return value !== void 0 && Number.isFinite(value) ? Math.max(0, Math.round(value)) : void 0;
|
|
5063
5045
|
}
|
|
5064
5046
|
function writeInferenceResponseLifecycleLog(path, entry) {
|
|
5047
|
+
const claudeSessionId = safeClaudeSessionId(entry.claudeSessionId);
|
|
5065
5048
|
const statusCode = nonNegativeInteger(entry.statusCode);
|
|
5066
5049
|
const durationMs = nonNegativeInteger(entry.durationMs);
|
|
5067
5050
|
const timeToFirstByteMs = nonNegativeInteger(entry.timeToFirstByteMs);
|
|
@@ -5081,6 +5064,7 @@ function writeInferenceResponseLifecycleLog(path, entry) {
|
|
|
5081
5064
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5082
5065
|
event: entry.event,
|
|
5083
5066
|
requestId: compactLogValue(entry.requestId, 100),
|
|
5067
|
+
...claudeSessionId ? { claudeSessionId } : {},
|
|
5084
5068
|
modelId: compactLogValue(entry.modelId),
|
|
5085
5069
|
provider: compactLogValue(entry.provider, 200),
|
|
5086
5070
|
route: entry.route,
|
|
@@ -5103,7 +5087,10 @@ function writeInferenceResponseLifecycleLog(path, entry) {
|
|
|
5103
5087
|
...cacheReadInputTokens !== void 0 ? { cacheReadInputTokens } : {},
|
|
5104
5088
|
...entry.lastPartType ? { lastPartType: compactLogValue(entry.lastPartType, 100) } : {},
|
|
5105
5089
|
...entry.errorType ? { errorType: compactLogValue(entry.errorType, 200) } : {},
|
|
5106
|
-
...entry.
|
|
5090
|
+
...entry.errorCode ? { errorCode: compactLogValue(entry.errorCode, 100) } : {},
|
|
5091
|
+
...entry.errorSignature ? { errorSignature: compactLogValue(entry.errorSignature, 100) } : {},
|
|
5092
|
+
...entry.failureSource ? { failureSource: entry.failureSource } : {},
|
|
5093
|
+
...entry.terminationSource ? { terminationSource: entry.terminationSource } : {}
|
|
5107
5094
|
}));
|
|
5108
5095
|
}
|
|
5109
5096
|
function writeProxyLifecycleLog(path, entry) {
|
|
@@ -5154,6 +5141,15 @@ function writeInferenceResponseErrorLog(path, entry) {
|
|
|
5154
5141
|
...includeContent ? { errorContent: compactLogValueWithMarker(entry.errorContent, RESPONSE_ERROR_MAX) } : {}
|
|
5155
5142
|
}));
|
|
5156
5143
|
}
|
|
5144
|
+
function writeInferenceRouteUnavailableLog(path, entry) {
|
|
5145
|
+
writeSecureLogLine(path, JSON.stringify({
|
|
5146
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5147
|
+
event: "route_unavailable",
|
|
5148
|
+
requestId: compactLogValue(entry.requestId, 100),
|
|
5149
|
+
modelId: compactLogValue(entry.modelId),
|
|
5150
|
+
statusCode: entry.statusCode
|
|
5151
|
+
}));
|
|
5152
|
+
}
|
|
5157
5153
|
function makeTraceLogger(logPath) {
|
|
5158
5154
|
resetTraceLog(logPath);
|
|
5159
5155
|
return (message) => writeSecureLogLine(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${message}`);
|
|
@@ -7309,6 +7305,38 @@ function sendJson(res, status, body) {
|
|
|
7309
7305
|
res.end(json);
|
|
7310
7306
|
}
|
|
7311
7307
|
|
|
7308
|
+
// src/model-aliases.ts
|
|
7309
|
+
var MODEL_ALIAS_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
7310
|
+
function isValidModelAlias(name) {
|
|
7311
|
+
return MODEL_ALIAS_PATTERN.test(name);
|
|
7312
|
+
}
|
|
7313
|
+
function parseModelAliasAssignment(value) {
|
|
7314
|
+
const separator = value.indexOf("=");
|
|
7315
|
+
if (separator < 1 || separator === value.length - 1) {
|
|
7316
|
+
return { error: "Alias must use name=clodex:<provider-id>:<model-id>." };
|
|
7317
|
+
}
|
|
7318
|
+
const name = value.slice(0, separator).trim();
|
|
7319
|
+
if (!isValidModelAlias(name)) {
|
|
7320
|
+
return { error: "Alias names must be 1-64 letters, numbers, dots, underscores, or hyphens." };
|
|
7321
|
+
}
|
|
7322
|
+
const rawTarget = value.slice(separator + 1).trim();
|
|
7323
|
+
const target = rawTarget.startsWith("clodex:") ? rawTarget.slice("clodex:".length) : rawTarget;
|
|
7324
|
+
const targetSeparator = target.indexOf(":");
|
|
7325
|
+
if (targetSeparator < 1 || targetSeparator === target.length - 1) {
|
|
7326
|
+
return { error: "Alias target must use clodex:<provider-id>:<model-id>." };
|
|
7327
|
+
}
|
|
7328
|
+
return {
|
|
7329
|
+
name,
|
|
7330
|
+
providerId: target.slice(0, targetSeparator),
|
|
7331
|
+
// `models --list` prints Claude's synthetic context suffix. It is a client
|
|
7332
|
+
// routing hint, not part of the provider catalog id stored in favorites.
|
|
7333
|
+
modelId: stripOneMContextSuffix(target.slice(targetSeparator + 1))
|
|
7334
|
+
};
|
|
7335
|
+
}
|
|
7336
|
+
function modelAliasTarget(alias) {
|
|
7337
|
+
return `clodex:${alias.providerId}:${alias.modelId}`;
|
|
7338
|
+
}
|
|
7339
|
+
|
|
7312
7340
|
// src/catalog.ts
|
|
7313
7341
|
function localModelToRoute(lp, model) {
|
|
7314
7342
|
if (model.modelFormat === "anthropic" && !model.baseUrl) return null;
|
|
@@ -7349,6 +7377,12 @@ function makeRouteResolver(localProviders) {
|
|
|
7349
7377
|
return provider && model ? localModelToRoute(provider, model) ?? void 0 : void 0;
|
|
7350
7378
|
};
|
|
7351
7379
|
}
|
|
7380
|
+
function resolveCatalogModelAliases(modelAliases, resolveRoute) {
|
|
7381
|
+
return modelAliases.map((alias) => ({
|
|
7382
|
+
name: alias.name,
|
|
7383
|
+
routeId: resolveRoute(alias.providerId, alias.modelId)?.aliasId ?? modelAliasTarget(alias)
|
|
7384
|
+
}));
|
|
7385
|
+
}
|
|
7352
7386
|
function buildCatalogRoutes(startingRoute, favorites, resolveRoute, max = MAX_MODEL_CATALOG) {
|
|
7353
7387
|
const droppedFavorites = [];
|
|
7354
7388
|
const tail = favorites.map((fav) => {
|
|
@@ -7363,38 +7397,6 @@ function buildCatalogRoutes(startingRoute, favorites, resolveRoute, max = MAX_MO
|
|
|
7363
7397
|
return { routes, droppedFavorites };
|
|
7364
7398
|
}
|
|
7365
7399
|
|
|
7366
|
-
// src/model-aliases.ts
|
|
7367
|
-
var MODEL_ALIAS_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
7368
|
-
function isValidModelAlias(name) {
|
|
7369
|
-
return MODEL_ALIAS_PATTERN.test(name);
|
|
7370
|
-
}
|
|
7371
|
-
function parseModelAliasAssignment(value) {
|
|
7372
|
-
const separator = value.indexOf("=");
|
|
7373
|
-
if (separator < 1 || separator === value.length - 1) {
|
|
7374
|
-
return { error: "Alias must use name=clodex:<provider-id>:<model-id>." };
|
|
7375
|
-
}
|
|
7376
|
-
const name = value.slice(0, separator).trim();
|
|
7377
|
-
if (!isValidModelAlias(name)) {
|
|
7378
|
-
return { error: "Alias names must be 1-64 letters, numbers, dots, underscores, or hyphens." };
|
|
7379
|
-
}
|
|
7380
|
-
const rawTarget = value.slice(separator + 1).trim();
|
|
7381
|
-
const target = rawTarget.startsWith("clodex:") ? rawTarget.slice("clodex:".length) : rawTarget;
|
|
7382
|
-
const targetSeparator = target.indexOf(":");
|
|
7383
|
-
if (targetSeparator < 1 || targetSeparator === target.length - 1) {
|
|
7384
|
-
return { error: "Alias target must use clodex:<provider-id>:<model-id>." };
|
|
7385
|
-
}
|
|
7386
|
-
return {
|
|
7387
|
-
name,
|
|
7388
|
-
providerId: target.slice(0, targetSeparator),
|
|
7389
|
-
// `models --list` prints Claude's synthetic context suffix. It is a client
|
|
7390
|
-
// routing hint, not part of the provider catalog id stored in favorites.
|
|
7391
|
-
modelId: stripOneMContextSuffix(target.slice(targetSeparator + 1))
|
|
7392
|
-
};
|
|
7393
|
-
}
|
|
7394
|
-
function modelAliasTarget(alias) {
|
|
7395
|
-
return `clodex:${alias.providerId}:${alias.modelId}`;
|
|
7396
|
-
}
|
|
7397
|
-
|
|
7398
7400
|
// src/http-proxy/routes.ts
|
|
7399
7401
|
var HTTP_PROXY_MODEL_PREFIX = "clodex:";
|
|
7400
7402
|
function httpProxyModelId(providerId, modelId) {
|
|
@@ -7578,6 +7580,11 @@ function formatOpenAIModels(models) {
|
|
|
7578
7580
|
};
|
|
7579
7581
|
}
|
|
7580
7582
|
|
|
7583
|
+
// src/route-unavailable.ts
|
|
7584
|
+
function routeUnavailableMessage(modelId) {
|
|
7585
|
+
return `Clodex model route '${modelId}' is unavailable. Run \`clodex models --list\` to see available routes, or \`clodex patch\` to refresh saved aliases.`;
|
|
7586
|
+
}
|
|
7587
|
+
|
|
7581
7588
|
// src/upstream-forward.ts
|
|
7582
7589
|
import { Readable } from "stream";
|
|
7583
7590
|
|
|
@@ -8678,7 +8685,7 @@ async function listenTcpServer(server, port, host) {
|
|
|
8678
8685
|
// src/proxy.ts
|
|
8679
8686
|
var STREAM_KEEPALIVE_INTERVAL_MS = 2e4;
|
|
8680
8687
|
var STREAM_KEEPALIVE_PING = 'event: ping\ndata: {"type":"ping"}\n\n';
|
|
8681
|
-
function createTranslationLifecycle(logPath, requestId, modelId, provider) {
|
|
8688
|
+
function createTranslationLifecycle(logPath, requestId, claudeSessionId, modelId, provider) {
|
|
8682
8689
|
if (!logPath || !requestId) return void 0;
|
|
8683
8690
|
const startedAt = Date.now();
|
|
8684
8691
|
let firstPartAt;
|
|
@@ -8693,6 +8700,7 @@ function createTranslationLifecycle(logPath, requestId, modelId, provider) {
|
|
|
8693
8700
|
const write = (event, extra = {}) => writeInferenceResponseLifecycleLog(logPath, {
|
|
8694
8701
|
event,
|
|
8695
8702
|
requestId,
|
|
8703
|
+
claudeSessionId,
|
|
8696
8704
|
modelId,
|
|
8697
8705
|
provider,
|
|
8698
8706
|
route: "translated",
|
|
@@ -8749,11 +8757,16 @@ function createTranslationLifecycle(logPath, requestId, modelId, provider) {
|
|
|
8749
8757
|
clearInterval(timer);
|
|
8750
8758
|
write("translation_cancelled", snapshot(Date.now()));
|
|
8751
8759
|
},
|
|
8752
|
-
fail(errorType, errorSignature) {
|
|
8760
|
+
fail(errorType, errorSignature, errorCode) {
|
|
8753
8761
|
if (stopped) return;
|
|
8754
8762
|
stopped = true;
|
|
8755
8763
|
clearInterval(timer);
|
|
8756
|
-
write("translation_failed", {
|
|
8764
|
+
write("translation_failed", {
|
|
8765
|
+
...snapshot(Date.now()),
|
|
8766
|
+
errorType,
|
|
8767
|
+
errorSignature,
|
|
8768
|
+
errorCode
|
|
8769
|
+
});
|
|
8757
8770
|
}
|
|
8758
8771
|
};
|
|
8759
8772
|
}
|
|
@@ -8798,11 +8811,7 @@ function aliasModelId(realId, providerId) {
|
|
|
8798
8811
|
return `anthropic-${sanitized}__${realId}`;
|
|
8799
8812
|
}
|
|
8800
8813
|
function lookupRoute(byAlias, id) {
|
|
8801
|
-
|
|
8802
|
-
const route = byAlias.get(key);
|
|
8803
|
-
if (route) return route;
|
|
8804
|
-
}
|
|
8805
|
-
return void 0;
|
|
8814
|
+
return byAlias.get(normalizeRouteLookupId(id));
|
|
8806
8815
|
}
|
|
8807
8816
|
async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenceLogPath, debugLogPath, webSocketDiagnosticsLogPath, modelAliases) {
|
|
8808
8817
|
const proxyToken = randomUUID6();
|
|
@@ -8810,12 +8819,16 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
|
|
|
8810
8819
|
if (routes.length === 0) {
|
|
8811
8820
|
throw new Error("Proxy catalog requires at least one route");
|
|
8812
8821
|
}
|
|
8813
|
-
const byAlias = new Map(routes.map((r) => [r.aliasId, r]));
|
|
8822
|
+
const byAlias = new Map(routes.map((r) => [normalizeRouteLookupId(r.aliasId), r]));
|
|
8823
|
+
const configuredAliasNames = new Set(
|
|
8824
|
+
(modelAliases ?? []).map((alias) => normalizeRouteLookupId(alias.name))
|
|
8825
|
+
);
|
|
8814
8826
|
for (const alias of modelAliases ?? []) {
|
|
8815
|
-
const route = byAlias
|
|
8816
|
-
|
|
8827
|
+
const route = lookupRoute(byAlias, alias.routeId);
|
|
8828
|
+
const aliasId = normalizeRouteLookupId(alias.name);
|
|
8829
|
+
if (route && !byAlias.has(aliasId)) byAlias.set(aliasId, route);
|
|
8817
8830
|
}
|
|
8818
|
-
const defaultRoute = byAlias
|
|
8831
|
+
const defaultRoute = lookupRoute(byAlias, defaultAliasId) ?? routes[0];
|
|
8819
8832
|
const plog = makeProxyLog(debug, debugLogPath);
|
|
8820
8833
|
const onRejection = (reason) => {
|
|
8821
8834
|
plog(() => `Unhandled Rejection: ${reason instanceof Error ? reason.stack || reason.message : String(reason)}`);
|
|
@@ -8882,7 +8895,13 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
|
|
|
8882
8895
|
const clientWantsStream = Boolean(anthropicBody.stream);
|
|
8883
8896
|
const relayRequestIdRaw = req.headers["x-relay-request-id"];
|
|
8884
8897
|
const relayRequestId = Array.isArray(relayRequestIdRaw) ? relayRequestIdRaw[0] : relayRequestIdRaw;
|
|
8885
|
-
const
|
|
8898
|
+
const resolvedRoute = typeof originalModel === "string" ? lookupRoute(byAlias, originalModel) : void 0;
|
|
8899
|
+
const configuredModelUnavailable = typeof originalModel === "string" && (normalizeRouteLookupId(originalModel).startsWith("clodex:") || configuredAliasNames.has(normalizeRouteLookupId(originalModel)));
|
|
8900
|
+
if (!resolvedRoute && configuredModelUnavailable) {
|
|
8901
|
+
anthropicError(res, 400, routeUnavailableMessage(originalModel));
|
|
8902
|
+
return;
|
|
8903
|
+
}
|
|
8904
|
+
const route = resolvedRoute ?? defaultRoute;
|
|
8886
8905
|
if (messagesEndpoint === "count_tokens" && route.modelFormat !== "anthropic") {
|
|
8887
8906
|
const inputTokens = estimateAnthropicInputTokens(anthropicBody);
|
|
8888
8907
|
plog(() => `token-count: local estimate model=${originalModel} input_tokens=${inputTokens}`);
|
|
@@ -8994,15 +9013,16 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
|
|
|
8994
9013
|
}
|
|
8995
9014
|
if (usesSdkAdapter) {
|
|
8996
9015
|
const openAiOAuth = route.npm === "@ai-sdk/openai" && route.authType === "oauth";
|
|
9016
|
+
const claudeSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
|
|
9017
|
+
const claudeSessionId = extractClaudeSessionId(anthropicBody, claudeSessionIdHeader);
|
|
8997
9018
|
const translationLifecycle = createTranslationLifecycle(
|
|
8998
9019
|
inferenceLogPath,
|
|
8999
9020
|
relayRequestId,
|
|
9021
|
+
claudeSessionId,
|
|
9000
9022
|
originalModel,
|
|
9001
9023
|
route.providerId ?? route.aliasId.split(":")[1] ?? "unknown"
|
|
9002
9024
|
);
|
|
9003
9025
|
const runSdkRequest = async () => {
|
|
9004
|
-
const claudeSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
|
|
9005
|
-
const claudeSessionId = extractClaudeSessionId(anthropicBody, claudeSessionIdHeader);
|
|
9006
9026
|
const params = translateRequest(anthropicBody, route.npm, {
|
|
9007
9027
|
openAiOAuth,
|
|
9008
9028
|
claudeSessionId,
|
|
@@ -9133,7 +9153,8 @@ async function startProxyCatalog(routes, defaultAliasId, debug = false, inferenc
|
|
|
9133
9153
|
}
|
|
9134
9154
|
translationLifecycle?.fail(
|
|
9135
9155
|
err instanceof Error ? err.name : "UpstreamError",
|
|
9136
|
-
sdkTranslationErrorSignature(err)
|
|
9156
|
+
sdkTranslationErrorSignature(err),
|
|
9157
|
+
details?.transportCode
|
|
9137
9158
|
);
|
|
9138
9159
|
const contextLengthExceeded = upstreamStatus === 400 && isContextLengthExceededError(err, message);
|
|
9139
9160
|
const clientMessage = contextLengthExceeded ? anthropicPromptTooLongMessage(
|
|
@@ -10528,7 +10549,7 @@ function requestHeadersWithoutProxyHeaders(req) {
|
|
|
10528
10549
|
}
|
|
10529
10550
|
return headers;
|
|
10530
10551
|
}
|
|
10531
|
-
function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorized, onErrorResponse, onResponseUsage, lifecycle) {
|
|
10552
|
+
function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorized, onErrorResponse, onResponseUsage, lifecycle, isLocalShutdown = () => false) {
|
|
10532
10553
|
return new Promise((resolve2) => {
|
|
10533
10554
|
const startedAt = Date.now();
|
|
10534
10555
|
let lastActivityAt = startedAt;
|
|
@@ -10546,6 +10567,7 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
10546
10567
|
writeInferenceResponseLifecycleLog(lifecycle.logPath, {
|
|
10547
10568
|
event,
|
|
10548
10569
|
requestId: lifecycle.requestId,
|
|
10570
|
+
claudeSessionId: lifecycle.claudeSessionId,
|
|
10549
10571
|
modelId: lifecycle.modelId,
|
|
10550
10572
|
provider: lifecycle.provider,
|
|
10551
10573
|
route: "passthrough",
|
|
@@ -10628,7 +10650,8 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
10628
10650
|
idleMs: now - lastActivityAt,
|
|
10629
10651
|
bytes,
|
|
10630
10652
|
chunks,
|
|
10631
|
-
errorType: errorType(err)
|
|
10653
|
+
errorType: errorType(err),
|
|
10654
|
+
terminationSource: "upstream_failure"
|
|
10632
10655
|
});
|
|
10633
10656
|
done();
|
|
10634
10657
|
});
|
|
@@ -10657,7 +10680,8 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
10657
10680
|
...firstByteAt !== void 0 ? { timeToFirstByteMs: firstByteAt - startedAt } : {},
|
|
10658
10681
|
idleMs: now - lastActivityAt,
|
|
10659
10682
|
bytes,
|
|
10660
|
-
chunks
|
|
10683
|
+
chunks,
|
|
10684
|
+
terminationSource: isLocalShutdown() ? "local_shutdown" : "downstream_client"
|
|
10661
10685
|
});
|
|
10662
10686
|
upstream.destroy(new Error("Client disconnected"));
|
|
10663
10687
|
done();
|
|
@@ -10677,7 +10701,8 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
10677
10701
|
idleMs: now - lastActivityAt,
|
|
10678
10702
|
bytes,
|
|
10679
10703
|
chunks,
|
|
10680
|
-
errorType: errorType(err)
|
|
10704
|
+
errorType: errorType(err),
|
|
10705
|
+
terminationSource: "upstream_failure"
|
|
10681
10706
|
});
|
|
10682
10707
|
onErrorResponse?.(502, `Anthropic upstream unreachable: ${err.message}`);
|
|
10683
10708
|
if (!res.headersSent) res.writeHead(502, { "Content-Type": "text/plain" });
|
|
@@ -10687,7 +10712,7 @@ function forwardRawAnthropicRequest(req, res, rawBody, origin, rejectUnauthorize
|
|
|
10687
10712
|
upstream.end(rawBody);
|
|
10688
10713
|
});
|
|
10689
10714
|
}
|
|
10690
|
-
function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
10715
|
+
function forwardToAdapter(req, res, rawBody, adapter, adapterRequest = http.request, lifecycle, isLocalShutdown = () => false) {
|
|
10691
10716
|
return new Promise((resolve2) => {
|
|
10692
10717
|
const startedAt = Date.now();
|
|
10693
10718
|
let lastActivityAt = startedAt;
|
|
@@ -10706,6 +10731,7 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10706
10731
|
writeInferenceResponseLifecycleLog(lifecycle.logPath, {
|
|
10707
10732
|
event,
|
|
10708
10733
|
requestId: lifecycle.requestId,
|
|
10734
|
+
claudeSessionId: lifecycle.claudeSessionId,
|
|
10709
10735
|
modelId: lifecycle.modelId,
|
|
10710
10736
|
provider: lifecycle.provider,
|
|
10711
10737
|
route: "translated",
|
|
@@ -10757,13 +10783,14 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10757
10783
|
...firstByteAt !== void 0 ? { timeToFirstByteMs: firstByteAt - startedAt } : {},
|
|
10758
10784
|
idleMs: now - lastActivityAt,
|
|
10759
10785
|
bytes,
|
|
10760
|
-
chunks
|
|
10786
|
+
chunks,
|
|
10787
|
+
terminationSource: isLocalShutdown() ? "local_shutdown" : "downstream_client"
|
|
10761
10788
|
});
|
|
10762
10789
|
adapterResponse?.destroy(new Error("Client disconnected"));
|
|
10763
10790
|
upstream?.destroy(new Error("Client disconnected"));
|
|
10764
10791
|
resolve2();
|
|
10765
10792
|
});
|
|
10766
|
-
const failAdapterRequest = (err) => {
|
|
10793
|
+
const failAdapterRequest = (err, failureSource) => {
|
|
10767
10794
|
if (clientDisconnected) {
|
|
10768
10795
|
resolve2();
|
|
10769
10796
|
return;
|
|
@@ -10779,13 +10806,16 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10779
10806
|
idleMs: now - lastActivityAt,
|
|
10780
10807
|
bytes,
|
|
10781
10808
|
chunks,
|
|
10782
|
-
errorType: err.name
|
|
10809
|
+
errorType: err.name,
|
|
10810
|
+
errorCode: err.code,
|
|
10811
|
+
failureSource,
|
|
10812
|
+
terminationSource: "upstream_failure"
|
|
10783
10813
|
});
|
|
10784
10814
|
if (!res.headersSent) res.writeHead(502, { "Content-Type": "text/plain" });
|
|
10785
10815
|
res.end(`Relay adapter unreachable: ${err.message}`);
|
|
10786
10816
|
resolve2();
|
|
10787
10817
|
};
|
|
10788
|
-
upstream =
|
|
10818
|
+
upstream = adapterRequest({
|
|
10789
10819
|
hostname: "127.0.0.1",
|
|
10790
10820
|
port: adapter.port,
|
|
10791
10821
|
method: "POST",
|
|
@@ -10817,7 +10847,7 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10817
10847
|
chunks += 1;
|
|
10818
10848
|
});
|
|
10819
10849
|
copyResponse(upstreamRes, res, void 0, lifecycle ? (usage) => writeLifecycle("response_usage", usage) : void 0);
|
|
10820
|
-
const failAdapterResponse = (err) => {
|
|
10850
|
+
const failAdapterResponse = (err, failureSource) => {
|
|
10821
10851
|
if (clientDisconnected) {
|
|
10822
10852
|
resolve2();
|
|
10823
10853
|
return;
|
|
@@ -10834,7 +10864,10 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10834
10864
|
idleMs: now - lastActivityAt,
|
|
10835
10865
|
bytes,
|
|
10836
10866
|
chunks,
|
|
10837
|
-
errorType: err.name
|
|
10867
|
+
errorType: err.name,
|
|
10868
|
+
errorCode: err.code,
|
|
10869
|
+
failureSource,
|
|
10870
|
+
terminationSource: "upstream_failure"
|
|
10838
10871
|
});
|
|
10839
10872
|
if (!res.writableEnded) res.destroy(err);
|
|
10840
10873
|
resolve2();
|
|
@@ -10844,16 +10877,27 @@ function forwardToAdapter(req, res, rawBody, adapter, lifecycle) {
|
|
|
10844
10877
|
lastActivityAt = Date.now();
|
|
10845
10878
|
resolve2();
|
|
10846
10879
|
});
|
|
10847
|
-
upstreamRes.once("error", failAdapterResponse);
|
|
10848
|
-
upstreamRes.once("aborted", () => failAdapterResponse(
|
|
10880
|
+
upstreamRes.once("error", (err) => failAdapterResponse(err, "adapter_response_error"));
|
|
10881
|
+
upstreamRes.once("aborted", () => failAdapterResponse(
|
|
10882
|
+
new Error("Relay adapter response aborted"),
|
|
10883
|
+
"adapter_response_aborted"
|
|
10884
|
+
));
|
|
10849
10885
|
upstreamRes.once("close", () => {
|
|
10850
|
-
if (!upstreamRes.complete)
|
|
10886
|
+
if (!upstreamRes.complete) {
|
|
10887
|
+
failAdapterResponse(
|
|
10888
|
+
new Error("Relay adapter response closed before completion"),
|
|
10889
|
+
"adapter_response_close"
|
|
10890
|
+
);
|
|
10891
|
+
}
|
|
10851
10892
|
});
|
|
10852
10893
|
});
|
|
10853
|
-
upstream.once("error", failAdapterRequest);
|
|
10894
|
+
upstream.once("error", (err) => failAdapterRequest(err, "adapter_request_error"));
|
|
10854
10895
|
upstream.once("close", () => {
|
|
10855
10896
|
if (!headersReceived && !failed) {
|
|
10856
|
-
failAdapterRequest(
|
|
10897
|
+
failAdapterRequest(
|
|
10898
|
+
new Error("Relay adapter connection closed before a response"),
|
|
10899
|
+
"adapter_request_close"
|
|
10900
|
+
);
|
|
10857
10901
|
}
|
|
10858
10902
|
});
|
|
10859
10903
|
upstream.end(rawBody);
|
|
@@ -10886,13 +10930,19 @@ function forwardPlainHttp(req, res) {
|
|
|
10886
10930
|
async function startHttpProxy(options) {
|
|
10887
10931
|
const certificates = ensureHttpProxyCertificates();
|
|
10888
10932
|
const routesById = /* @__PURE__ */ new Map();
|
|
10933
|
+
const reservedModelIds = /* @__PURE__ */ new Set();
|
|
10889
10934
|
for (const route of options.routes) {
|
|
10890
|
-
|
|
10935
|
+
routesById.set(normalizeRouteLookupId(route.aliasId), route);
|
|
10891
10936
|
}
|
|
10892
10937
|
for (const alias of options.modelAliases ?? []) {
|
|
10893
|
-
const
|
|
10938
|
+
const aliasId = normalizeRouteLookupId(alias.name);
|
|
10939
|
+
reservedModelIds.add(aliasId);
|
|
10940
|
+
const route = routesById.get(normalizeRouteLookupId(alias.routeId));
|
|
10894
10941
|
if (!route) continue;
|
|
10895
|
-
|
|
10942
|
+
routesById.set(aliasId, route);
|
|
10943
|
+
}
|
|
10944
|
+
for (const modelId of options.reservedModelIds ?? []) {
|
|
10945
|
+
reservedModelIds.add(normalizeRouteLookupId(modelId));
|
|
10896
10946
|
}
|
|
10897
10947
|
const anthropicOrigin = new URL2(options.anthropicOrigin ?? "https://api.anthropic.com");
|
|
10898
10948
|
let adapter = options.adapterHandle ?? null;
|
|
@@ -10907,6 +10957,7 @@ async function startHttpProxy(options) {
|
|
|
10907
10957
|
options.modelAliases
|
|
10908
10958
|
);
|
|
10909
10959
|
}
|
|
10960
|
+
let shuttingDown = false;
|
|
10910
10961
|
const mitmServer = https.createServer({
|
|
10911
10962
|
key: certificates.serverKey,
|
|
10912
10963
|
cert: certificates.serverCert,
|
|
@@ -10925,13 +10976,49 @@ async function startHttpProxy(options) {
|
|
|
10925
10976
|
const requestId = randomUUID8();
|
|
10926
10977
|
let parsed = null;
|
|
10927
10978
|
let route;
|
|
10979
|
+
let adapterBody = rawBody;
|
|
10980
|
+
const contentEncoding = (Array.isArray(req.headers["content-encoding"]) ? req.headers["content-encoding"].join(",") : req.headers["content-encoding"] ?? "").trim().toLowerCase();
|
|
10981
|
+
const encodedRequestBody = contentEncoding !== "" && contentEncoding !== "identity";
|
|
10928
10982
|
try {
|
|
10929
|
-
|
|
10930
|
-
|
|
10983
|
+
const decodedBody = decodeRequestBody(rawBody, req.headers["content-encoding"]);
|
|
10984
|
+
parsed = JSON.parse(decodedBody);
|
|
10985
|
+
if (encodedRequestBody) adapterBody = Buffer.from(decodedBody);
|
|
10986
|
+
if (typeof parsed.model === "string") {
|
|
10987
|
+
route = routesById.get(normalizeRouteLookupId(parsed.model));
|
|
10988
|
+
}
|
|
10931
10989
|
} catch {
|
|
10990
|
+
if (encodedRequestBody) {
|
|
10991
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
10992
|
+
res.end(JSON.stringify({
|
|
10993
|
+
type: "error",
|
|
10994
|
+
error: {
|
|
10995
|
+
type: "invalid_request_error",
|
|
10996
|
+
message: "Unable to inspect compressed request body"
|
|
10997
|
+
}
|
|
10998
|
+
}));
|
|
10999
|
+
return;
|
|
11000
|
+
}
|
|
10932
11001
|
}
|
|
10933
11002
|
const claudeSessionIdHeader = Array.isArray(req.headers["x-claude-code-session-id"]) ? req.headers["x-claude-code-session-id"][0] : req.headers["x-claude-code-session-id"];
|
|
10934
11003
|
const claudeSessionId = parsed ? extractClaudeSessionId(parsed, claudeSessionIdHeader) : void 0;
|
|
11004
|
+
const requestedModel = typeof parsed?.model === "string" ? parsed.model : void 0;
|
|
11005
|
+
const unresolvedRoutedModel = !route && requestedModel !== void 0 && (normalizeRouteLookupId(requestedModel).startsWith(HTTP_PROXY_MODEL_PREFIX) || reservedModelIds.has(normalizeRouteLookupId(requestedModel)));
|
|
11006
|
+
if (unresolvedRoutedModel) {
|
|
11007
|
+
const message = routeUnavailableMessage(requestedModel);
|
|
11008
|
+
if (messagesEndpoint === "messages" && options.inferenceLogPath) {
|
|
11009
|
+
writeInferenceRouteUnavailableLog(options.inferenceLogPath, {
|
|
11010
|
+
requestId,
|
|
11011
|
+
modelId: requestedModel,
|
|
11012
|
+
statusCode: 400
|
|
11013
|
+
});
|
|
11014
|
+
}
|
|
11015
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
11016
|
+
res.end(JSON.stringify({
|
|
11017
|
+
type: "error",
|
|
11018
|
+
error: { type: "invalid_request_error", message }
|
|
11019
|
+
}));
|
|
11020
|
+
return;
|
|
11021
|
+
}
|
|
10935
11022
|
if (messagesEndpoint === "messages" && options.inferenceLogPath) {
|
|
10936
11023
|
const provider = route ? route.providerId ?? route.aliasId.split(":")[1] ?? "unknown" : "anthropic";
|
|
10937
11024
|
writeInferenceRequestLog(options.inferenceLogPath, {
|
|
@@ -10957,13 +11044,22 @@ async function startHttpProxy(options) {
|
|
|
10957
11044
|
});
|
|
10958
11045
|
}
|
|
10959
11046
|
if (route && adapter) {
|
|
10960
|
-
await forwardToAdapter(
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
11047
|
+
await forwardToAdapter(
|
|
11048
|
+
req,
|
|
11049
|
+
res,
|
|
11050
|
+
adapterBody,
|
|
11051
|
+
adapter,
|
|
11052
|
+
options.adapterRequest,
|
|
11053
|
+
messagesEndpoint === "messages" && options.inferenceLogPath ? {
|
|
11054
|
+
logPath: options.inferenceLogPath,
|
|
11055
|
+
requestId,
|
|
11056
|
+
claudeSessionId,
|
|
11057
|
+
modelId: typeof parsed?.model === "string" ? parsed.model : "unknown",
|
|
11058
|
+
provider: route.providerId ?? route.aliasId.split(":")[1] ?? "unknown",
|
|
11059
|
+
progressIntervalMs: options.responseProgressIntervalMs ?? INFERENCE_PROGRESS_INTERVAL_MS
|
|
11060
|
+
} : void 0,
|
|
11061
|
+
() => shuttingDown
|
|
11062
|
+
);
|
|
10967
11063
|
return;
|
|
10968
11064
|
}
|
|
10969
11065
|
await forwardRawAnthropicRequest(
|
|
@@ -10983,6 +11079,7 @@ async function startHttpProxy(options) {
|
|
|
10983
11079
|
messagesEndpoint === "messages" && options.inferenceLogPath ? (usage) => writeInferenceResponseLifecycleLog(options.inferenceLogPath, {
|
|
10984
11080
|
event: "response_usage",
|
|
10985
11081
|
requestId,
|
|
11082
|
+
claudeSessionId,
|
|
10986
11083
|
modelId: typeof parsed?.model === "string" ? parsed.model : "unknown",
|
|
10987
11084
|
provider: "anthropic",
|
|
10988
11085
|
route: "passthrough",
|
|
@@ -10991,10 +11088,12 @@ async function startHttpProxy(options) {
|
|
|
10991
11088
|
messagesEndpoint === "messages" && options.inferenceLogPath ? {
|
|
10992
11089
|
logPath: options.inferenceLogPath,
|
|
10993
11090
|
requestId,
|
|
11091
|
+
claudeSessionId,
|
|
10994
11092
|
modelId: typeof parsed?.model === "string" ? parsed.model : "unknown",
|
|
10995
11093
|
provider: "anthropic",
|
|
10996
11094
|
progressIntervalMs: options.responseProgressIntervalMs ?? INFERENCE_PROGRESS_INTERVAL_MS
|
|
10997
|
-
} : void 0
|
|
11095
|
+
} : void 0,
|
|
11096
|
+
() => shuttingDown
|
|
10998
11097
|
);
|
|
10999
11098
|
return;
|
|
11000
11099
|
}
|
|
@@ -11072,6 +11171,7 @@ async function startHttpProxy(options) {
|
|
|
11072
11171
|
inferenceLogPath: options.inferenceLogPath,
|
|
11073
11172
|
webSocketDiagnosticsLogPath: options.webSocketDiagnosticsLogPath,
|
|
11074
11173
|
close: async () => {
|
|
11174
|
+
shuttingDown = true;
|
|
11075
11175
|
for (const socket of sockets) socket.destroy();
|
|
11076
11176
|
await new Promise((resolve2) => proxyServer.close(() => resolve2()));
|
|
11077
11177
|
mitmServer.close();
|
|
@@ -11139,18 +11239,40 @@ function reportSkippedHttpProxyFavorites(loaded) {
|
|
|
11139
11239
|
);
|
|
11140
11240
|
}
|
|
11141
11241
|
}
|
|
11142
|
-
|
|
11143
|
-
|
|
11144
|
-
const handle = await startHttpProxy({
|
|
11242
|
+
function buildConfiguredHttpProxyOptions(loaded, port, debug = false, inferenceLogPath = getInferenceRequestLogPath(), debugLogPath, webSocketDiagnosticsLogPath) {
|
|
11243
|
+
return {
|
|
11145
11244
|
host: "127.0.0.1",
|
|
11146
11245
|
port,
|
|
11147
11246
|
routes: loaded.routes,
|
|
11148
11247
|
modelAliases: loaded.aliases,
|
|
11248
|
+
reservedModelIds: loaded.unavailableAliases.map((alias) => alias.name),
|
|
11149
11249
|
debug,
|
|
11150
11250
|
debugLogPath,
|
|
11151
11251
|
inferenceLogPath,
|
|
11152
11252
|
webSocketDiagnosticsLogPath
|
|
11153
|
-
}
|
|
11253
|
+
};
|
|
11254
|
+
}
|
|
11255
|
+
function formatHttpProxyEnvironmentLines(handle, baseEnv = process.env) {
|
|
11256
|
+
const env = { ...baseEnv };
|
|
11257
|
+
const hadNoProxy = env["NO_PROXY"] !== void 0 || env["no_proxy"] !== void 0;
|
|
11258
|
+
removeAnthropicProxyBypass(env);
|
|
11259
|
+
return [
|
|
11260
|
+
` HTTPS_PROXY=http://127.0.0.1:${handle.port}`,
|
|
11261
|
+
` HTTP_PROXY=http://127.0.0.1:${handle.port}`,
|
|
11262
|
+
` NODE_EXTRA_CA_CERTS=${handle.caCertPath}`,
|
|
11263
|
+
...hadNoProxy ? [` NO_PROXY=${env["NO_PROXY"] ?? ""}`, ` no_proxy=${env["no_proxy"] ?? ""}`] : []
|
|
11264
|
+
];
|
|
11265
|
+
}
|
|
11266
|
+
async function startConfiguredHttpProxy(port, debug = false, inferenceLogPath = getInferenceRequestLogPath(), debugLogPath, webSocketDiagnosticsLogPath) {
|
|
11267
|
+
const loaded = await loadHttpProxyRoutes();
|
|
11268
|
+
const handle = await startHttpProxy(buildConfiguredHttpProxyOptions(
|
|
11269
|
+
loaded,
|
|
11270
|
+
port,
|
|
11271
|
+
debug,
|
|
11272
|
+
inferenceLogPath,
|
|
11273
|
+
debugLogPath,
|
|
11274
|
+
webSocketDiagnosticsLogPath
|
|
11275
|
+
));
|
|
11154
11276
|
handle.caCertPath = ensureHttpProxyCaBundle(
|
|
11155
11277
|
handle.caCertPath,
|
|
11156
11278
|
process.env["NODE_EXTRA_CA_CERTS"]
|
|
@@ -11194,9 +11316,7 @@ async function runHttpProxyServerCommand(debug = false, webSocketDiagnostics = f
|
|
|
11194
11316
|
});
|
|
11195
11317
|
console.log("");
|
|
11196
11318
|
console.log(pc9.bold(pc9.green("clodex proxy-mode server running")));
|
|
11197
|
-
console.log(
|
|
11198
|
-
console.log(` HTTP_PROXY=http://127.0.0.1:${handle.port}`);
|
|
11199
|
-
console.log(` NODE_EXTRA_CA_CERTS=${handle.caCertPath}`);
|
|
11319
|
+
for (const line of formatHttpProxyEnvironmentLines(handle)) console.log(line);
|
|
11200
11320
|
console.log(` Request log: ${handle.inferenceLogPath}`);
|
|
11201
11321
|
if (handle.webSocketDiagnosticsLogPath) {
|
|
11202
11322
|
console.log(` WebSocket diagnostics: ${handle.webSocketDiagnosticsLogPath}`);
|
|
@@ -12824,10 +12944,18 @@ function printHelp(text4) {
|
|
|
12824
12944
|
${text4}
|
|
12825
12945
|
`);
|
|
12826
12946
|
}
|
|
12827
|
-
async function launchClaudeViaCatalog(catalogRoutes, startingRoute, contextWindow, trace, claudeArgs) {
|
|
12947
|
+
async function launchClaudeViaCatalog(catalogRoutes, startingRoute, modelAliases, contextWindow, trace, claudeArgs) {
|
|
12828
12948
|
let proxyHandle;
|
|
12829
12949
|
try {
|
|
12830
|
-
proxyHandle = await startProxyCatalog(
|
|
12950
|
+
proxyHandle = await startProxyCatalog(
|
|
12951
|
+
catalogRoutes,
|
|
12952
|
+
startingRoute.aliasId,
|
|
12953
|
+
trace,
|
|
12954
|
+
void 0,
|
|
12955
|
+
void 0,
|
|
12956
|
+
void 0,
|
|
12957
|
+
modelAliases
|
|
12958
|
+
);
|
|
12831
12959
|
p12.log.info(
|
|
12832
12960
|
`Switch menu active \u2014 proxy on port ${proxyHandle.port} ` + pc13.dim(`(${catalogRoutes.length} model${catalogRoutes.length !== 1 ? "s" : ""} in /model)`)
|
|
12833
12961
|
);
|
|
@@ -13380,6 +13508,7 @@ Error: ${launchPlan.error}
|
|
|
13380
13508
|
return launchClaudeViaCatalog(
|
|
13381
13509
|
catalogRoutes,
|
|
13382
13510
|
startingRoute,
|
|
13511
|
+
resolveCatalogModelAliases(prefs.modelAliases ?? [], resolveRoute),
|
|
13383
13512
|
selectedModel.contextWindow,
|
|
13384
13513
|
trace,
|
|
13385
13514
|
claudeArgs
|