@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/README.md +1 -0
- package/dist/cli.js +21 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.js +27 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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: [
|
|
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";
|
|
@@ -2503,16 +2512,12 @@ function normalizeMessagesForThinking(messages) {
|
|
|
2503
2512
|
}
|
|
2504
2513
|
var KIMI_BLOCK_RE = /<[||][^<>]*begin[^<>]*[||]>[\s\S]*?<[||][^<>]*end[^<>]*[||]>/gi;
|
|
2505
2514
|
var KIMI_TOKEN_RE = /<[||][^<>]*[||]>/g;
|
|
2506
|
-
var DSML_BLOCK_RE = /<[||]DSML[||][^>]*>[\s\S]*?<\/[||]DSML[||][^>]*>/gi;
|
|
2507
|
-
var DSML_TAG_RE = /<\/?[||]DSML[||][^>]*>/gi;
|
|
2508
2515
|
var THINKING_TAG_RE = /<\s*\/?\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>/gi;
|
|
2509
2516
|
var THINKING_BLOCK_RE = /<\s*(?:think(?:ing)?|thought|antthinking)\b[^>]*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
|
|
2510
2517
|
function stripThinkingTokens(content) {
|
|
2511
2518
|
if (!content) return content;
|
|
2512
2519
|
let cleaned = content.replace(KIMI_BLOCK_RE, "");
|
|
2513
2520
|
cleaned = cleaned.replace(KIMI_TOKEN_RE, "");
|
|
2514
|
-
cleaned = cleaned.replace(DSML_BLOCK_RE, "");
|
|
2515
|
-
cleaned = cleaned.replace(DSML_TAG_RE, "");
|
|
2516
2521
|
cleaned = cleaned.replace(THINKING_BLOCK_RE, "");
|
|
2517
2522
|
cleaned = cleaned.replace(THINKING_TAG_RE, "");
|
|
2518
2523
|
return cleaned;
|
|
@@ -2819,7 +2824,8 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
|
|
|
2819
2824
|
if (isGoogleModel(modelId) && Array.isArray(parsed.messages)) {
|
|
2820
2825
|
parsed.messages = normalizeMessagesForGoogle(parsed.messages);
|
|
2821
2826
|
}
|
|
2822
|
-
|
|
2827
|
+
const hasThinkingEnabled = !!(parsed.thinking || parsed.extended_thinking || isReasoningModel(modelId));
|
|
2828
|
+
if (hasThinkingEnabled && Array.isArray(parsed.messages)) {
|
|
2823
2829
|
parsed.messages = normalizeMessagesForThinking(parsed.messages);
|
|
2824
2830
|
}
|
|
2825
2831
|
requestBody = Buffer.from(JSON.stringify(parsed));
|
|
@@ -3061,7 +3067,11 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3061
3067
|
modelsToTry = contextFiltered.slice(0, MAX_FALLBACK_ATTEMPTS);
|
|
3062
3068
|
modelsToTry = prioritizeNonRateLimited(modelsToTry);
|
|
3063
3069
|
} else {
|
|
3064
|
-
|
|
3070
|
+
if (modelId && modelId !== FREE_MODEL) {
|
|
3071
|
+
modelsToTry = [modelId, FREE_MODEL];
|
|
3072
|
+
} else {
|
|
3073
|
+
modelsToTry = modelId ? [modelId] : [];
|
|
3074
|
+
}
|
|
3065
3075
|
}
|
|
3066
3076
|
let upstream;
|
|
3067
3077
|
let lastError;
|
|
@@ -3140,7 +3150,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3140
3150
|
const parsed = JSON.parse(transformedErr);
|
|
3141
3151
|
errPayload = JSON.stringify(parsed);
|
|
3142
3152
|
} catch {
|
|
3143
|
-
errPayload = JSON.stringify({
|
|
3153
|
+
errPayload = JSON.stringify({
|
|
3154
|
+
error: { message: rawErrBody, type: "provider_error", status: errStatus }
|
|
3155
|
+
});
|
|
3144
3156
|
}
|
|
3145
3157
|
const errEvent = `data: ${errPayload}
|
|
3146
3158
|
|
|
@@ -3244,7 +3256,7 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3244
3256
|
index,
|
|
3245
3257
|
delta: {},
|
|
3246
3258
|
logprobs: null,
|
|
3247
|
-
finish_reason: choice.finish_reason ?? "stop"
|
|
3259
|
+
finish_reason: toolCalls && toolCalls.length > 0 ? "tool_calls" : choice.finish_reason ?? "stop"
|
|
3248
3260
|
}
|
|
3249
3261
|
]
|
|
3250
3262
|
};
|