@blockrun/clawrouter 0.12.252 → 0.12.254
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 +37 -12
- package/dist/index.js +37 -12
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -90607,6 +90607,10 @@ async function startProxy(options) {
|
|
|
90607
90607
|
}
|
|
90608
90608
|
if (req.url === "/v1/audio/generations" && req.method === "POST") {
|
|
90609
90609
|
const audioStartTime = Date.now();
|
|
90610
|
+
const clientAbort = new AbortController();
|
|
90611
|
+
res.on("close", () => {
|
|
90612
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
90613
|
+
});
|
|
90610
90614
|
const chunks = [];
|
|
90611
90615
|
for await (const chunk of req) {
|
|
90612
90616
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -90622,7 +90626,8 @@ async function startProxy(options) {
|
|
|
90622
90626
|
const upstream = await payFetch(`${apiBase}/v1/audio/generations`, {
|
|
90623
90627
|
method: "POST",
|
|
90624
90628
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
90625
|
-
body: reqBody
|
|
90629
|
+
body: reqBody,
|
|
90630
|
+
signal: clientAbort.signal
|
|
90626
90631
|
});
|
|
90627
90632
|
const text = await upstream.text();
|
|
90628
90633
|
if (!upstream.ok) {
|
|
@@ -90644,7 +90649,7 @@ async function startProxy(options) {
|
|
|
90644
90649
|
for (const track of result.data) {
|
|
90645
90650
|
if (track.url?.startsWith("https://") || track.url?.startsWith("http://")) {
|
|
90646
90651
|
try {
|
|
90647
|
-
const audioResp = await fetch(track.url);
|
|
90652
|
+
const audioResp = await fetch(track.url, { signal: clientAbort.signal });
|
|
90648
90653
|
if (audioResp.ok) {
|
|
90649
90654
|
const contentType = audioResp.headers.get("content-type") ?? "audio/mpeg";
|
|
90650
90655
|
const ext = contentType.includes("wav") ? "wav" : "mp3";
|
|
@@ -90676,6 +90681,7 @@ async function startProxy(options) {
|
|
|
90676
90681
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
90677
90682
|
res.end(JSON.stringify(result));
|
|
90678
90683
|
} catch (err) {
|
|
90684
|
+
if (clientAbort.signal.aborted) return;
|
|
90679
90685
|
const msg = err instanceof Error ? err.message : String(err);
|
|
90680
90686
|
console.error(`[ClawRouter] Audio generation error: ${msg}`);
|
|
90681
90687
|
if (!res.headersSent) {
|
|
@@ -91695,6 +91701,10 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91695
91701
|
console.log(
|
|
91696
91702
|
`[ClawRouter] /img2img \u2192 ${img2imgModel} (${img2imgSize}): ${img2imgPrompt.slice(0, 80)}`
|
|
91697
91703
|
);
|
|
91704
|
+
const img2imgAbort = new AbortController();
|
|
91705
|
+
res.on("close", () => {
|
|
91706
|
+
if (!res.writableEnded) img2imgAbort.abort();
|
|
91707
|
+
});
|
|
91698
91708
|
try {
|
|
91699
91709
|
const img2imgBody = JSON.stringify({
|
|
91700
91710
|
model: img2imgModel,
|
|
@@ -91707,7 +91717,8 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91707
91717
|
const img2imgResponse = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
91708
91718
|
method: "POST",
|
|
91709
91719
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
91710
|
-
body: img2imgBody
|
|
91720
|
+
body: img2imgBody,
|
|
91721
|
+
signal: img2imgAbort.signal
|
|
91711
91722
|
});
|
|
91712
91723
|
const img2imgResult = await img2imgResponse.json();
|
|
91713
91724
|
let responseText;
|
|
@@ -91757,6 +91768,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91757
91768
|
}
|
|
91758
91769
|
sendImg2ImgText(responseText);
|
|
91759
91770
|
} catch (err) {
|
|
91771
|
+
if (img2imgAbort.signal.aborted) return;
|
|
91760
91772
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
91761
91773
|
console.error(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
91762
91774
|
if (!res.headersSent) {
|
|
@@ -92308,13 +92320,16 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
92308
92320
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
92309
92321
|
const globalController = new AbortController();
|
|
92310
92322
|
const timeoutId = setTimeout(() => globalController.abort(), timeoutMs);
|
|
92323
|
+
const clientDisconnected = () => res.destroyed && !res.writableEnded;
|
|
92324
|
+
const abortError = () => clientDisconnected() ? new ClientDisconnectedError() : new Error(`Request timed out after ${timeoutMs}ms`);
|
|
92311
92325
|
const onClientClose = () => {
|
|
92312
|
-
if (!globalController.signal.aborted) {
|
|
92326
|
+
if (!res.writableEnded && !globalController.signal.aborted) {
|
|
92313
92327
|
console.log(`[ClawRouter] Client disconnected \u2014 aborting upstream request`);
|
|
92314
92328
|
globalController.abort();
|
|
92315
92329
|
}
|
|
92316
92330
|
};
|
|
92317
|
-
|
|
92331
|
+
res.on("close", onClientClose);
|
|
92332
|
+
if (res.destroyed) onClientClose();
|
|
92318
92333
|
try {
|
|
92319
92334
|
let modelsToTry;
|
|
92320
92335
|
const excludeList = options.excludeModels ?? loadExcludeList();
|
|
@@ -92373,7 +92388,7 @@ data: [DONE]
|
|
|
92373
92388
|
completed = true;
|
|
92374
92389
|
deduplicator.removeInflight(dedupKey);
|
|
92375
92390
|
clearTimeout(timeoutId);
|
|
92376
|
-
|
|
92391
|
+
res.removeListener("close", onClientClose);
|
|
92377
92392
|
return;
|
|
92378
92393
|
}
|
|
92379
92394
|
const contextExcluded = fullChain.filter((m) => !contextFiltered.includes(m));
|
|
@@ -92472,7 +92487,7 @@ data: [DONE]
|
|
|
92472
92487
|
}
|
|
92473
92488
|
deduplicator.removeInflight(dedupKey);
|
|
92474
92489
|
clearTimeout(timeoutId);
|
|
92475
|
-
|
|
92490
|
+
res.removeListener("close", onClientClose);
|
|
92476
92491
|
return;
|
|
92477
92492
|
}
|
|
92478
92493
|
if (excluded.length > 0) {
|
|
@@ -92503,7 +92518,7 @@ data: [DONE]
|
|
|
92503
92518
|
const tryModel = modelsToTry[i];
|
|
92504
92519
|
const isLastAttempt = i === modelsToTry.length - 1;
|
|
92505
92520
|
if (globalController.signal.aborted) {
|
|
92506
|
-
throw
|
|
92521
|
+
throw abortError();
|
|
92507
92522
|
}
|
|
92508
92523
|
console.log(`[ClawRouter] Trying model ${i + 1}/${modelsToTry.length}: ${tryModel}`);
|
|
92509
92524
|
const perAttemptTimeoutMs = timeoutForModel(tryModel);
|
|
@@ -92523,7 +92538,7 @@ data: [DONE]
|
|
|
92523
92538
|
);
|
|
92524
92539
|
clearTimeout(modelTimeoutId);
|
|
92525
92540
|
if (globalController.signal.aborted) {
|
|
92526
|
-
throw
|
|
92541
|
+
throw abortError();
|
|
92527
92542
|
}
|
|
92528
92543
|
if (!result.success && modelController.signal.aborted && !isLastAttempt) {
|
|
92529
92544
|
console.log(
|
|
@@ -92735,7 +92750,7 @@ data: [DONE]
|
|
|
92735
92750
|
break;
|
|
92736
92751
|
}
|
|
92737
92752
|
clearTimeout(timeoutId);
|
|
92738
|
-
|
|
92753
|
+
res.removeListener("close", onClientClose);
|
|
92739
92754
|
if (heartbeatInterval) {
|
|
92740
92755
|
clearInterval(heartbeatInterval);
|
|
92741
92756
|
heartbeatInterval = void 0;
|
|
@@ -93238,12 +93253,16 @@ data: [DONE]
|
|
|
93238
93253
|
completed = true;
|
|
93239
93254
|
} catch (err) {
|
|
93240
93255
|
clearTimeout(timeoutId);
|
|
93241
|
-
|
|
93256
|
+
res.removeListener("close", onClientClose);
|
|
93242
93257
|
if (heartbeatInterval) {
|
|
93243
93258
|
clearInterval(heartbeatInterval);
|
|
93244
93259
|
heartbeatInterval = void 0;
|
|
93245
93260
|
}
|
|
93246
93261
|
deduplicator.removeInflight(dedupKey);
|
|
93262
|
+
if (err instanceof ClientDisconnectedError || err instanceof Error && err.name === "AbortError" && clientDisconnected()) {
|
|
93263
|
+
console.log(`[ClawRouter] Request cancelled \u2014 client disconnected`);
|
|
93264
|
+
return;
|
|
93265
|
+
}
|
|
93247
93266
|
balanceMonitor.invalidate();
|
|
93248
93267
|
if (err instanceof Error && err.name === "AbortError") {
|
|
93249
93268
|
throw new Error(`Request timed out after ${timeoutMs}ms`, { cause: err });
|
|
@@ -93299,7 +93318,7 @@ data: [DONE]
|
|
|
93299
93318
|
});
|
|
93300
93319
|
}
|
|
93301
93320
|
}
|
|
93302
|
-
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;
|
|
93321
|
+
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;
|
|
93303
93322
|
var init_proxy = __esm({
|
|
93304
93323
|
"src/proxy.ts"() {
|
|
93305
93324
|
"use strict";
|
|
@@ -93379,6 +93398,12 @@ var init_proxy = __esm({
|
|
|
93379
93398
|
PORT_RETRY_DELAY_MS = 1e3;
|
|
93380
93399
|
MODEL_BODY_READ_TIMEOUT_MS = 3e5;
|
|
93381
93400
|
ERROR_BODY_READ_TIMEOUT_MS = 3e4;
|
|
93401
|
+
ClientDisconnectedError = class extends Error {
|
|
93402
|
+
constructor() {
|
|
93403
|
+
super("Client disconnected");
|
|
93404
|
+
this.name = "ClientDisconnectedError";
|
|
93405
|
+
}
|
|
93406
|
+
};
|
|
93382
93407
|
rateLimitedModels = /* @__PURE__ */ new Map();
|
|
93383
93408
|
overloadedModels = /* @__PURE__ */ new Map();
|
|
93384
93409
|
perProviderErrors = /* @__PURE__ */ new Map();
|
package/dist/index.js
CHANGED
|
@@ -90427,6 +90427,10 @@ async function startProxy(options) {
|
|
|
90427
90427
|
}
|
|
90428
90428
|
if (req.url === "/v1/audio/generations" && req.method === "POST") {
|
|
90429
90429
|
const audioStartTime = Date.now();
|
|
90430
|
+
const clientAbort = new AbortController();
|
|
90431
|
+
res.on("close", () => {
|
|
90432
|
+
if (!res.writableEnded) clientAbort.abort();
|
|
90433
|
+
});
|
|
90430
90434
|
const chunks = [];
|
|
90431
90435
|
for await (const chunk of req) {
|
|
90432
90436
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -90442,7 +90446,8 @@ async function startProxy(options) {
|
|
|
90442
90446
|
const upstream = await payFetch(`${apiBase}/v1/audio/generations`, {
|
|
90443
90447
|
method: "POST",
|
|
90444
90448
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
90445
|
-
body: reqBody
|
|
90449
|
+
body: reqBody,
|
|
90450
|
+
signal: clientAbort.signal
|
|
90446
90451
|
});
|
|
90447
90452
|
const text = await upstream.text();
|
|
90448
90453
|
if (!upstream.ok) {
|
|
@@ -90464,7 +90469,7 @@ async function startProxy(options) {
|
|
|
90464
90469
|
for (const track of result.data) {
|
|
90465
90470
|
if (track.url?.startsWith("https://") || track.url?.startsWith("http://")) {
|
|
90466
90471
|
try {
|
|
90467
|
-
const audioResp = await fetch(track.url);
|
|
90472
|
+
const audioResp = await fetch(track.url, { signal: clientAbort.signal });
|
|
90468
90473
|
if (audioResp.ok) {
|
|
90469
90474
|
const contentType = audioResp.headers.get("content-type") ?? "audio/mpeg";
|
|
90470
90475
|
const ext = contentType.includes("wav") ? "wav" : "mp3";
|
|
@@ -90496,6 +90501,7 @@ async function startProxy(options) {
|
|
|
90496
90501
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
90497
90502
|
res.end(JSON.stringify(result));
|
|
90498
90503
|
} catch (err) {
|
|
90504
|
+
if (clientAbort.signal.aborted) return;
|
|
90499
90505
|
const msg = err instanceof Error ? err.message : String(err);
|
|
90500
90506
|
console.error(`[ClawRouter] Audio generation error: ${msg}`);
|
|
90501
90507
|
if (!res.headersSent) {
|
|
@@ -91515,6 +91521,10 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91515
91521
|
console.log(
|
|
91516
91522
|
`[ClawRouter] /img2img \u2192 ${img2imgModel} (${img2imgSize}): ${img2imgPrompt.slice(0, 80)}`
|
|
91517
91523
|
);
|
|
91524
|
+
const img2imgAbort = new AbortController();
|
|
91525
|
+
res.on("close", () => {
|
|
91526
|
+
if (!res.writableEnded) img2imgAbort.abort();
|
|
91527
|
+
});
|
|
91518
91528
|
try {
|
|
91519
91529
|
const img2imgBody = JSON.stringify({
|
|
91520
91530
|
model: img2imgModel,
|
|
@@ -91527,7 +91537,8 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91527
91537
|
const img2imgResponse = await payFetch(`${apiBase}/v1/images/image2image`, {
|
|
91528
91538
|
method: "POST",
|
|
91529
91539
|
headers: { "content-type": "application/json", "user-agent": USER_AGENT },
|
|
91530
|
-
body: img2imgBody
|
|
91540
|
+
body: img2imgBody,
|
|
91541
|
+
signal: img2imgAbort.signal
|
|
91531
91542
|
});
|
|
91532
91543
|
const img2imgResult = await img2imgResponse.json();
|
|
91533
91544
|
let responseText;
|
|
@@ -91577,6 +91588,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
91577
91588
|
}
|
|
91578
91589
|
sendImg2ImgText(responseText);
|
|
91579
91590
|
} catch (err) {
|
|
91591
|
+
if (img2imgAbort.signal.aborted) return;
|
|
91580
91592
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
91581
91593
|
console.error(`[ClawRouter] /img2img error: ${errMsg}`);
|
|
91582
91594
|
if (!res.headersSent) {
|
|
@@ -92128,13 +92140,16 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
92128
92140
|
const timeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
92129
92141
|
const globalController = new AbortController();
|
|
92130
92142
|
const timeoutId = setTimeout(() => globalController.abort(), timeoutMs);
|
|
92143
|
+
const clientDisconnected = () => res.destroyed && !res.writableEnded;
|
|
92144
|
+
const abortError = () => clientDisconnected() ? new ClientDisconnectedError() : new Error(`Request timed out after ${timeoutMs}ms`);
|
|
92131
92145
|
const onClientClose = () => {
|
|
92132
|
-
if (!globalController.signal.aborted) {
|
|
92146
|
+
if (!res.writableEnded && !globalController.signal.aborted) {
|
|
92133
92147
|
console.log(`[ClawRouter] Client disconnected \u2014 aborting upstream request`);
|
|
92134
92148
|
globalController.abort();
|
|
92135
92149
|
}
|
|
92136
92150
|
};
|
|
92137
|
-
|
|
92151
|
+
res.on("close", onClientClose);
|
|
92152
|
+
if (res.destroyed) onClientClose();
|
|
92138
92153
|
try {
|
|
92139
92154
|
let modelsToTry;
|
|
92140
92155
|
const excludeList = options.excludeModels ?? loadExcludeList();
|
|
@@ -92193,7 +92208,7 @@ data: [DONE]
|
|
|
92193
92208
|
completed = true;
|
|
92194
92209
|
deduplicator.removeInflight(dedupKey);
|
|
92195
92210
|
clearTimeout(timeoutId);
|
|
92196
|
-
|
|
92211
|
+
res.removeListener("close", onClientClose);
|
|
92197
92212
|
return;
|
|
92198
92213
|
}
|
|
92199
92214
|
const contextExcluded = fullChain.filter((m) => !contextFiltered.includes(m));
|
|
@@ -92292,7 +92307,7 @@ data: [DONE]
|
|
|
92292
92307
|
}
|
|
92293
92308
|
deduplicator.removeInflight(dedupKey);
|
|
92294
92309
|
clearTimeout(timeoutId);
|
|
92295
|
-
|
|
92310
|
+
res.removeListener("close", onClientClose);
|
|
92296
92311
|
return;
|
|
92297
92312
|
}
|
|
92298
92313
|
if (excluded.length > 0) {
|
|
@@ -92323,7 +92338,7 @@ data: [DONE]
|
|
|
92323
92338
|
const tryModel = modelsToTry[i];
|
|
92324
92339
|
const isLastAttempt = i === modelsToTry.length - 1;
|
|
92325
92340
|
if (globalController.signal.aborted) {
|
|
92326
|
-
throw
|
|
92341
|
+
throw abortError();
|
|
92327
92342
|
}
|
|
92328
92343
|
console.log(`[ClawRouter] Trying model ${i + 1}/${modelsToTry.length}: ${tryModel}`);
|
|
92329
92344
|
const perAttemptTimeoutMs = timeoutForModel(tryModel);
|
|
@@ -92343,7 +92358,7 @@ data: [DONE]
|
|
|
92343
92358
|
);
|
|
92344
92359
|
clearTimeout(modelTimeoutId);
|
|
92345
92360
|
if (globalController.signal.aborted) {
|
|
92346
|
-
throw
|
|
92361
|
+
throw abortError();
|
|
92347
92362
|
}
|
|
92348
92363
|
if (!result.success && modelController.signal.aborted && !isLastAttempt) {
|
|
92349
92364
|
console.log(
|
|
@@ -92555,7 +92570,7 @@ data: [DONE]
|
|
|
92555
92570
|
break;
|
|
92556
92571
|
}
|
|
92557
92572
|
clearTimeout(timeoutId);
|
|
92558
|
-
|
|
92573
|
+
res.removeListener("close", onClientClose);
|
|
92559
92574
|
if (heartbeatInterval) {
|
|
92560
92575
|
clearInterval(heartbeatInterval);
|
|
92561
92576
|
heartbeatInterval = void 0;
|
|
@@ -93058,12 +93073,16 @@ data: [DONE]
|
|
|
93058
93073
|
completed = true;
|
|
93059
93074
|
} catch (err) {
|
|
93060
93075
|
clearTimeout(timeoutId);
|
|
93061
|
-
|
|
93076
|
+
res.removeListener("close", onClientClose);
|
|
93062
93077
|
if (heartbeatInterval) {
|
|
93063
93078
|
clearInterval(heartbeatInterval);
|
|
93064
93079
|
heartbeatInterval = void 0;
|
|
93065
93080
|
}
|
|
93066
93081
|
deduplicator.removeInflight(dedupKey);
|
|
93082
|
+
if (err instanceof ClientDisconnectedError || err instanceof Error && err.name === "AbortError" && clientDisconnected()) {
|
|
93083
|
+
console.log(`[ClawRouter] Request cancelled \u2014 client disconnected`);
|
|
93084
|
+
return;
|
|
93085
|
+
}
|
|
93067
93086
|
balanceMonitor.invalidate();
|
|
93068
93087
|
if (err instanceof Error && err.name === "AbortError") {
|
|
93069
93088
|
throw new Error(`Request timed out after ${timeoutMs}ms`, { cause: err });
|
|
@@ -93119,7 +93138,7 @@ data: [DONE]
|
|
|
93119
93138
|
});
|
|
93120
93139
|
}
|
|
93121
93140
|
}
|
|
93122
|
-
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;
|
|
93141
|
+
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;
|
|
93123
93142
|
var init_proxy = __esm({
|
|
93124
93143
|
"src/proxy.ts"() {
|
|
93125
93144
|
"use strict";
|
|
@@ -93199,6 +93218,12 @@ var init_proxy = __esm({
|
|
|
93199
93218
|
PORT_RETRY_DELAY_MS = 1e3;
|
|
93200
93219
|
MODEL_BODY_READ_TIMEOUT_MS = 3e5;
|
|
93201
93220
|
ERROR_BODY_READ_TIMEOUT_MS = 3e4;
|
|
93221
|
+
ClientDisconnectedError = class extends Error {
|
|
93222
|
+
constructor() {
|
|
93223
|
+
super("Client disconnected");
|
|
93224
|
+
this.name = "ClientDisconnectedError";
|
|
93225
|
+
}
|
|
93226
|
+
};
|
|
93202
93227
|
rateLimitedModels = /* @__PURE__ */ new Map();
|
|
93203
93228
|
overloadedModels = /* @__PURE__ */ new Map();
|
|
93204
93229
|
perProviderErrors = /* @__PURE__ */ new Map();
|
package/package.json
CHANGED