@blockrun/clawrouter 0.12.61 → 0.12.63

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.
Files changed (33) hide show
  1. package/docs/anthropic-cost-savings.md +349 -0
  2. package/docs/architecture.md +559 -0
  3. package/docs/assets/blockrun-248-day-cost-overrun-problem.png +0 -0
  4. package/docs/assets/blockrun-clawrouter-7-layer-token-compression-openclaw.png +0 -0
  5. package/docs/assets/blockrun-clawrouter-observation-compression-97-percent-token-savings.png +0 -0
  6. package/docs/assets/blockrun-clawrouter-openclaw-agentic-proxy-architecture.png +0 -0
  7. package/docs/assets/blockrun-clawrouter-openclaw-automatic-tier-routing-model-selection.png +0 -0
  8. package/docs/assets/blockrun-clawrouter-openclaw-error-classification-retry-storm-prevention.png +0 -0
  9. package/docs/assets/blockrun-clawrouter-openclaw-session-memory-journaling-vs-context-compounding.png +0 -0
  10. package/docs/assets/blockrun-clawrouter-vs-openclaw-standalone-comparison-production-safety.png +0 -0
  11. package/docs/assets/blockrun-clawrouter-x402-usdc-micropayment-wallet-budget-control.png +0 -0
  12. package/docs/assets/blockrun-openclaw-inference-layer-blind-spots.png +0 -0
  13. package/docs/blog-benchmark-2026-03.md +184 -0
  14. package/docs/blog-openclaw-cost-overruns.md +197 -0
  15. package/docs/clawrouter-savings.png +0 -0
  16. package/docs/configuration.md +512 -0
  17. package/docs/features.md +257 -0
  18. package/docs/image-generation.md +380 -0
  19. package/docs/plans/2026-02-03-smart-routing-design.md +267 -0
  20. package/docs/plans/2026-02-13-e2e-docker-deployment.md +1260 -0
  21. package/docs/plans/2026-02-28-worker-network.md +947 -0
  22. package/docs/plans/2026-03-18-error-classification.md +574 -0
  23. package/docs/plans/2026-03-19-exclude-models.md +538 -0
  24. package/docs/routing-profiles.md +81 -0
  25. package/docs/subscription-failover.md +320 -0
  26. package/docs/technical-routing-2026-03.md +322 -0
  27. package/docs/troubleshooting.md +159 -0
  28. package/docs/vision.md +49 -0
  29. package/docs/vs-openrouter.md +157 -0
  30. package/docs/worker-network.md +1241 -0
  31. package/package.json +3 -2
  32. package/scripts/reinstall.sh +8 -4
  33. package/scripts/update.sh +8 -4
@@ -0,0 +1,512 @@
1
+ # Configuration Reference
2
+
3
+ Complete reference for ClawRouter configuration options.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Environment Variables](#environment-variables)
8
+ - [Wallet Configuration](#wallet-configuration)
9
+ - [Wallet Backup & Recovery](#wallet-backup--recovery)
10
+ - [Proxy Settings](#proxy-settings)
11
+ - [Programmatic Usage](#programmatic-usage)
12
+ - [Routing Configuration](#routing-configuration)
13
+ - [Tier Overrides](#tier-overrides)
14
+ - [Scoring Weights](#scoring-weights)
15
+ - [Testing Configuration](#testing-configuration)
16
+
17
+ ---
18
+
19
+ ## Environment Variables
20
+
21
+ | Variable | Default | Description |
22
+ | --------------------------- | ------------------------------------- | ------------------------------------------------------------------------ |
23
+ | `BLOCKRUN_WALLET_KEY` | - | Ethereum private key (hex, 0x-prefixed). Used if no saved wallet exists. |
24
+ | `BLOCKRUN_PROXY_PORT` | `8402` | Port for the local x402 proxy server. |
25
+ | `CLAWROUTER_SOLANA_RPC_URL` | `https://api.mainnet-beta.solana.com` | Solana RPC endpoint for USDC balance checks. |
26
+ | `CLAWROUTER_DISABLED` | `false` | Set to `true` to disable smart routing (pass requests through as-is). |
27
+ | `CLAWROUTER_WORKER` | - | Set to `1` to enable Worker Mode (earn USDC by running health checks). |
28
+
29
+ ### BLOCKRUN_WALLET_KEY
30
+
31
+ The wallet private key for signing x402 micropayments.
32
+
33
+ ```bash
34
+ export BLOCKRUN_WALLET_KEY=0x...your_private_key...
35
+ ```
36
+
37
+ **Resolution order:**
38
+
39
+ 1. Saved file (`~/.openclaw/blockrun/wallet.key`) — checked first
40
+ 2. `BLOCKRUN_WALLET_KEY` environment variable — used if no saved file
41
+ 3. Auto-generate — creates new wallet and saves to file
42
+
43
+ > **Security Note:** The saved file takes priority to prevent accidentally switching wallets and losing access to funded balances.
44
+
45
+ ### BLOCKRUN_PROXY_PORT
46
+
47
+ Configure the proxy to listen on a different port:
48
+
49
+ ```bash
50
+ export BLOCKRUN_PROXY_PORT=8403
51
+ openclaw gateway restart
52
+ ```
53
+
54
+ **Behavior:**
55
+
56
+ - If a proxy is already running on the configured port, ClawRouter will **reuse it** instead of failing with `EADDRINUSE`
57
+ - The proxy returns the wallet address of the existing instance, not the configured wallet
58
+ - A warning is logged if the existing proxy uses a different wallet
59
+
60
+ **Valid values:** 1-65535 (integers only). Invalid values fall back to 8402.
61
+
62
+ ### CLAWROUTER_SOLANA_RPC_URL
63
+
64
+ Override the Solana RPC endpoint used for USDC balance checks (Solana chain only):
65
+
66
+ ```bash
67
+ export CLAWROUTER_SOLANA_RPC_URL=https://your-rpc-provider.com
68
+ openclaw gateway restart
69
+ ```
70
+
71
+ Public RPC may rate-limit on heavy usage. Use a dedicated RPC for production.
72
+
73
+ ---
74
+
75
+ ## Wallet Configuration
76
+
77
+ ClawRouter supports **two payment chains**: Base (EVM) and Solana. Both are USDC only — no SOL or ETH accepted for payments.
78
+
79
+ ### Check Active Wallet
80
+
81
+ ```bash
82
+ # View wallet address + balance (both chains shown)
83
+ /wallet
84
+
85
+ # Or via HTTP
86
+ curl http://localhost:8402/health | jq .wallet
87
+ curl "http://localhost:8402/health?full=true" | jq
88
+ ```
89
+
90
+ Response (dual-chain):
91
+
92
+ ```json
93
+ {
94
+ "status": "ok",
95
+ "wallet": "0x1234...abcd",
96
+ "solanaWallet": "7Xkr...xyz",
97
+ "paymentChain": "base",
98
+ "balance": "$2.50",
99
+ "isLow": false,
100
+ "isEmpty": false
101
+ }
102
+ ```
103
+
104
+ ### Switch Payment Chain
105
+
106
+ ```bash
107
+ /wallet solana # Switch to Solana USDC payments
108
+ /wallet base # Switch back to Base (EVM) USDC payments
109
+ ```
110
+
111
+ Or use the `/chain` command:
112
+
113
+ ```bash
114
+ /chain solana
115
+ /chain base
116
+ ```
117
+
118
+ The selected chain is persisted across gateway restarts.
119
+
120
+ ### Switch Wallets
121
+
122
+ To use a different wallet:
123
+
124
+ ```bash
125
+ # 1. Remove saved wallet
126
+ rm ~/.openclaw/blockrun/wallet.key
127
+
128
+ # 2. Set new wallet key
129
+ export BLOCKRUN_WALLET_KEY=0x...
130
+
131
+ # 3. Restart
132
+ openclaw gateway restart
133
+ ```
134
+
135
+ ### Backup Wallet
136
+
137
+ ```bash
138
+ # Backup wallet key
139
+ cp ~/.openclaw/blockrun/wallet.key ~/backup/
140
+
141
+ # View wallet address from key file
142
+ cat ~/.openclaw/blockrun/wallet.key
143
+ ```
144
+
145
+ ### Wallet Backup & Recovery
146
+
147
+ ClawRouter generates a **BIP-39 mnemonic** on first install — stored at `~/.openclaw/blockrun/wallet.key`. This single mnemonic derives both your EVM (Base) and Solana addresses. **Back up this file before terminating any VPS or machine!**
148
+
149
+ #### Using the `/wallet` Command
150
+
151
+ ```bash
152
+ # Check wallet status (address, balance, chain, file location)
153
+ /wallet
154
+
155
+ # Export mnemonic + private keys for backup
156
+ /wallet export
157
+ ```
158
+
159
+ The `/wallet export` command displays your mnemonic and keys so you can copy them before terminating a machine.
160
+
161
+ #### Manual Backup
162
+
163
+ ```bash
164
+ # Option 1: Copy the key file
165
+ cp ~/.openclaw/blockrun/wallet.key ~/backup-wallet.key
166
+
167
+ # Option 2: View mnemonic
168
+ cat ~/.openclaw/blockrun/wallet.key
169
+ ```
170
+
171
+ #### Restore on a New Machine
172
+
173
+ ```bash
174
+ # Option 1: Recover from mnemonic
175
+ npx @blockrun/clawrouter wallet recover "word1 word2 ... word12"
176
+
177
+ # Option 2: Set environment variable (before installing ClawRouter)
178
+ export BLOCKRUN_WALLET_KEY=0x...your_private_key...
179
+ openclaw plugins install @blockrun/clawrouter
180
+
181
+ # Option 3: Create the key file directly
182
+ mkdir -p ~/.openclaw/blockrun
183
+ echo "your twelve word mnemonic here" > ~/.openclaw/blockrun/wallet.key
184
+ chmod 600 ~/.openclaw/blockrun/wallet.key
185
+ openclaw plugins install @blockrun/clawrouter
186
+ ```
187
+
188
+ **Important:** If a saved wallet file exists, it takes priority over the environment variable. To use a different wallet, delete the existing file first.
189
+
190
+ #### Lost Key Recovery
191
+
192
+ If you lose your wallet key, **there is no way to recover it**. The wallet is self-custodial, meaning only you have the private key. We do not store keys or have any way to restore access.
193
+
194
+ **Prevention tips:**
195
+
196
+ - Run `/wallet export` before terminating any VPS
197
+ - Keep a secure backup of `~/.openclaw/blockrun/wallet.key`
198
+ - For production use, consider using a hardware wallet or key management system
199
+
200
+ ---
201
+
202
+ ## Proxy Settings
203
+
204
+ ### Proxy Reuse (v0.4.1+)
205
+
206
+ ClawRouter automatically detects and reuses an existing proxy on startup:
207
+
208
+ ```
209
+ Session 1: startProxy() → starts server on :8402
210
+ Session 2: startProxy() → detects existing, reuses handle
211
+ ```
212
+
213
+ **Behavior:**
214
+
215
+ - Health check is performed on the configured port before starting
216
+ - If responsive, returns a handle that uses the existing proxy
217
+ - `close()` on reused handles is a no-op (doesn't stop the original server)
218
+ - Warning logged if existing proxy uses a different wallet
219
+
220
+ ### Programmatic Usage
221
+
222
+ Use ClawRouter without OpenClaw:
223
+
224
+ ```typescript
225
+ import { startProxy } from "@blockrun/clawrouter";
226
+
227
+ const proxy = await startProxy({
228
+ walletKey: process.env.BLOCKRUN_WALLET_KEY!,
229
+ onReady: (port) => console.log(`Proxy on port ${port}`),
230
+ onRouted: (d) => console.log(`${d.model} saved ${(d.savings * 100).toFixed(0)}%`),
231
+ });
232
+
233
+ // Any OpenAI-compatible client works
234
+ const res = await fetch(`${proxy.baseUrl}/v1/chat/completions`, {
235
+ method: "POST",
236
+ headers: { "Content-Type": "application/json" },
237
+ body: JSON.stringify({
238
+ model: "blockrun/auto",
239
+ messages: [{ role: "user", content: "What is 2+2?" }],
240
+ }),
241
+ });
242
+
243
+ await proxy.close();
244
+ ```
245
+
246
+ Or use the router directly (no proxy, no payments):
247
+
248
+ ```typescript
249
+ import { route, DEFAULT_ROUTING_CONFIG, BLOCKRUN_MODELS } from "@blockrun/clawrouter";
250
+
251
+ // Build pricing map
252
+ const modelPricing = new Map();
253
+ for (const m of BLOCKRUN_MODELS) {
254
+ modelPricing.set(m.id, { inputPrice: m.inputPrice, outputPrice: m.outputPrice });
255
+ }
256
+
257
+ const decision = route("Prove sqrt(2) is irrational", undefined, 4096, {
258
+ config: DEFAULT_ROUTING_CONFIG,
259
+ modelPricing,
260
+ });
261
+
262
+ console.log(decision);
263
+ // {
264
+ // model: "deepseek/deepseek-reasoner",
265
+ // tier: "REASONING",
266
+ // confidence: 0.97,
267
+ // method: "rules",
268
+ // savings: 0.994,
269
+ // costEstimate: 0.002,
270
+ // }
271
+ ```
272
+
273
+ ### Programmatic Options
274
+
275
+ All options for `startProxy()`:
276
+
277
+ ```typescript
278
+ import { startProxy } from "@blockrun/clawrouter";
279
+
280
+ const proxy = await startProxy({
281
+ walletKey: "0x...",
282
+
283
+ // Port configuration
284
+ port: 8402, // Default: 8402 or BLOCKRUN_PROXY_PORT
285
+
286
+ // Timeouts
287
+ requestTimeoutMs: 180000, // 3 minutes (covers on-chain tx + LLM response)
288
+
289
+ // API base (for testing)
290
+ apiBase: "https://blockrun.ai/api",
291
+
292
+ // Callbacks
293
+ onReady: (port) => console.log(`Proxy ready on ${port}`),
294
+ onError: (error) => console.error(error),
295
+ onRouted: (decision) => console.log(decision.model, decision.tier),
296
+ onLowBalance: (info) => console.warn(`Low balance: ${info.balanceUSD}`),
297
+ onInsufficientFunds: (info) => console.error(`Need ${info.requiredUSD}`),
298
+ onPayment: (info) => console.log(`Paid ${info.amount} for ${info.model}`),
299
+
300
+ // Routing config overrides
301
+ routingConfig: {
302
+ // See Routing Configuration below
303
+ },
304
+ });
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Routing Configuration
310
+
311
+ ### Via openclaw.yaml
312
+
313
+ ```yaml
314
+ plugins:
315
+ - id: "@blockrun/clawrouter"
316
+ config:
317
+ # Maximum spend per session/run in USD.
318
+ # Default: disabled (no limit)
319
+ maxCostPerRun: 0.50 # $0.50 per session
320
+
321
+ # How to enforce the budget cap. Default: graceful
322
+ #
323
+ # graceful (default): when budget runs low, ClawRouter automatically downgrades
324
+ # to cheaper models (premium → auto → eco → free). Tasks keep running.
325
+ # Only returns an error if no model can serve the request at all.
326
+ #
327
+ # strict: immediately returns 429 (X-ClawRouter-Cost-Cap-Exceeded: 1) once
328
+ # the session spend reaches the cap. Use when you need a hard budget ceiling.
329
+ maxCostPerRunMode: graceful # or: strict
330
+
331
+ # Note: image generation endpoints (/v1/images/generations) bypass maxCostPerRun.
332
+ # Their cost is charged via x402 micropayment directly and is not tracked per-session.
333
+
334
+ routing:
335
+ # Override tier assignments
336
+ tiers:
337
+ SIMPLE:
338
+ primary: "google/gemini-2.5-flash"
339
+ fallback: ["deepseek/deepseek-chat"]
340
+ MEDIUM:
341
+ primary: "deepseek/deepseek-chat"
342
+ fallback: ["openai/gpt-4o-mini"]
343
+ COMPLEX:
344
+ primary: "anthropic/claude-sonnet-4.6"
345
+ fallback: ["openai/gpt-4o"]
346
+ REASONING:
347
+ primary: "deepseek/deepseek-reasoner"
348
+ fallback: ["openai/o3-mini"]
349
+
350
+ # Override scoring parameters
351
+ scoring:
352
+ reasoningKeywords: ["prove", "theorem", "formal", "derive"]
353
+ codeKeywords: ["function", "class", "async", "import"]
354
+ simpleKeywords: ["what is", "define", "hello"]
355
+
356
+ # Override thresholds
357
+ classifier:
358
+ confidenceThreshold: 0.7
359
+ reasoningConfidence: 0.97
360
+
361
+ # Context-based overrides
362
+ overrides:
363
+ largeContextTokens: 100000 # Force COMPLEX above this
364
+ structuredOutput: true # Bump to min MEDIUM for JSON/YAML
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Tier Overrides
370
+
371
+ ### Default Tier Mappings
372
+
373
+ | Tier | Primary Model | Fallback Chain |
374
+ | --------- | ----------------------------- | ----------------------------------------------- |
375
+ | SIMPLE | `google/gemini-2.5-flash` | `deepseek/deepseek-chat` |
376
+ | MEDIUM | `deepseek/deepseek-chat` | `openai/gpt-4o-mini`, `google/gemini-2.5-flash` |
377
+ | COMPLEX | `anthropic/claude-sonnet-4.6` | `openai/gpt-4o`, `google/gemini-2.5-pro` |
378
+ | REASONING | `deepseek/deepseek-reasoner` | `openai/o3-mini`, `anthropic/claude-sonnet-4.6` |
379
+
380
+ ### Fallback Chain
381
+
382
+ When the primary model fails (rate limits, billing errors, provider outages), ClawRouter tries the next model in the fallback chain:
383
+
384
+ ```
385
+ Request → gemini-2.5-flash (rate limited)
386
+ → deepseek-chat (billing error)
387
+ → gpt-4o-mini (success)
388
+ ```
389
+
390
+ Max fallback attempts: 3 models per request.
391
+
392
+ ### Custom Tier Configuration
393
+
394
+ ```yaml
395
+ routing:
396
+ tiers:
397
+ COMPLEX:
398
+ primary: "openai/gpt-4o" # Use GPT-4o instead of Claude
399
+ fallback:
400
+ - "anthropic/claude-sonnet-4.6"
401
+ - "google/gemini-2.5-pro"
402
+ ```
403
+
404
+ ---
405
+
406
+ ## Scoring Weights
407
+
408
+ The 15-dimension weighted scorer determines query complexity:
409
+
410
+ | Dimension | Weight | Detection |
411
+ | --------------------- | ------ | ---------------------------------------- |
412
+ | `reasoningMarkers` | 0.18 | "prove", "theorem", "step by step" |
413
+ | `codePresence` | 0.15 | "function", "async", "import", "```" |
414
+ | `multiStepPatterns` | 0.12 | "first...then", "step 1", numbered lists |
415
+ | `agenticTask` | 0.10 | "run", "test", "fix", "deploy", "edit" |
416
+ | `technicalTerms` | 0.10 | "algorithm", "kubernetes", "distributed" |
417
+ | `tokenCount` | 0.08 | short (<50) vs long (>500) |
418
+ | `creativeMarkers` | 0.05 | "story", "poem", "brainstorm" |
419
+ | `questionComplexity` | 0.05 | Multiple question marks |
420
+ | `constraintCount` | 0.04 | "at most", "O(n)", "maximum" |
421
+ | `imperativeVerbs` | 0.03 | "build", "create", "implement" |
422
+ | `outputFormat` | 0.03 | "json", "yaml", "schema" |
423
+ | `simpleIndicators` | 0.02 | "what is", "define", "translate" |
424
+ | `domainSpecificity` | 0.02 | "quantum", "fpga", "genomics" |
425
+ | `referenceComplexity` | 0.02 | "the docs", "the api", "above" |
426
+ | `negationComplexity` | 0.01 | "don't", "avoid", "without" |
427
+
428
+ ### Custom Keywords
429
+
430
+ ```yaml
431
+ routing:
432
+ scoring:
433
+ # Add domain-specific reasoning triggers
434
+ reasoningKeywords:
435
+ - "prove"
436
+ - "theorem"
437
+ - "formal verification"
438
+ - "type theory" # Custom
439
+
440
+ # Add framework-specific code triggers
441
+ codeKeywords:
442
+ - "function"
443
+ - "useEffect" # React-specific
444
+ - "prisma" # ORM-specific
445
+ ```
446
+
447
+ ---
448
+
449
+ ## Advanced: Confidence Calibration
450
+
451
+ The classifier uses sigmoid calibration to convert raw scores to confidence values:
452
+
453
+ ```
454
+ confidence = 1 / (1 + exp(-k * (score - midpoint)))
455
+ ```
456
+
457
+ Parameters:
458
+
459
+ - `k = 8` — steepness of the sigmoid curve
460
+ - `midpoint = 0.5` — score at which confidence = 50%
461
+
462
+ ### Override Thresholds
463
+
464
+ ```yaml
465
+ routing:
466
+ classifier:
467
+ # Require higher confidence for tier assignment
468
+ confidenceThreshold: 0.8 # Default: 0.7
469
+
470
+ # Force REASONING tier at lower confidence
471
+ reasoningConfidence: 0.90 # Default: 0.97
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Testing Configuration
477
+
478
+ ### Dry Run (No Payments)
479
+
480
+ For testing routing without spending USDC:
481
+
482
+ ```typescript
483
+ import { route, DEFAULT_ROUTING_CONFIG, BLOCKRUN_MODELS } from "@blockrun/clawrouter";
484
+
485
+ // Build pricing map
486
+ const modelPricing = new Map();
487
+ for (const m of BLOCKRUN_MODELS) {
488
+ modelPricing.set(m.id, { inputPrice: m.inputPrice, outputPrice: m.outputPrice });
489
+ }
490
+
491
+ // Test routing decisions locally
492
+ const decision = route("Prove sqrt(2) is irrational", undefined, 4096, {
493
+ config: DEFAULT_ROUTING_CONFIG,
494
+ modelPricing,
495
+ });
496
+
497
+ console.log(decision);
498
+ // { model: "deepseek/deepseek-reasoner", tier: "REASONING", ... }
499
+ ```
500
+
501
+ ### Run Tests
502
+
503
+ ```bash
504
+ # Router tests (no wallet needed)
505
+ npx tsx test/e2e.ts
506
+
507
+ # Proxy reuse tests
508
+ npx tsx test/proxy-reuse.ts
509
+
510
+ # Full e2e with payments (requires funded wallet)
511
+ BLOCKRUN_WALLET_KEY=0x... npx tsx test/e2e.ts
512
+ ```