@blockrun/clawrouter 0.1.0
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 +365 -0
- package/dist/index.d.ts +357 -0
- package/dist/index.js +888 -0
- package/dist/index.js.map +1 -0
- package/openclaw.plugin.json +25 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ClawRouter
|
|
4
|
+
|
|
5
|
+
**Save 63% on LLM costs. Automatically.**
|
|
6
|
+
|
|
7
|
+
Route every request to the cheapest model that can handle it.
|
|
8
|
+
One wallet, 30+ models, zero API keys.
|
|
9
|
+
|
|
10
|
+
[](https://npmjs.com/package/@blockrun/clawrouter)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://typescriptlang.org)
|
|
13
|
+
[](https://nodejs.org)
|
|
14
|
+
|
|
15
|
+
[Docs](https://blockrun.ai/docs) · [Models](https://blockrun.ai/models) · [Telegram](https://t.me/blockrunAI) · [X](https://x.com/BlockRunAI)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
"What is 2+2?" → Gemini Flash $0.60/M saved 94%
|
|
23
|
+
"Summarize this article" → DeepSeek Chat $0.42/M saved 96%
|
|
24
|
+
"Build a React component" → Claude Sonnet $15.00/M best quality
|
|
25
|
+
"Prove this theorem" → o3 $8.00/M saved 20%
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
ClawRouter is a smart LLM router for [OpenClaw](https://github.com/openclaw/openclaw). It classifies each request, picks the cheapest model that can handle it, and pays per-request via [x402](https://x402.org) USDC micropayments on Base. No account, no API key — your wallet signs each payment.
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# 1. Install — auto-generates a wallet on Base
|
|
34
|
+
openclaw plugin install @blockrun/clawrouter
|
|
35
|
+
|
|
36
|
+
# 2. Fund your wallet with USDC on Base (address printed on install)
|
|
37
|
+
# A few dollars is enough to start — each request costs fractions of a cent
|
|
38
|
+
|
|
39
|
+
# 3. Enable smart routing
|
|
40
|
+
openclaw config set model blockrun/auto
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Every request now routes to the cheapest capable model.
|
|
44
|
+
|
|
45
|
+
Already have a funded wallet? Bring your own: `export BLOCKRUN_WALLET_KEY=0x...`
|
|
46
|
+
|
|
47
|
+
Want a specific model instead? `openclaw config set model openai/gpt-4o` — you still get x402 payments and usage logging.
|
|
48
|
+
|
|
49
|
+
## How Routing Works
|
|
50
|
+
|
|
51
|
+
Hybrid rules-first approach. Heuristic rules handle ~80% of requests in <1ms at zero cost. Only ambiguous queries hit the LLM classifier.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Request → Rule-based scorer (< 1ms, free)
|
|
55
|
+
├── Clear → pick model → done
|
|
56
|
+
└── Ambiguous → LLM classifier (~200ms, ~$0.00003)
|
|
57
|
+
└── classify → pick model → done
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Rules Engine
|
|
61
|
+
|
|
62
|
+
8 scoring dimensions: token count, code presence, reasoning markers, technical terms, creative markers, simple indicators, multi-step patterns, question complexity.
|
|
63
|
+
|
|
64
|
+
Score maps to a tier:
|
|
65
|
+
|
|
66
|
+
| Score | Tier | Primary Model | Output $/M | vs GPT-4o |
|
|
67
|
+
|-------|------|--------------|-----------|-----------|
|
|
68
|
+
| ≤ 0 | SIMPLE | gemini-2.5-flash | $0.60 | **94% cheaper** |
|
|
69
|
+
| 1-2 | *ambiguous* | → LLM classifier | — | — |
|
|
70
|
+
| 3-4 | MEDIUM | deepseek-chat | $0.42 | **96% cheaper** |
|
|
71
|
+
| 5-6 | COMPLEX | claude-sonnet-4 | $15.00 | higher quality |
|
|
72
|
+
| 7+ | REASONING | o3 | $8.00 | **20% cheaper** |
|
|
73
|
+
|
|
74
|
+
### LLM Classifier Fallback
|
|
75
|
+
|
|
76
|
+
When rules score in the ambiguous zone (1-2), ClawRouter sends the first 500 characters to `gemini-2.5-flash` with `max_tokens: 10` and asks for one word: SIMPLE, MEDIUM, COMPLEX, or REASONING. Cost per classification: ~$0.00003. Results cached for 1 hour.
|
|
77
|
+
|
|
78
|
+
### Estimated Savings
|
|
79
|
+
|
|
80
|
+
| Tier | % of Traffic | Output $/M |
|
|
81
|
+
|------|-------------|-----------|
|
|
82
|
+
| SIMPLE | 40% | $0.60 |
|
|
83
|
+
| MEDIUM | 30% | $0.42 |
|
|
84
|
+
| COMPLEX | 20% | $15.00 |
|
|
85
|
+
| REASONING | 10% | $8.00 |
|
|
86
|
+
| **Weighted avg** | | **$3.67/M — 63% savings vs GPT-4o** |
|
|
87
|
+
|
|
88
|
+
Every routed request logs its decision:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
[ClawRouter] deepseek-chat (MEDIUM, rules, confidence=0.85)
|
|
92
|
+
Cost: $0.0004 | Baseline: $0.0095 | Saved: 95.8%
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Models
|
|
96
|
+
|
|
97
|
+
30+ models across 5 providers, all through one wallet:
|
|
98
|
+
|
|
99
|
+
| Model | Input $/M | Output $/M | Context | Reasoning |
|
|
100
|
+
|-------|----------|-----------|---------|:---------:|
|
|
101
|
+
| **OpenAI** | | | | |
|
|
102
|
+
| gpt-5.2 | $1.75 | $14.00 | 400K | * |
|
|
103
|
+
| gpt-5-mini | $0.25 | $2.00 | 200K | |
|
|
104
|
+
| gpt-5-nano | $0.05 | $0.40 | 128K | |
|
|
105
|
+
| gpt-4o | $2.50 | $10.00 | 128K | |
|
|
106
|
+
| gpt-4o-mini | $0.15 | $0.60 | 128K | |
|
|
107
|
+
| o3 | $2.00 | $8.00 | 200K | * |
|
|
108
|
+
| o3-mini | $1.10 | $4.40 | 128K | * |
|
|
109
|
+
| o4-mini | $1.10 | $4.40 | 128K | * |
|
|
110
|
+
| **Anthropic** | | | | |
|
|
111
|
+
| claude-opus-4.5 | $15.00 | $75.00 | 200K | * |
|
|
112
|
+
| claude-sonnet-4 | $3.00 | $15.00 | 200K | * |
|
|
113
|
+
| claude-haiku-4.5 | $1.00 | $5.00 | 200K | |
|
|
114
|
+
| **Google** | | | | |
|
|
115
|
+
| gemini-3-pro-preview | $2.00 | $12.00 | 1M | * |
|
|
116
|
+
| gemini-2.5-pro | $1.25 | $10.00 | 1M | * |
|
|
117
|
+
| gemini-2.5-flash | $0.15 | $0.60 | 1M | |
|
|
118
|
+
| **DeepSeek** | | | | |
|
|
119
|
+
| deepseek-chat | $0.28 | $0.42 | 128K | |
|
|
120
|
+
| deepseek-reasoner | $0.28 | $0.42 | 128K | * |
|
|
121
|
+
| **xAI** | | | | |
|
|
122
|
+
| grok-3 | $3.00 | $15.00 | 131K | * |
|
|
123
|
+
| grok-3-fast | $5.00 | $25.00 | 131K | * |
|
|
124
|
+
| grok-3-mini | $0.30 | $0.50 | 131K | |
|
|
125
|
+
|
|
126
|
+
Full list in [`src/models.ts`](src/models.ts).
|
|
127
|
+
|
|
128
|
+
## Payment
|
|
129
|
+
|
|
130
|
+
No account. No API key. Payment IS authentication via [x402](https://x402.org).
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Request → 402 (price: $0.003) → wallet signs USDC → retry → response
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
USDC stays in your wallet until the moment each request is paid — non-custodial. The price is visible in the 402 response before your wallet signs.
|
|
137
|
+
|
|
138
|
+
**Pricing formula:**
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
Price = (input_tokens × input_rate) + (max_output_tokens × output_rate)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Funding your wallet** — send USDC on Base to your wallet address:
|
|
145
|
+
- Coinbase — buy USDC, send to Base
|
|
146
|
+
- Any CEX — withdraw USDC to Base
|
|
147
|
+
- Bridge — move USDC from any chain to Base
|
|
148
|
+
|
|
149
|
+
## Usage Logging
|
|
150
|
+
|
|
151
|
+
Every routed request is logged as a JSON line:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
~/.openclaw/blockrun/logs/usage-2026-02-03.jsonl
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{"timestamp":"2026-02-03T20:15:30.123Z","model":"google/gemini-2.5-flash","cost":0.000246,"latencyMs":1250}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Configuration
|
|
162
|
+
|
|
163
|
+
### Override Routing
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
# openclaw.yaml
|
|
167
|
+
plugins:
|
|
168
|
+
- id: "@blockrun/clawrouter"
|
|
169
|
+
config:
|
|
170
|
+
routing:
|
|
171
|
+
tiers:
|
|
172
|
+
COMPLEX:
|
|
173
|
+
primary: "openai/gpt-4o"
|
|
174
|
+
SIMPLE:
|
|
175
|
+
primary: "openai/gpt-4o-mini"
|
|
176
|
+
scoring:
|
|
177
|
+
reasoningKeywords: ["proof", "theorem", "formal verification"]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Pin a Model
|
|
181
|
+
|
|
182
|
+
Skip routing. Use one model for everything:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
openclaw config set model openai/gpt-4o
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
You still get x402 payments and usage logging.
|
|
189
|
+
|
|
190
|
+
## Architecture
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
src/
|
|
194
|
+
├── index.ts # Plugin entry — register() + activate()
|
|
195
|
+
├── provider.ts # Registers "blockrun" provider in OpenClaw
|
|
196
|
+
├── proxy.ts # Local HTTP proxy — routing + x402 payment
|
|
197
|
+
├── models.ts # 30+ model definitions with pricing
|
|
198
|
+
├── auth.ts # Wallet key resolution (env, config, prompt)
|
|
199
|
+
├── logger.ts # JSON lines usage logger
|
|
200
|
+
├── types.ts # OpenClaw plugin type definitions
|
|
201
|
+
└── router/
|
|
202
|
+
├── index.ts # route() entry point
|
|
203
|
+
├── rules.ts # Rule-based classifier (8 scoring dimensions)
|
|
204
|
+
├── llm-classifier.ts # LLM fallback (gemini-flash, cached)
|
|
205
|
+
├── selector.ts # Tier → model selection + cost calculation
|
|
206
|
+
├── config.ts # Default routing configuration
|
|
207
|
+
└── types.ts # RoutingDecision, Tier, ScoringResult
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The plugin runs a local HTTP proxy between OpenClaw and BlockRun's API. OpenClaw sees a standard OpenAI-compatible endpoint at `localhost`. Routing is **client-side** — open source and inspectable.
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
OpenClaw Agent
|
|
214
|
+
│
|
|
215
|
+
▼
|
|
216
|
+
ClawRouter (localhost proxy)
|
|
217
|
+
│ ① Classify query (rules → LLM fallback)
|
|
218
|
+
│ ② Pick cheapest capable model
|
|
219
|
+
│ ③ Sign x402 USDC payment
|
|
220
|
+
│
|
|
221
|
+
▼
|
|
222
|
+
BlockRun API → Provider (OpenAI, Anthropic, Google, DeepSeek, xAI)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Programmatic Usage
|
|
226
|
+
|
|
227
|
+
Use ClawRouter as a library without OpenClaw:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
import { startProxy } from "@blockrun/clawrouter";
|
|
231
|
+
|
|
232
|
+
const proxy = await startProxy({
|
|
233
|
+
walletKey: process.env.BLOCKRUN_WALLET_KEY!,
|
|
234
|
+
onReady: (port) => console.log(`Proxy on port ${port}`),
|
|
235
|
+
onRouted: (d) => {
|
|
236
|
+
const saved = (d.savings * 100).toFixed(0);
|
|
237
|
+
console.log(`${d.model} (${d.tier}) saved ${saved}%`);
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Use with any OpenAI-compatible client
|
|
242
|
+
const res = await fetch(`${proxy.baseUrl}/v1/chat/completions`, {
|
|
243
|
+
method: "POST",
|
|
244
|
+
headers: { "Content-Type": "application/json" },
|
|
245
|
+
body: JSON.stringify({
|
|
246
|
+
model: "blockrun/auto",
|
|
247
|
+
messages: [{ role: "user", content: "What is 2+2?" }],
|
|
248
|
+
}),
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
await proxy.close();
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Or use the router directly:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { route, DEFAULT_ROUTING_CONFIG } from "@blockrun/clawrouter";
|
|
258
|
+
|
|
259
|
+
const decision = await route("Prove sqrt(2) is irrational", undefined, 4096, {
|
|
260
|
+
config: DEFAULT_ROUTING_CONFIG,
|
|
261
|
+
modelPricing,
|
|
262
|
+
payFetch,
|
|
263
|
+
apiBase: "https://blockrun.ai/api",
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
console.log(decision);
|
|
267
|
+
// {
|
|
268
|
+
// model: "openai/o3",
|
|
269
|
+
// tier: "REASONING",
|
|
270
|
+
// confidence: 0.9,
|
|
271
|
+
// method: "rules",
|
|
272
|
+
// savings: 0.20,
|
|
273
|
+
// costEstimate: 0.032776,
|
|
274
|
+
// baselineCost: 0.040970,
|
|
275
|
+
// }
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Development
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
git clone https://github.com/BlockRunAI/ClawRouter.git
|
|
282
|
+
cd ClawRouter
|
|
283
|
+
npm install
|
|
284
|
+
npm run build # Build with tsup
|
|
285
|
+
npm run dev # Watch mode
|
|
286
|
+
npm run typecheck # Type check
|
|
287
|
+
|
|
288
|
+
# Run tests
|
|
289
|
+
npx tsup test/e2e.ts --format esm --outDir test/dist --no-dts
|
|
290
|
+
node test/dist/e2e.js
|
|
291
|
+
|
|
292
|
+
# Run with live proxy (requires funded wallet)
|
|
293
|
+
BLOCKRUN_WALLET_KEY=0x... node test/dist/e2e.js
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Roadmap
|
|
297
|
+
|
|
298
|
+
- [x] Provider plugin — one wallet, 30+ models, x402 payment proxy
|
|
299
|
+
- [x] Smart routing — hybrid rules + LLM classifier, 4-tier model selection
|
|
300
|
+
- [x] Usage logging — JSON lines to disk, per-request cost tracking
|
|
301
|
+
- [ ] Graceful fallback — auto-switch on rate limit or provider error
|
|
302
|
+
- [ ] Spend controls — daily/monthly budgets, server-side enforcement
|
|
303
|
+
- [ ] Cost dashboard — analytics at blockrun.ai
|
|
304
|
+
|
|
305
|
+
## Why Not OpenRouter / LiteLLM?
|
|
306
|
+
|
|
307
|
+
They're built for developers — create an account, get an API key, prepay a balance, manage it through a dashboard.
|
|
308
|
+
|
|
309
|
+
ClawRouter is built for **agents**. The difference:
|
|
310
|
+
|
|
311
|
+
| | OpenRouter / LiteLLM | ClawRouter |
|
|
312
|
+
|---|---|---|
|
|
313
|
+
| **Setup** | Human creates account, gets API key | Agent generates wallet, pays per request |
|
|
314
|
+
| **Payment** | Prepaid balance (custodial) | Per-request micropayment (non-custodial) |
|
|
315
|
+
| **Auth** | API key (shared secret) | Wallet signature (cryptographic proof) |
|
|
316
|
+
| **Custody** | Provider holds your money | USDC stays in YOUR wallet until spent |
|
|
317
|
+
| **Routing** | Proprietary / closed | Open source, client-side, inspectable |
|
|
318
|
+
|
|
319
|
+
As agents become autonomous, they need financial infrastructure designed for machines. An agent shouldn't need a human to sign up for a service and paste an API key. It should generate a wallet, receive funds, and pay per request — programmatically.
|
|
320
|
+
|
|
321
|
+
## Test Results
|
|
322
|
+
|
|
323
|
+
Real output from `node test/dist/e2e.js` — routing decisions are made in <1ms:
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
═══ Routing Test Results ═══
|
|
327
|
+
|
|
328
|
+
Simple queries (→ Gemini Flash, 94% savings):
|
|
329
|
+
✓ "What is the capital of France?" → SIMPLE
|
|
330
|
+
✓ "Hello" → SIMPLE
|
|
331
|
+
✓ "Define photosynthesis" → SIMPLE
|
|
332
|
+
✓ "Translate hello to Spanish" → SIMPLE
|
|
333
|
+
|
|
334
|
+
Reasoning queries (→ o3, 20% savings):
|
|
335
|
+
✓ "Prove sqrt(2) is irrational" → REASONING
|
|
336
|
+
✓ "Derive time complexity + prove optimal" → REASONING
|
|
337
|
+
|
|
338
|
+
═══ Full Router (rules-only path) ═══
|
|
339
|
+
|
|
340
|
+
✓ Simple factual → google/gemini-2.5-flash (SIMPLE, rules) saved=94.0%
|
|
341
|
+
✓ Greeting → google/gemini-2.5-flash (SIMPLE, rules) saved=94.0%
|
|
342
|
+
✓ Math proof → openai/o3 (REASONING, rules) saved=20.0%
|
|
343
|
+
|
|
344
|
+
Cost estimate sanity:
|
|
345
|
+
✓ Cost estimate > 0: $0.002458
|
|
346
|
+
✓ Baseline cost > 0: $0.040970
|
|
347
|
+
✓ Savings in range [0,1]: 0.9400
|
|
348
|
+
✓ Cost ($0.002458) <= Baseline ($0.040970)
|
|
349
|
+
|
|
350
|
+
═══ Live Proxy Test ═══
|
|
351
|
+
|
|
352
|
+
✓ Health check: ok
|
|
353
|
+
[routed] google/gemini-2.5-flash (SIMPLE) saved=94.0%
|
|
354
|
+
✓ Response: 2+2 equals 4.
|
|
355
|
+
|
|
356
|
+
═══════════════════════════════════
|
|
357
|
+
21 passed, 0 failed
|
|
358
|
+
═══════════════════════════════════
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Bottom line:** A simple "What is 2+2?" costs **$0.002** instead of **$0.041** — that's **94% savings** on every simple query.
|
|
362
|
+
|
|
363
|
+
## License
|
|
364
|
+
|
|
365
|
+
MIT
|