@blockrun/clawrouter 0.5.0 → 0.5.1
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 +52 -41
- package/dist/index.js +17 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -130,12 +130,12 @@ Mixed-language prompts are supported — keywords from all languages are checked
|
|
|
130
130
|
|
|
131
131
|
### Tier → Model Mapping
|
|
132
132
|
|
|
133
|
-
| Tier | Primary Model
|
|
134
|
-
| --------- |
|
|
135
|
-
| SIMPLE | gemini-2.5-flash
|
|
136
|
-
| MEDIUM | grok-code-fast-1
|
|
137
|
-
| COMPLEX | gemini-2.5-pro
|
|
138
|
-
| REASONING | grok-4-fast-reasoning
|
|
133
|
+
| Tier | Primary Model | Cost/M | Savings vs Opus |
|
|
134
|
+
| --------- | --------------------- | ------ | --------------- |
|
|
135
|
+
| SIMPLE | gemini-2.5-flash | $0.60 | **99.2%** |
|
|
136
|
+
| MEDIUM | grok-code-fast-1 | $1.50 | **98.0%** |
|
|
137
|
+
| COMPLEX | gemini-2.5-pro | $10.00 | **86.7%** |
|
|
138
|
+
| REASONING | grok-4-fast-reasoning | $0.50 | **99.3%** |
|
|
139
139
|
|
|
140
140
|
Special rule: 2+ reasoning markers → REASONING at 0.97 confidence.
|
|
141
141
|
|
|
@@ -150,18 +150,19 @@ ClawRouter automatically detects multi-step agentic tasks and routes to models o
|
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
**How it works:**
|
|
153
|
+
|
|
153
154
|
- Detects agentic keywords: file ops ("read", "edit"), execution ("run", "test", "deploy"), iteration ("fix", "debug", "verify")
|
|
154
155
|
- Threshold: 2+ signals triggers auto-switch to agentic tiers
|
|
155
156
|
- No config needed — works automatically
|
|
156
157
|
|
|
157
158
|
**Agentic tier models** (optimized for multi-step autonomy):
|
|
158
159
|
|
|
159
|
-
| Tier | Agentic Model
|
|
160
|
-
| --------- |
|
|
161
|
-
| SIMPLE | claude-haiku-4.5
|
|
162
|
-
| MEDIUM | kimi-k2.5
|
|
163
|
-
| COMPLEX | claude-sonnet-4
|
|
164
|
-
| REASONING | kimi-k2.5
|
|
160
|
+
| Tier | Agentic Model | Why |
|
|
161
|
+
| --------- | ---------------- | ------------------------------ |
|
|
162
|
+
| SIMPLE | claude-haiku-4.5 | Fast + reliable tool use |
|
|
163
|
+
| MEDIUM | kimi-k2.5 | 200+ tool chains, 76% cheaper |
|
|
164
|
+
| COMPLEX | claude-sonnet-4 | Best balance for complex tasks |
|
|
165
|
+
| REASONING | kimi-k2.5 | Extended reasoning + execution |
|
|
165
166
|
|
|
166
167
|
You can also force agentic mode via config:
|
|
167
168
|
|
|
@@ -172,7 +173,7 @@ plugins:
|
|
|
172
173
|
config:
|
|
173
174
|
routing:
|
|
174
175
|
overrides:
|
|
175
|
-
agenticMode: true
|
|
176
|
+
agenticMode: true # Always use agentic tiers
|
|
176
177
|
```
|
|
177
178
|
|
|
178
179
|
### Tool Detection (v0.5)
|
|
@@ -235,34 +236,34 @@ Compared to **$75/M** for Claude Opus = **96% savings** on a typical workload.
|
|
|
235
236
|
|
|
236
237
|
30+ models across 6 providers, one wallet:
|
|
237
238
|
|
|
238
|
-
| Model
|
|
239
|
-
|
|
|
240
|
-
| **OpenAI**
|
|
241
|
-
| gpt-5.2
|
|
242
|
-
| gpt-4o
|
|
243
|
-
| gpt-4o-mini
|
|
244
|
-
| o3
|
|
245
|
-
| o3-mini
|
|
246
|
-
| **Anthropic**
|
|
247
|
-
| claude-opus-4.5
|
|
248
|
-
| claude-sonnet-4
|
|
249
|
-
| claude-haiku-4.5
|
|
250
|
-
| **Google**
|
|
251
|
-
| gemini-2.5-pro
|
|
252
|
-
| gemini-2.5-flash
|
|
253
|
-
| **DeepSeek**
|
|
254
|
-
| deepseek-chat
|
|
255
|
-
| deepseek-reasoner
|
|
256
|
-
| **xAI**
|
|
257
|
-
| grok-3
|
|
258
|
-
| grok-3-mini
|
|
259
|
-
| grok-4-fast-reasoning | $0.20
|
|
260
|
-
| grok-4-fast
|
|
261
|
-
| grok-code-fast-1
|
|
262
|
-
| **Moonshot**
|
|
263
|
-
| kimi-k2.5
|
|
264
|
-
| **NVIDIA**
|
|
265
|
-
| gpt-oss-120b
|
|
239
|
+
| Model | Input $/M | Output $/M | Context | Reasoning |
|
|
240
|
+
| --------------------- | --------- | ---------- | ------- | :-------: |
|
|
241
|
+
| **OpenAI** | | | | |
|
|
242
|
+
| gpt-5.2 | $1.75 | $14.00 | 400K | \* |
|
|
243
|
+
| gpt-4o | $2.50 | $10.00 | 128K | |
|
|
244
|
+
| gpt-4o-mini | $0.15 | $0.60 | 128K | |
|
|
245
|
+
| o3 | $2.00 | $8.00 | 200K | \* |
|
|
246
|
+
| o3-mini | $1.10 | $4.40 | 128K | \* |
|
|
247
|
+
| **Anthropic** | | | | |
|
|
248
|
+
| claude-opus-4.5 | $5.00 | $25.00 | 200K | \* |
|
|
249
|
+
| claude-sonnet-4 | $3.00 | $15.00 | 200K | \* |
|
|
250
|
+
| claude-haiku-4.5 | $1.00 | $5.00 | 200K | |
|
|
251
|
+
| **Google** | | | | |
|
|
252
|
+
| gemini-2.5-pro | $1.25 | $10.00 | 1M | \* |
|
|
253
|
+
| gemini-2.5-flash | $0.15 | $0.60 | 1M | |
|
|
254
|
+
| **DeepSeek** | | | | |
|
|
255
|
+
| deepseek-chat | $0.14 | $0.28 | 128K | |
|
|
256
|
+
| deepseek-reasoner | $0.55 | $2.19 | 128K | \* |
|
|
257
|
+
| **xAI** | | | | |
|
|
258
|
+
| grok-3 | $3.00 | $15.00 | 131K | \* |
|
|
259
|
+
| grok-3-mini | $0.30 | $0.50 | 131K | |
|
|
260
|
+
| grok-4-fast-reasoning | $0.20 | $0.50 | 131K | \* |
|
|
261
|
+
| grok-4-fast | $0.20 | $0.50 | 131K | |
|
|
262
|
+
| grok-code-fast-1 | $0.20 | $1.50 | 131K | |
|
|
263
|
+
| **Moonshot** | | | | |
|
|
264
|
+
| kimi-k2.5 | $0.50 | $2.40 | 262K | \* |
|
|
265
|
+
| **NVIDIA** | | | | |
|
|
266
|
+
| gpt-oss-120b | **FREE** | **FREE** | 128K | |
|
|
266
267
|
|
|
267
268
|
Full list: [`src/models.ts`](src/models.ts)
|
|
268
269
|
|
|
@@ -538,6 +539,7 @@ Track your savings in real-time:
|
|
|
538
539
|
```
|
|
539
540
|
|
|
540
541
|
Output:
|
|
542
|
+
|
|
541
543
|
```
|
|
542
544
|
╔════════════════════════════════════════════════════════════╗
|
|
543
545
|
║ ClawRouter Usage Statistics ║
|
|
@@ -625,6 +627,15 @@ Wallet needs funding.
|
|
|
625
627
|
3. $1-5 is enough for hundreds of requests
|
|
626
628
|
4. Restart OpenClaw
|
|
627
629
|
|
|
630
|
+
### "WARNING: dangerous code patterns — possible credential harvesting"
|
|
631
|
+
|
|
632
|
+
This is a **false positive**. ClawRouter legitimately:
|
|
633
|
+
|
|
634
|
+
1. Reads `BLOCKRUN_WALLET_KEY` from environment (for authentication)
|
|
635
|
+
2. Sends authenticated requests to BlockRun API (for x402 micropayments)
|
|
636
|
+
|
|
637
|
+
This pattern triggers OpenClaw's security scanner, but it's the intended behavior — the wallet key is required to sign payment transactions. The code is fully open source and auditable.
|
|
638
|
+
|
|
628
639
|
### Security Scanner Warning: "env-harvesting"
|
|
629
640
|
|
|
630
641
|
OpenClaw's security scanner may flag ClawRouter with:
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var MODEL_ALIASES = {
|
|
|
24
24
|
"grok-fast": "xai/grok-4-fast-reasoning",
|
|
25
25
|
"grok-code": "xai/grok-code-fast-1",
|
|
26
26
|
// NVIDIA
|
|
27
|
-
|
|
27
|
+
nvidia: "nvidia/gpt-oss-120b"
|
|
28
28
|
};
|
|
29
29
|
function resolveModelAlias(model) {
|
|
30
30
|
const normalized = model.trim().toLowerCase();
|
|
@@ -1561,7 +1561,11 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
1561
1561
|
MEDIUM: {
|
|
1562
1562
|
primary: "xai/grok-code-fast-1",
|
|
1563
1563
|
// Code specialist, $0.20/$1.50
|
|
1564
|
-
fallback: [
|
|
1564
|
+
fallback: [
|
|
1565
|
+
"deepseek/deepseek-chat",
|
|
1566
|
+
"xai/grok-4-fast-non-reasoning",
|
|
1567
|
+
"google/gemini-2.5-flash"
|
|
1568
|
+
]
|
|
1565
1569
|
},
|
|
1566
1570
|
COMPLEX: {
|
|
1567
1571
|
primary: "google/gemini-2.5-pro",
|
|
@@ -1814,11 +1818,11 @@ function formatStatsAscii(stats) {
|
|
|
1814
1818
|
lines.push(`\u2551 Period: ${stats.period.padEnd(49)}\u2551`);
|
|
1815
1819
|
lines.push(`\u2551 Total Requests: ${stats.totalRequests.toString().padEnd(41)}\u2551`);
|
|
1816
1820
|
lines.push(`\u2551 Total Cost: $${stats.totalCost.toFixed(4).padEnd(43)}\u2551`);
|
|
1821
|
+
lines.push(`\u2551 Baseline Cost (Opus): $${stats.totalBaselineCost.toFixed(4).padEnd(33)}\u2551`);
|
|
1817
1822
|
lines.push(
|
|
1818
|
-
`\u2551
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
`\u2551 \u{1F4B0} Total Saved: $${stats.totalSavings.toFixed(4)} (${stats.savingsPercentage.toFixed(1)}%)`.padEnd(61) + "\u2551"
|
|
1823
|
+
`\u2551 \u{1F4B0} Total Saved: $${stats.totalSavings.toFixed(4)} (${stats.savingsPercentage.toFixed(1)}%)`.padEnd(
|
|
1824
|
+
61
|
|
1825
|
+
) + "\u2551"
|
|
1822
1826
|
);
|
|
1823
1827
|
lines.push(`\u2551 Avg Latency: ${stats.avgLatencyMs.toFixed(0)}ms`.padEnd(61) + "\u2551");
|
|
1824
1828
|
lines.push("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
|
|
@@ -2169,10 +2173,7 @@ var SessionStore = class {
|
|
|
2169
2173
|
constructor(config = {}) {
|
|
2170
2174
|
this.config = { ...DEFAULT_SESSION_CONFIG, ...config };
|
|
2171
2175
|
if (this.config.enabled) {
|
|
2172
|
-
this.cleanupInterval = setInterval(
|
|
2173
|
-
() => this.cleanup(),
|
|
2174
|
-
5 * 60 * 1e3
|
|
2175
|
-
);
|
|
2176
|
+
this.cleanupInterval = setInterval(() => this.cleanup(), 5 * 60 * 1e3);
|
|
2176
2177
|
}
|
|
2177
2178
|
}
|
|
2178
2179
|
/**
|
|
@@ -2681,7 +2682,9 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
2681
2682
|
bodyModified = true;
|
|
2682
2683
|
}
|
|
2683
2684
|
if (isAutoModel) {
|
|
2684
|
-
const sessionId = getSessionId(
|
|
2685
|
+
const sessionId = getSessionId(
|
|
2686
|
+
req.headers
|
|
2687
|
+
);
|
|
2685
2688
|
const existingSession = sessionId ? sessionStore.getSession(sessionId) : void 0;
|
|
2686
2689
|
if (existingSession) {
|
|
2687
2690
|
console.log(
|
|
@@ -3054,7 +3057,8 @@ async function proxyRequest(req, res, apiBase, payFetch, options, routerOpts, de
|
|
|
3054
3057
|
} else {
|
|
3055
3058
|
const responseHeaders = {};
|
|
3056
3059
|
upstream.headers.forEach((value, key) => {
|
|
3057
|
-
if (key === "transfer-encoding" || key === "connection" || key === "content-encoding")
|
|
3060
|
+
if (key === "transfer-encoding" || key === "connection" || key === "content-encoding")
|
|
3061
|
+
return;
|
|
3058
3062
|
responseHeaders[key] = value;
|
|
3059
3063
|
});
|
|
3060
3064
|
res.writeHead(upstream.status, responseHeaders);
|
|
@@ -3395,11 +3399,7 @@ async function createStatsCommand() {
|
|
|
3395
3399
|
const stats = await getStats(Math.min(days, 30));
|
|
3396
3400
|
const ascii = formatStatsAscii(stats);
|
|
3397
3401
|
return {
|
|
3398
|
-
text: [
|
|
3399
|
-
"```",
|
|
3400
|
-
ascii,
|
|
3401
|
-
"```"
|
|
3402
|
-
].join("\n")
|
|
3402
|
+
text: ["```", ascii, "```"].join("\n")
|
|
3403
3403
|
};
|
|
3404
3404
|
} catch (err) {
|
|
3405
3405
|
return {
|