@blockrun/clawrouter 0.8.14 → 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/README.md CHANGED
@@ -60,6 +60,7 @@ Done! Smart routing (`blockrun/auto`) is now your default model.
60
60
  **📖 Full Windows Guide:** [docs/windows-installation.md](docs/windows-installation.md)
61
61
 
62
62
  **Quick Summary:**
63
+
63
64
  - ✅ ClawRouter code is Windows-compatible
64
65
  - ❌ OpenClaw CLI has a `spawn EINVAL` bug on Windows
65
66
  - ✅ Works perfectly on **Linux** and **macOS**
package/dist/cli.js CHANGED
@@ -1150,7 +1150,11 @@ var DEFAULT_ROUTING_CONFIG = {
1150
1150
  SIMPLE: {
1151
1151
  primary: "moonshot/kimi-k2.5",
1152
1152
  // Cheaper than Haiku ($0.5/$2.4 vs $1/$5), larger context
1153
- fallback: ["anthropic/claude-haiku-4.5", "xai/grok-4-fast-non-reasoning", "openai/gpt-4o-mini"]
1153
+ fallback: [
1154
+ "anthropic/claude-haiku-4.5",
1155
+ "xai/grok-4-fast-non-reasoning",
1156
+ "openai/gpt-4o-mini"
1157
+ ]
1154
1158
  },
1155
1159
  MEDIUM: {
1156
1160
  primary: "xai/grok-code-fast-1",
@@ -1662,6 +1666,11 @@ function getModelContextWindow(modelId) {
1662
1666
  const model = BLOCKRUN_MODELS.find((m) => m.id === normalized);
1663
1667
  return model?.contextWindow;
1664
1668
  }
1669
+ function isReasoningModel(modelId) {
1670
+ const normalized = modelId.replace("blockrun/", "");
1671
+ const model = BLOCKRUN_MODELS.find((m) => m.id === normalized);
1672
+ return model?.reasoning ?? false;
1673
+ }
1665
1674
 
1666
1675
  // src/logger.ts
1667
1676
  import { appendFile, mkdir } from "fs/promises";
@@ -2815,7 +2824,8 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
2815
2824
  if (isGoogleModel(modelId) && Array.isArray(parsed.messages)) {
2816
2825
  parsed.messages = normalizeMessagesForGoogle(parsed.messages);
2817
2826
  }
2818
- if (parsed.thinking && Array.isArray(parsed.messages)) {
2827
+ const hasThinkingEnabled = !!(parsed.thinking || parsed.extended_thinking || isReasoningModel(modelId));
2828
+ if (hasThinkingEnabled && Array.isArray(parsed.messages)) {
2819
2829
  parsed.messages = normalizeMessagesForThinking(parsed.messages);
2820
2830
  }
2821
2831
  requestBody = Buffer.from(JSON.stringify(parsed));
@@ -3057,7 +3067,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3057
3067
  modelsToTry = contextFiltered.slice(0, MAX_FALLBACK_ATTEMPTS);
3058
3068
  modelsToTry = prioritizeNonRateLimited(modelsToTry);
3059
3069
  } else {
3060
- modelsToTry = modelId ? [modelId] : [];
3070
+ if (modelId && modelId !== FREE_MODEL) {
3071
+ modelsToTry = [modelId, FREE_MODEL];
3072
+ } else {
3073
+ modelsToTry = modelId ? [modelId] : [];
3074
+ }
3061
3075
  }
3062
3076
  let upstream;
3063
3077
  let lastError;
@@ -3136,7 +3150,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3136
3150
  const parsed = JSON.parse(transformedErr);
3137
3151
  errPayload = JSON.stringify(parsed);
3138
3152
  } catch {
3139
- errPayload = JSON.stringify({ error: { message: rawErrBody, type: "provider_error", status: errStatus } });
3153
+ errPayload = JSON.stringify({
3154
+ error: { message: rawErrBody, type: "provider_error", status: errStatus }
3155
+ });
3140
3156
  }
3141
3157
  const errEvent = `data: ${errPayload}
3142
3158
 
@@ -3240,7 +3256,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
3240
3256
  index,
3241
3257
  delta: {},
3242
3258
  logprobs: null,
3243
- finish_reason: choice.finish_reason ?? "stop"
3259
+ finish_reason: toolCalls && toolCalls.length > 0 ? "tool_calls" : choice.finish_reason ?? "stop"
3244
3260
  }
3245
3261
  ]
3246
3262
  };