@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 CHANGED
@@ -2223,6 +2223,42 @@ var HEALTH_CHECK_TIMEOUT_MS = 2e3;
2223
2223
  var RATE_LIMIT_COOLDOWN_MS = 6e4;
2224
2224
  var PORT_RETRY_ATTEMPTS = 5;
2225
2225
  var PORT_RETRY_DELAY_MS = 1e3;
2226
+ function transformPaymentError(errorBody) {
2227
+ try {
2228
+ const parsed = JSON.parse(errorBody);
2229
+ if (parsed.error === "Payment verification failed" && parsed.details) {
2230
+ const match = parsed.details.match(/Verification failed:\s*(\{.*\})/s);
2231
+ if (match) {
2232
+ const innerJson = JSON.parse(match[1]);
2233
+ if (innerJson.invalidReason === "insufficient_funds" && innerJson.invalidMessage) {
2234
+ const balanceMatch = innerJson.invalidMessage.match(
2235
+ /insufficient balance:\s*(\d+)\s*<\s*(\d+)/i
2236
+ );
2237
+ if (balanceMatch) {
2238
+ const currentMicros = parseInt(balanceMatch[1], 10);
2239
+ const requiredMicros = parseInt(balanceMatch[2], 10);
2240
+ const currentUSD = (currentMicros / 1e6).toFixed(6);
2241
+ const requiredUSD = (requiredMicros / 1e6).toFixed(6);
2242
+ const wallet = innerJson.payer || "unknown";
2243
+ const shortWallet = wallet.length > 12 ? `${wallet.slice(0, 6)}...${wallet.slice(-4)}` : wallet;
2244
+ return JSON.stringify({
2245
+ error: {
2246
+ message: `Insufficient USDC balance. Current: $${currentUSD}, Required: ~$${requiredUSD}`,
2247
+ type: "insufficient_funds",
2248
+ wallet,
2249
+ current_balance_usd: currentUSD,
2250
+ required_usd: requiredUSD,
2251
+ help: `Fund wallet ${shortWallet} with USDC on Base, or use free model: /model free`
2252
+ }
2253
+ });
2254
+ }
2255
+ }
2256
+ }
2257
+ }
2258
+ } catch {
2259
+ }
2260
+ return errorBody;
2261
+ }
2226
2262
  var rateLimitedModels = /* @__PURE__ */ new Map();
2227
2263
  function isRateLimited(modelId) {
2228
2264
  const hitTime = rateLimitedModels.get(modelId);
@@ -2467,12 +2503,16 @@ function normalizeMessagesForThinking(messages) {
2467
2503
  }
2468
2504
  var KIMI_BLOCK_RE = /<[||][^<>]*begin[^<>]*[||]>[\s\S]*?<[||][^<>]*end[^<>]*[||]>/gi;
2469
2505
  var KIMI_TOKEN_RE = /<[||][^<>]*[||]>/g;
2506
+ var DSML_BLOCK_RE = /<[||]DSML[||][^>]*>[\s\S]*?<\/[||]DSML[||][^>]*>/gi;
2507
+ var DSML_TAG_RE = /<\/?[||]DSML[||][^>]*>/gi;
2470
2508
  var THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>/gi;
2471
2509
  var THINKING_BLOCK_RE = /<\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2472
2510
  function stripThinkingTokens(content) {
2473
2511
  if (!content) return content;
2474
2512
  let cleaned = content.replace(KIMI_BLOCK_RE, "");
2475
2513
  cleaned = cleaned.replace(KIMI_TOKEN_RE, "");
2514
+ cleaned = cleaned.replace(DSML_BLOCK_RE, "");
2515
+ cleaned = cleaned.replace(DSML_TAG_RE, "");
2476
2516
  cleaned = cleaned.replace(THINKING_BLOCK_RE, "");
2477
2517
  cleaned = cleaned.replace(THINKING_TAG_RE, "");
2478
2518
  return cleaned;
@@ -3091,10 +3131,18 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3091
3131
  options.onRouted?.(routingDecision);
3092
3132
  }
3093
3133
  if (!upstream) {
3094
- const errBody = lastError?.body || "All models in fallback chain failed";
3134
+ const rawErrBody = lastError?.body || "All models in fallback chain failed";
3095
3135
  const errStatus = lastError?.status || 502;
3136
+ const transformedErr = transformPaymentError(rawErrBody);
3096
3137
  if (headersSentEarly) {
3097
- const errEvent = `data: ${JSON.stringify({ error: { message: errBody, type: "provider_error", status: errStatus } })}
3138
+ let errPayload;
3139
+ try {
3140
+ const parsed = JSON.parse(transformedErr);
3141
+ errPayload = JSON.stringify(parsed);
3142
+ } catch {
3143
+ errPayload = JSON.stringify({ error: { message: rawErrBody, type: "provider_error", status: errStatus } });
3144
+ }
3145
+ const errEvent = `data: ${errPayload}
3098
3146
 
3099
3147
  `;
3100
3148
  safeWrite(res, errEvent);
@@ -3109,17 +3157,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3109
3157
  });
3110
3158
  } else {
3111
3159
  res.writeHead(errStatus, { "Content-Type": "application/json" });
3112
- res.end(
3113
- JSON.stringify({
3114
- error: { message: errBody, type: "provider_error" }
3115
- })
3116
- );
3160
+ res.end(transformedErr);
3117
3161
  deduplicator.complete(dedupKey, {
3118
3162
  status: errStatus,
3119
3163
  headers: { "content-type": "application/json" },
3120
- body: Buffer.from(
3121
- JSON.stringify({ error: { message: errBody, type: "provider_error" } })
3122
- ),
3164
+ body: Buffer.from(transformedErr),
3123
3165
  completedAt: Date.now()
3124
3166
  });
3125
3167
  }