@blockrun/clawrouter 0.12.62 → 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.
- package/docs/anthropic-cost-savings.md +349 -0
- package/docs/architecture.md +559 -0
- package/docs/assets/blockrun-248-day-cost-overrun-problem.png +0 -0
- package/docs/assets/blockrun-clawrouter-7-layer-token-compression-openclaw.png +0 -0
- package/docs/assets/blockrun-clawrouter-observation-compression-97-percent-token-savings.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-agentic-proxy-architecture.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-automatic-tier-routing-model-selection.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-error-classification-retry-storm-prevention.png +0 -0
- package/docs/assets/blockrun-clawrouter-openclaw-session-memory-journaling-vs-context-compounding.png +0 -0
- package/docs/assets/blockrun-clawrouter-vs-openclaw-standalone-comparison-production-safety.png +0 -0
- package/docs/assets/blockrun-clawrouter-x402-usdc-micropayment-wallet-budget-control.png +0 -0
- package/docs/assets/blockrun-openclaw-inference-layer-blind-spots.png +0 -0
- package/docs/blog-benchmark-2026-03.md +184 -0
- package/docs/blog-openclaw-cost-overruns.md +197 -0
- package/docs/clawrouter-savings.png +0 -0
- package/docs/configuration.md +512 -0
- package/docs/features.md +257 -0
- package/docs/image-generation.md +380 -0
- package/docs/plans/2026-02-03-smart-routing-design.md +267 -0
- package/docs/plans/2026-02-13-e2e-docker-deployment.md +1260 -0
- package/docs/plans/2026-02-28-worker-network.md +947 -0
- package/docs/plans/2026-03-18-error-classification.md +574 -0
- package/docs/plans/2026-03-19-exclude-models.md +538 -0
- package/docs/routing-profiles.md +81 -0
- package/docs/subscription-failover.md +320 -0
- package/docs/technical-routing-2026-03.md +322 -0
- package/docs/troubleshooting.md +159 -0
- package/docs/vision.md +49 -0
- package/docs/vs-openrouter.md +157 -0
- package/docs/worker-network.md +1241 -0
- package/package.json +2 -1
|
@@ -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
|
+
```
|