@blockrun/clawrouter 0.8.13 → 0.8.15

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/index.js CHANGED
@@ -440,6 +440,11 @@ function getModelContextWindow(modelId) {
440
440
  const model = BLOCKRUN_MODELS.find((m) => m.id === normalized);
441
441
  return model?.contextWindow;
442
442
  }
443
+ function isReasoningModel(modelId) {
444
+ const normalized = modelId.replace("blockrun/", "");
445
+ const model = BLOCKRUN_MODELS.find((m) => m.id === normalized);
446
+ return model?.reasoning ?? false;
447
+ }
443
448
 
444
449
  // src/provider.ts
445
450
  var activeProxy = null;
@@ -1615,7 +1620,11 @@ var DEFAULT_ROUTING_CONFIG = {
1615
1620
  SIMPLE: {
1616
1621
  primary: "moonshot/kimi-k2.5",
1617
1622
  // Cheaper than Haiku ($0.5/$2.4 vs $1/$5), larger context
1618
- fallback: ["anthropic/claude-haiku-4.5", "xai/grok-4-fast-non-reasoning", "openai/gpt-4o-mini"]
1623
+ fallback: [
1624
+ "anthropic/claude-haiku-4.5",
1625
+ "xai/grok-4-fast-non-reasoning",
1626
+ "openai/gpt-4o-mini"
1627
+ ]
1619
1628
  },
1620
1629
  MEDIUM: {
1621
1630
  primary: "xai/grok-code-fast-1",
@@ -2642,16 +2651,12 @@ function normalizeMessagesForThinking(messages) {
2642
2651
  }
2643
2652
  var KIMI_BLOCK_RE = /<[||][^<>]*begin[^<>]*[||]>[\s\S]*?<[||][^<>]*end[^<>]*[||]>/gi;
2644
2653
  var KIMI_TOKEN_RE = /<[||][^<>]*[||]>/g;
2645
- var DSML_BLOCK_RE = /<[||]DSML[||][^>]*>[\s\S]*?<\/[||]DSML[||][^>]*>/gi;
2646
- var DSML_TAG_RE = /<\/?[||]DSML[||][^>]*>/gi;
2647
2654
  var THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>/gi;
2648
2655
  var THINKING_BLOCK_RE = /<\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
2649
2656
  function stripThinkingTokens(content) {
2650
2657
  if (!content) return content;
2651
2658
  let cleaned = content.replace(KIMI_BLOCK_RE, "");
2652
2659
  cleaned = cleaned.replace(KIMI_TOKEN_RE, "");
2653
- cleaned = cleaned.replace(DSML_BLOCK_RE, "");
2654
- cleaned = cleaned.replace(DSML_TAG_RE, "");
2655
2660
  cleaned = cleaned.replace(THINKING_BLOCK_RE, "");
2656
2661
  cleaned = cleaned.replace(THINKING_TAG_RE, "");
2657
2662
  return cleaned;
@@ -2958,7 +2963,8 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
2958
2963
  if (isGoogleModel(modelId) && Array.isArray(parsed.messages)) {
2959
2964
  parsed.messages = normalizeMessagesForGoogle(parsed.messages);
2960
2965
  }
2961
- if (parsed.thinking && Array.isArray(parsed.messages)) {
2966
+ const hasThinkingEnabled = !!(parsed.thinking || parsed.extended_thinking || isReasoningModel(modelId));
2967
+ if (hasThinkingEnabled && Array.isArray(parsed.messages)) {
2962
2968
  parsed.messages = normalizeMessagesForThinking(parsed.messages);
2963
2969
  }
2964
2970
  requestBody = Buffer.from(JSON.stringify(parsed));
@@ -3200,7 +3206,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3200
3206
  modelsToTry = contextFiltered.slice(0, MAX_FALLBACK_ATTEMPTS);
3201
3207
  modelsToTry = prioritizeNonRateLimited(modelsToTry);
3202
3208
  } else {
3203
- modelsToTry = modelId ? [modelId] : [];
3209
+ if (modelId && modelId !== FREE_MODEL) {
3210
+ modelsToTry = [modelId, FREE_MODEL];
3211
+ } else {
3212
+ modelsToTry = modelId ? [modelId] : [];
3213
+ }
3204
3214
  }
3205
3215
  let upstream;
3206
3216
  let lastError;
@@ -3279,7 +3289,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3279
3289
  const parsed = JSON.parse(transformedErr);
3280
3290
  errPayload = JSON.stringify(parsed);
3281
3291
  } catch {
3282
- errPayload = JSON.stringify({ error: { message: rawErrBody, type: "provider_error", status: errStatus } });
3292
+ errPayload = JSON.stringify({
3293
+ error: { message: rawErrBody, type: "provider_error", status: errStatus }
3294
+ });
3283
3295
  }
3284
3296
  const errEvent = `data: ${errPayload}
3285
3297
 
@@ -3383,7 +3395,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3383
3395
  index,
3384
3396
  delta: {},
3385
3397
  logprobs: null,
3386
- finish_reason: choice.finish_reason ?? "stop"
3398
+ finish_reason: toolCalls && toolCalls.length > 0 ? "tool_calls" : choice.finish_reason ?? "stop"
3387
3399
  }
3388
3400
  ]
3389
3401
  };
@@ -3612,7 +3624,9 @@ function injectModelsConfig(logger) {
3612
3624
  mkdirSync(configDir, { recursive: true });
3613
3625
  logger.info("Created OpenClaw config directory");
3614
3626
  } catch (err) {
3615
- logger.info(`Failed to create config dir: ${err instanceof Error ? err.message : String(err)}`);
3627
+ logger.info(
3628
+ `Failed to create config dir: ${err instanceof Error ? err.message : String(err)}`
3629
+ );
3616
3630
  return;
3617
3631
  }
3618
3632
  }
@@ -3626,7 +3640,9 @@ function injectModelsConfig(logger) {
3626
3640
  needsWrite = true;
3627
3641
  }
3628
3642
  } catch (err) {
3629
- logger.info(`Failed to parse config (will recreate): ${err instanceof Error ? err.message : String(err)}`);
3643
+ logger.info(
3644
+ `Failed to parse config (will recreate): ${err instanceof Error ? err.message : String(err)}`
3645
+ );
3630
3646
  config = {};
3631
3647
  needsWrite = true;
3632
3648
  }