@blockrun/clawrouter 0.8.11 → 0.8.13
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 +52 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.js +52 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2362,6 +2362,42 @@ var HEALTH_CHECK_TIMEOUT_MS = 2e3;
|
|
|
2362
2362
|
var RATE_LIMIT_COOLDOWN_MS = 6e4;
|
|
2363
2363
|
var PORT_RETRY_ATTEMPTS = 5;
|
|
2364
2364
|
var PORT_RETRY_DELAY_MS = 1e3;
|
|
2365
|
+
function transformPaymentError(errorBody) {
|
|
2366
|
+
try {
|
|
2367
|
+
const parsed = JSON.parse(errorBody);
|
|
2368
|
+
if (parsed.error === "Payment verification failed" && parsed.details) {
|
|
2369
|
+
const match = parsed.details.match(/Verification failed:\s*(\{.*\})/s);
|
|
2370
|
+
if (match) {
|
|
2371
|
+
const innerJson = JSON.parse(match[1]);
|
|
2372
|
+
if (innerJson.invalidReason === "insufficient_funds" && innerJson.invalidMessage) {
|
|
2373
|
+
const balanceMatch = innerJson.invalidMessage.match(
|
|
2374
|
+
/insufficient balance:\s*(\d+)\s*<\s*(\d+)/i
|
|
2375
|
+
);
|
|
2376
|
+
if (balanceMatch) {
|
|
2377
|
+
const currentMicros = parseInt(balanceMatch[1], 10);
|
|
2378
|
+
const requiredMicros = parseInt(balanceMatch[2], 10);
|
|
2379
|
+
const currentUSD = (currentMicros / 1e6).toFixed(6);
|
|
2380
|
+
const requiredUSD = (requiredMicros / 1e6).toFixed(6);
|
|
2381
|
+
const wallet = innerJson.payer || "unknown";
|
|
2382
|
+
const shortWallet = wallet.length > 12 ? `${wallet.slice(0, 6)}...${wallet.slice(-4)}` : wallet;
|
|
2383
|
+
return JSON.stringify({
|
|
2384
|
+
error: {
|
|
2385
|
+
message: `Insufficient USDC balance. Current: $${currentUSD}, Required: ~$${requiredUSD}`,
|
|
2386
|
+
type: "insufficient_funds",
|
|
2387
|
+
wallet,
|
|
2388
|
+
current_balance_usd: currentUSD,
|
|
2389
|
+
required_usd: requiredUSD,
|
|
2390
|
+
help: `Fund wallet ${shortWallet} with USDC on Base, or use free model: /model free`
|
|
2391
|
+
}
|
|
2392
|
+
});
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
} catch {
|
|
2398
|
+
}
|
|
2399
|
+
return errorBody;
|
|
2400
|
+
}
|
|
2365
2401
|
var rateLimitedModels = /* @__PURE__ */ new Map();
|
|
2366
2402
|
function isRateLimited(modelId) {
|
|
2367
2403
|
const hitTime = rateLimitedModels.get(modelId);
|
|
@@ -2606,12 +2642,16 @@ function normalizeMessagesForThinking(messages) {
|
|
|
2606
2642
|
}
|
|
2607
2643
|
var KIMI_BLOCK_RE = /<[||][^<>]*begin[^<>]*[||]>[\s\S]*?<[||][^<>]*end[^<>]*[||]>/gi;
|
|
2608
2644
|
var KIMI_TOKEN_RE = /<[||][^<>]*[||]>/g;
|
|
2645
|
+
var DSML_BLOCK_RE = /<[||]DSML[||][^>]*>[\s\S]*?<\/[||]DSML[||][^>]*>/gi;
|
|
2646
|
+
var DSML_TAG_RE = /<\/?[||]DSML[||][^>]*>/gi;
|
|
2609
2647
|
var THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>/gi;
|
|
2610
2648
|
var THINKING_BLOCK_RE = /<\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
|
|
2611
2649
|
function stripThinkingTokens(content) {
|
|
2612
2650
|
if (!content) return content;
|
|
2613
2651
|
let cleaned = content.replace(KIMI_BLOCK_RE, "");
|
|
2614
2652
|
cleaned = cleaned.replace(KIMI_TOKEN_RE, "");
|
|
2653
|
+
cleaned = cleaned.replace(DSML_BLOCK_RE, "");
|
|
2654
|
+
cleaned = cleaned.replace(DSML_TAG_RE, "");
|
|
2615
2655
|
cleaned = cleaned.replace(THINKING_BLOCK_RE, "");
|
|
2616
2656
|
cleaned = cleaned.replace(THINKING_TAG_RE, "");
|
|
2617
2657
|
return cleaned;
|
|
@@ -3230,10 +3270,18 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3230
3270
|
options.onRouted?.(routingDecision);
|
|
3231
3271
|
}
|
|
3232
3272
|
if (!upstream) {
|
|
3233
|
-
const
|
|
3273
|
+
const rawErrBody = lastError?.body || "All models in fallback chain failed";
|
|
3234
3274
|
const errStatus = lastError?.status || 502;
|
|
3275
|
+
const transformedErr = transformPaymentError(rawErrBody);
|
|
3235
3276
|
if (headersSentEarly) {
|
|
3236
|
-
|
|
3277
|
+
let errPayload;
|
|
3278
|
+
try {
|
|
3279
|
+
const parsed = JSON.parse(transformedErr);
|
|
3280
|
+
errPayload = JSON.stringify(parsed);
|
|
3281
|
+
} catch {
|
|
3282
|
+
errPayload = JSON.stringify({ error: { message: rawErrBody, type: "provider_error", status: errStatus } });
|
|
3283
|
+
}
|
|
3284
|
+
const errEvent = `data: ${errPayload}
|
|
3237
3285
|
|
|
3238
3286
|
`;
|
|
3239
3287
|
safeWrite(res, errEvent);
|
|
@@ -3248,17 +3296,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3248
3296
|
});
|
|
3249
3297
|
} else {
|
|
3250
3298
|
res.writeHead(errStatus, { "Content-Type": "application/json" });
|
|
3251
|
-
res.end(
|
|
3252
|
-
JSON.stringify({
|
|
3253
|
-
error: { message: errBody, type: "provider_error" }
|
|
3254
|
-
})
|
|
3255
|
-
);
|
|
3299
|
+
res.end(transformedErr);
|
|
3256
3300
|
deduplicator.complete(dedupKey, {
|
|
3257
3301
|
status: errStatus,
|
|
3258
3302
|
headers: { "content-type": "application/json" },
|
|
3259
|
-
body: Buffer.from(
|
|
3260
|
-
JSON.stringify({ error: { message: errBody, type: "provider_error" } })
|
|
3261
|
-
),
|
|
3303
|
+
body: Buffer.from(transformedErr),
|
|
3262
3304
|
completedAt: Date.now()
|
|
3263
3305
|
});
|
|
3264
3306
|
}
|