@blockrun/clawrouter 0.12.253 → 0.12.255
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/cli.js +31 -16
- package/dist/index.js +31 -16
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -90441,7 +90441,7 @@ async function startProxy(options) {
|
|
|
90441
90441
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90442
90442
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
90443
90443
|
try {
|
|
90444
|
-
const imgResp = await fetch(img.url);
|
|
90444
|
+
const imgResp = await fetch(img.url, { signal: clientAbort.signal });
|
|
90445
90445
|
if (imgResp.ok) {
|
|
90446
90446
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
90447
90447
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
@@ -90523,6 +90523,7 @@ async function startProxy(options) {
|
|
|
90523
90523
|
img2imgCost = estimateImageCost(img2imgModel, parsed.size, parsed.n || 1);
|
|
90524
90524
|
reqBody = JSON.stringify(parsed);
|
|
90525
90525
|
} catch (parseErr) {
|
|
90526
|
+
if (clientAbort.signal.aborted) return;
|
|
90526
90527
|
const msg = parseErr instanceof Error ? parseErr.message : String(parseErr);
|
|
90527
90528
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
90528
90529
|
res.end(JSON.stringify({ error: "Invalid request", details: msg }));
|
|
@@ -90563,7 +90564,7 @@ async function startProxy(options) {
|
|
|
90563
90564
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90564
90565
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
90565
90566
|
try {
|
|
90566
|
-
const imgResp = await fetch(img.url);
|
|
90567
|
+
const imgResp = await fetch(img.url, { signal: clientAbort.signal });
|
|
90567
90568
|
if (imgResp.ok) {
|
|
90568
90569
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
90569
90570
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
@@ -90809,7 +90810,7 @@ async function startProxy(options) {
|
|
|
90809
90810
|
for (const clip of finalResult.data) {
|
|
90810
90811
|
if (clip.url?.startsWith("https://") || clip.url?.startsWith("http://")) {
|
|
90811
90812
|
try {
|
|
90812
|
-
const videoResp = await fetch(clip.url);
|
|
90813
|
+
const videoResp = await fetch(clip.url, { signal: clientAbort.signal });
|
|
90813
90814
|
if (videoResp.ok) {
|
|
90814
90815
|
const contentType = videoResp.headers.get("content-type") ?? "video/mp4";
|
|
90815
90816
|
const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
|
|
@@ -91428,6 +91429,10 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91428
91429
|
console.log(
|
|
91429
91430
|
`[ClawRouter] /imagegen command \u2192 ${imageModel} (${imageSize}): ${imagePrompt.slice(0, 80)}...`
|
|
91430
91431
|
);
|
|
91432
|
+
const imagegenAbort = new AbortController();
|
|
91433
|
+
res.on("close", () => {
|
|
91434
|
+
if (!res.writableEnded) imagegenAbort.abort();
|
|
91435
|
+
});
|
|
91431
91436
|
try {
|
|
91432
91437
|
const imageUpstreamUrl = `${apiBase}/v1/images/generations`;
|
|
91433
91438
|
const imageBody = JSON.stringify({
|
|
@@ -91436,10 +91441,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91436
91441
|
size: imageSize,
|
|
91437
91442
|
n: 1
|
|
91438
91443
|
});
|
|
91439
|
-
const imagegenAbort = new AbortController();
|
|
91440
|
-
res.on("close", () => {
|
|
91441
|
-
if (!res.writableEnded) imagegenAbort.abort();
|
|
91442
|
-
});
|
|
91443
91444
|
const imageResponse = await payFetch(imageUpstreamUrl, {
|
|
91444
91445
|
method: "POST",
|
|
91445
91446
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
@@ -91581,6 +91582,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91581
91582
|
);
|
|
91582
91583
|
}
|
|
91583
91584
|
} catch (err) {
|
|
91585
|
+
if (imagegenAbort.signal.aborted) return;
|
|
91584
91586
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
91585
91587
|
console.error(`[ClawRouter] /imagegen error: ${errMsg}`);
|
|
91586
91588
|
if (!res.headersSent) {
|
|
@@ -92320,13 +92322,16 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
92320
92322
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
92321
92323
|
const globalController = new AbortController();
|
|
92322
92324
|
const timeoutId = setTimeout(() => globalController.abort(), timeoutMs);
|
|
92325
|
+
const clientDisconnected = () => res.destroyed && !res.writableEnded;
|
|
92326
|
+
const abortError = () => clientDisconnected() ? new ClientDisconnectedError() : new Error(`Request timed out after ${timeoutMs}ms`);
|
|
92323
92327
|
const onClientClose = () => {
|
|
92324
|
-
if (!globalController.signal.aborted) {
|
|
92328
|
+
if (!res.writableEnded && !globalController.signal.aborted) {
|
|
92325
92329
|
console.log(`[ClawRouter] Client disconnected \u2014 aborting upstream request`);
|
|
92326
92330
|
globalController.abort();
|
|
92327
92331
|
}
|
|
92328
92332
|
};
|
|
92329
|
-
|
|
92333
|
+
res.on("close", onClientClose);
|
|
92334
|
+
if (res.destroyed) onClientClose();
|
|
92330
92335
|
try {
|
|
92331
92336
|
let modelsToTry;
|
|
92332
92337
|
const excludeList = options.excludeModels ?? loadExcludeList();
|
|
@@ -92385,7 +92390,7 @@ data: [DONE]
|
|
|
92385
92390
|
completed = true;
|
|
92386
92391
|
deduplicator.removeInflight(dedupKey);
|
|
92387
92392
|
clearTimeout(timeoutId);
|
|
92388
|
-
|
|
92393
|
+
res.removeListener("close", onClientClose);
|
|
92389
92394
|
return;
|
|
92390
92395
|
}
|
|
92391
92396
|
const contextExcluded = fullChain.filter((m) => !contextFiltered.includes(m));
|
|
@@ -92484,7 +92489,7 @@ data: [DONE]
|
|
|
92484
92489
|
}
|
|
92485
92490
|
deduplicator.removeInflight(dedupKey);
|
|
92486
92491
|
clearTimeout(timeoutId);
|
|
92487
|
-
|
|
92492
|
+
res.removeListener("close", onClientClose);
|
|
92488
92493
|
return;
|
|
92489
92494
|
}
|
|
92490
92495
|
if (excluded.length > 0) {
|
|
@@ -92515,7 +92520,7 @@ data: [DONE]
|
|
|
92515
92520
|
const tryModel = modelsToTry[i];
|
|
92516
92521
|
const isLastAttempt = i === modelsToTry.length - 1;
|
|
92517
92522
|
if (globalController.signal.aborted) {
|
|
92518
|
-
throw
|
|
92523
|
+
throw abortError();
|
|
92519
92524
|
}
|
|
92520
92525
|
console.log(`[ClawRouter] Trying model ${i + 1}/${modelsToTry.length}: ${tryModel}`);
|
|
92521
92526
|
const perAttemptTimeoutMs = timeoutForModel(tryModel);
|
|
@@ -92535,7 +92540,7 @@ data: [DONE]
|
|
|
92535
92540
|
);
|
|
92536
92541
|
clearTimeout(modelTimeoutId);
|
|
92537
92542
|
if (globalController.signal.aborted) {
|
|
92538
|
-
throw
|
|
92543
|
+
throw abortError();
|
|
92539
92544
|
}
|
|
92540
92545
|
if (!result.success && modelController.signal.aborted && !isLastAttempt) {
|
|
92541
92546
|
console.log(
|
|
@@ -92747,7 +92752,7 @@ data: [DONE]
|
|
|
92747
92752
|
break;
|
|
92748
92753
|
}
|
|
92749
92754
|
clearTimeout(timeoutId);
|
|
92750
|
-
|
|
92755
|
+
res.removeListener("close", onClientClose);
|
|
92751
92756
|
if (heartbeatInterval) {
|
|
92752
92757
|
clearInterval(heartbeatInterval);
|
|
92753
92758
|
heartbeatInterval = void 0;
|
|
@@ -93250,12 +93255,16 @@ data: [DONE]
|
|
|
93250
93255
|
completed = true;
|
|
93251
93256
|
} catch (err) {
|
|
93252
93257
|
clearTimeout(timeoutId);
|
|
93253
|
-
|
|
93258
|
+
res.removeListener("close", onClientClose);
|
|
93254
93259
|
if (heartbeatInterval) {
|
|
93255
93260
|
clearInterval(heartbeatInterval);
|
|
93256
93261
|
heartbeatInterval = void 0;
|
|
93257
93262
|
}
|
|
93258
93263
|
deduplicator.removeInflight(dedupKey);
|
|
93264
|
+
if (err instanceof ClientDisconnectedError || err instanceof Error && err.name === "AbortError" && clientDisconnected()) {
|
|
93265
|
+
console.log(`[ClawRouter] Request cancelled \u2014 client disconnected`);
|
|
93266
|
+
return;
|
|
93267
|
+
}
|
|
93259
93268
|
balanceMonitor.invalidate();
|
|
93260
93269
|
if (err instanceof Error && err.name === "AbortError") {
|
|
93261
93270
|
throw new Error(`Request timed out after ${timeoutMs}ms`, { cause: err });
|
|
@@ -93311,7 +93320,7 @@ data: [DONE]
|
|
|
93311
93320
|
});
|
|
93312
93321
|
}
|
|
93313
93322
|
}
|
|
93314
|
-
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
93323
|
+
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
93315
93324
|
var init_proxy = __esm({
|
|
93316
93325
|
"src/proxy.ts"() {
|
|
93317
93326
|
"use strict";
|
|
@@ -93391,6 +93400,12 @@ var init_proxy = __esm({
|
|
|
93391
93400
|
PORT_RETRY_DELAY_MS = 1e3;
|
|
93392
93401
|
MODEL_BODY_READ_TIMEOUT_MS = 3e5;
|
|
93393
93402
|
ERROR_BODY_READ_TIMEOUT_MS = 3e4;
|
|
93403
|
+
ClientDisconnectedError = class extends Error {
|
|
93404
|
+
constructor() {
|
|
93405
|
+
super("Client disconnected");
|
|
93406
|
+
this.name = "ClientDisconnectedError";
|
|
93407
|
+
}
|
|
93408
|
+
};
|
|
93394
93409
|
rateLimitedModels = /* @__PURE__ */ new Map();
|
|
93395
93410
|
overloadedModels = /* @__PURE__ */ new Map();
|
|
93396
93411
|
perProviderErrors = /* @__PURE__ */ new Map();
|
package/dist/index.js
CHANGED
|
@@ -90261,7 +90261,7 @@ async function startProxy(options) {
|
|
|
90261
90261
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90262
90262
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
90263
90263
|
try {
|
|
90264
|
-
const imgResp = await fetch(img.url);
|
|
90264
|
+
const imgResp = await fetch(img.url, { signal: clientAbort.signal });
|
|
90265
90265
|
if (imgResp.ok) {
|
|
90266
90266
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
90267
90267
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
@@ -90343,6 +90343,7 @@ async function startProxy(options) {
|
|
|
90343
90343
|
img2imgCost = estimateImageCost(img2imgModel, parsed.size, parsed.n || 1);
|
|
90344
90344
|
reqBody = JSON.stringify(parsed);
|
|
90345
90345
|
} catch (parseErr) {
|
|
90346
|
+
if (clientAbort.signal.aborted) return;
|
|
90346
90347
|
const msg = parseErr instanceof Error ? parseErr.message : String(parseErr);
|
|
90347
90348
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
90348
90349
|
res.end(JSON.stringify({ error: "Invalid request", details: msg }));
|
|
@@ -90383,7 +90384,7 @@ async function startProxy(options) {
|
|
|
90383
90384
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90384
90385
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
90385
90386
|
try {
|
|
90386
|
-
const imgResp = await fetch(img.url);
|
|
90387
|
+
const imgResp = await fetch(img.url, { signal: clientAbort.signal });
|
|
90387
90388
|
if (imgResp.ok) {
|
|
90388
90389
|
const contentType = imgResp.headers.get("content-type") ?? "image/png";
|
|
90389
90390
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
@@ -90629,7 +90630,7 @@ async function startProxy(options) {
|
|
|
90629
90630
|
for (const clip of finalResult.data) {
|
|
90630
90631
|
if (clip.url?.startsWith("https://") || clip.url?.startsWith("http://")) {
|
|
90631
90632
|
try {
|
|
90632
|
-
const videoResp = await fetch(clip.url);
|
|
90633
|
+
const videoResp = await fetch(clip.url, { signal: clientAbort.signal });
|
|
90633
90634
|
if (videoResp.ok) {
|
|
90634
90635
|
const contentType = videoResp.headers.get("content-type") ?? "video/mp4";
|
|
90635
90636
|
const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
|
|
@@ -91248,6 +91249,10 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91248
91249
|
console.log(
|
|
91249
91250
|
`[ClawRouter] /imagegen command \u2192 ${imageModel} (${imageSize}): ${imagePrompt.slice(0, 80)}...`
|
|
91250
91251
|
);
|
|
91252
|
+
const imagegenAbort = new AbortController();
|
|
91253
|
+
res.on("close", () => {
|
|
91254
|
+
if (!res.writableEnded) imagegenAbort.abort();
|
|
91255
|
+
});
|
|
91251
91256
|
try {
|
|
91252
91257
|
const imageUpstreamUrl = `${apiBase}/v1/images/generations`;
|
|
91253
91258
|
const imageBody = JSON.stringify({
|
|
@@ -91256,10 +91261,6 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91256
91261
|
size: imageSize,
|
|
91257
91262
|
n: 1
|
|
91258
91263
|
});
|
|
91259
|
-
const imagegenAbort = new AbortController();
|
|
91260
|
-
res.on("close", () => {
|
|
91261
|
-
if (!res.writableEnded) imagegenAbort.abort();
|
|
91262
|
-
});
|
|
91263
91264
|
const imageResponse = await payFetch(imageUpstreamUrl, {
|
|
91264
91265
|
method: "POST",
|
|
91265
91266
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
@@ -91401,6 +91402,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91401
91402
|
);
|
|
91402
91403
|
}
|
|
91403
91404
|
} catch (err) {
|
|
91405
|
+
if (imagegenAbort.signal.aborted) return;
|
|
91404
91406
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
91405
91407
|
console.error(`[ClawRouter] /imagegen error: ${errMsg}`);
|
|
91406
91408
|
if (!res.headersSent) {
|
|
@@ -92140,13 +92142,16 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
92140
92142
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
92141
92143
|
const globalController = new AbortController();
|
|
92142
92144
|
const timeoutId = setTimeout(() => globalController.abort(), timeoutMs);
|
|
92145
|
+
const clientDisconnected = () => res.destroyed && !res.writableEnded;
|
|
92146
|
+
const abortError = () => clientDisconnected() ? new ClientDisconnectedError() : new Error(`Request timed out after ${timeoutMs}ms`);
|
|
92143
92147
|
const onClientClose = () => {
|
|
92144
|
-
if (!globalController.signal.aborted) {
|
|
92148
|
+
if (!res.writableEnded && !globalController.signal.aborted) {
|
|
92145
92149
|
console.log(`[ClawRouter] Client disconnected \u2014 aborting upstream request`);
|
|
92146
92150
|
globalController.abort();
|
|
92147
92151
|
}
|
|
92148
92152
|
};
|
|
92149
|
-
|
|
92153
|
+
res.on("close", onClientClose);
|
|
92154
|
+
if (res.destroyed) onClientClose();
|
|
92150
92155
|
try {
|
|
92151
92156
|
let modelsToTry;
|
|
92152
92157
|
const excludeList = options.excludeModels ?? loadExcludeList();
|
|
@@ -92205,7 +92210,7 @@ data: [DONE]
|
|
|
92205
92210
|
completed = true;
|
|
92206
92211
|
deduplicator.removeInflight(dedupKey);
|
|
92207
92212
|
clearTimeout(timeoutId);
|
|
92208
|
-
|
|
92213
|
+
res.removeListener("close", onClientClose);
|
|
92209
92214
|
return;
|
|
92210
92215
|
}
|
|
92211
92216
|
const contextExcluded = fullChain.filter((m) => !contextFiltered.includes(m));
|
|
@@ -92304,7 +92309,7 @@ data: [DONE]
|
|
|
92304
92309
|
}
|
|
92305
92310
|
deduplicator.removeInflight(dedupKey);
|
|
92306
92311
|
clearTimeout(timeoutId);
|
|
92307
|
-
|
|
92312
|
+
res.removeListener("close", onClientClose);
|
|
92308
92313
|
return;
|
|
92309
92314
|
}
|
|
92310
92315
|
if (excluded.length > 0) {
|
|
@@ -92335,7 +92340,7 @@ data: [DONE]
|
|
|
92335
92340
|
const tryModel = modelsToTry[i];
|
|
92336
92341
|
const isLastAttempt = i === modelsToTry.length - 1;
|
|
92337
92342
|
if (globalController.signal.aborted) {
|
|
92338
|
-
throw
|
|
92343
|
+
throw abortError();
|
|
92339
92344
|
}
|
|
92340
92345
|
console.log(`[ClawRouter] Trying model ${i + 1}/${modelsToTry.length}: ${tryModel}`);
|
|
92341
92346
|
const perAttemptTimeoutMs = timeoutForModel(tryModel);
|
|
@@ -92355,7 +92360,7 @@ data: [DONE]
|
|
|
92355
92360
|
);
|
|
92356
92361
|
clearTimeout(modelTimeoutId);
|
|
92357
92362
|
if (globalController.signal.aborted) {
|
|
92358
|
-
throw
|
|
92363
|
+
throw abortError();
|
|
92359
92364
|
}
|
|
92360
92365
|
if (!result.success && modelController.signal.aborted && !isLastAttempt) {
|
|
92361
92366
|
console.log(
|
|
@@ -92567,7 +92572,7 @@ data: [DONE]
|
|
|
92567
92572
|
break;
|
|
92568
92573
|
}
|
|
92569
92574
|
clearTimeout(timeoutId);
|
|
92570
|
-
|
|
92575
|
+
res.removeListener("close", onClientClose);
|
|
92571
92576
|
if (heartbeatInterval) {
|
|
92572
92577
|
clearInterval(heartbeatInterval);
|
|
92573
92578
|
heartbeatInterval = void 0;
|
|
@@ -93070,12 +93075,16 @@ data: [DONE]
|
|
|
93070
93075
|
completed = true;
|
|
93071
93076
|
} catch (err) {
|
|
93072
93077
|
clearTimeout(timeoutId);
|
|
93073
|
-
|
|
93078
|
+
res.removeListener("close", onClientClose);
|
|
93074
93079
|
if (heartbeatInterval) {
|
|
93075
93080
|
clearInterval(heartbeatInterval);
|
|
93076
93081
|
heartbeatInterval = void 0;
|
|
93077
93082
|
}
|
|
93078
93083
|
deduplicator.removeInflight(dedupKey);
|
|
93084
|
+
if (err instanceof ClientDisconnectedError || err instanceof Error && err.name === "AbortError" && clientDisconnected()) {
|
|
93085
|
+
console.log(`[ClawRouter] Request cancelled \u2014 client disconnected`);
|
|
93086
|
+
return;
|
|
93087
|
+
}
|
|
93079
93088
|
balanceMonitor.invalidate();
|
|
93080
93089
|
if (err instanceof Error && err.name === "AbortError") {
|
|
93081
93090
|
throw new Error(`Request timed out after ${timeoutMs}ms`, { cause: err });
|
|
@@ -93131,7 +93140,7 @@ data: [DONE]
|
|
|
93131
93140
|
});
|
|
93132
93141
|
}
|
|
93133
93142
|
}
|
|
93134
|
-
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
93143
|
+
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
93135
93144
|
var init_proxy = __esm({
|
|
93136
93145
|
"src/proxy.ts"() {
|
|
93137
93146
|
"use strict";
|
|
@@ -93211,6 +93220,12 @@ var init_proxy = __esm({
|
|
|
93211
93220
|
PORT_RETRY_DELAY_MS = 1e3;
|
|
93212
93221
|
MODEL_BODY_READ_TIMEOUT_MS = 3e5;
|
|
93213
93222
|
ERROR_BODY_READ_TIMEOUT_MS = 3e4;
|
|
93223
|
+
ClientDisconnectedError = class extends Error {
|
|
93224
|
+
constructor() {
|
|
93225
|
+
super("Client disconnected");
|
|
93226
|
+
this.name = "ClientDisconnectedError";
|
|
93227
|
+
}
|
|
93228
|
+
};
|
|
93214
93229
|
rateLimitedModels = /* @__PURE__ */ new Map();
|
|
93215
93230
|
overloadedModels = /* @__PURE__ */ new Map();
|
|
93216
93231
|
perProviderErrors = /* @__PURE__ */ new Map();
|
package/package.json
CHANGED