@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 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 | 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%** |
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 | Why |
160
- | --------- | -------------------- | -------------------------------------- |
161
- | SIMPLE | claude-haiku-4.5 | Fast + reliable tool use |
162
- | MEDIUM | kimi-k2.5 | 200+ tool chains, 76% cheaper |
163
- | COMPLEX | claude-sonnet-4 | Best balance for complex tasks |
164
- | REASONING | kimi-k2.5 | Extended reasoning + execution |
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 # Always use agentic tiers
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 | Input $/M | Output $/M | Context | Reasoning |
239
- | ----------------- | --------- | ---------- | ------- | :-------: |
240
- | **OpenAI** | | | | |
241
- | gpt-5.2 | $1.75 | $14.00 | 400K | \* |
242
- | gpt-4o | $2.50 | $10.00 | 128K | |
243
- | gpt-4o-mini | $0.15 | $0.60 | 128K | |
244
- | o3 | $2.00 | $8.00 | 200K | \* |
245
- | o3-mini | $1.10 | $4.40 | 128K | \* |
246
- | **Anthropic** | | | | |
247
- | claude-opus-4.5 | $5.00 | $25.00 | 200K | \* |
248
- | claude-sonnet-4 | $3.00 | $15.00 | 200K | \* |
249
- | claude-haiku-4.5 | $1.00 | $5.00 | 200K | |
250
- | **Google** | | | | |
251
- | gemini-2.5-pro | $1.25 | $10.00 | 1M | \* |
252
- | gemini-2.5-flash | $0.15 | $0.60 | 1M | |
253
- | **DeepSeek** | | | | |
254
- | deepseek-chat | $0.14 | $0.28 | 128K | |
255
- | deepseek-reasoner | $0.55 | $2.19 | 128K | \* |
256
- | **xAI** | | | | |
257
- | grok-3 | $3.00 | $15.00 | 131K | \* |
258
- | grok-3-mini | $0.30 | $0.50 | 131K | |
259
- | grok-4-fast-reasoning | $0.20 | $0.50 | 131K | \* |
260
- | grok-4-fast | $0.20 | $0.50 | 131K | |
261
- | grok-code-fast-1 | $0.20 | $1.50 | 131K | |
262
- | **Moonshot** | | | | |
263
- | kimi-k2.5 | $0.50 | $2.40 | 262K | \* |
264
- | **NVIDIA** | | | | |
265
- | gpt-oss-120b | **FREE** | **FREE** | 128K | |
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
- "nvidia": "nvidia/gpt-oss-120b"
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: ["deepseek/deepseek-chat", "xai/grok-4-fast-non-reasoning", "google/gemini-2.5-flash"]
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 Baseline Cost (Opus): $${stats.totalBaselineCost.toFixed(4).padEnd(33)}\u2551`
1819
- );
1820
- lines.push(
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(req.headers);
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") return;
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 {