@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 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
+ [![npm](https://img.shields.io/npm/v/@blockrun/clawrouter.svg)](https://npmjs.com/package/@blockrun/clawrouter)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
12
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://typescriptlang.org)
13
+ [![Node](https://img.shields.io/badge/node-%E2%89%A520-brightgreen.svg)](https://nodejs.org)
14
+
15
+ [Docs](https://blockrun.ai/docs) &middot; [Models](https://blockrun.ai/models) &middot; [Telegram](https://t.me/blockrunAI) &middot; [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