@blockrun/clawrouter 0.9.18 → 0.9.20
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 +2 -2
- package/dist/cli.js +116 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +123 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/reinstall.sh +1 -1
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ Choose your routing strategy with `/model <profile>`:
|
|
|
72
72
|
**Other shortcuts:**
|
|
73
73
|
|
|
74
74
|
- **Model aliases:** `/model br-sonnet`, `/model grok`, `/model gpt5`, `/model o3`
|
|
75
|
-
- **Specific models:** `blockrun/openai/gpt-4o` or `blockrun/anthropic/claude-sonnet-4`
|
|
75
|
+
- **Specific models:** `blockrun/openai/gpt-4o` or `blockrun/anthropic/claude-sonnet-4.6`
|
|
76
76
|
- **Bring your wallet:** `export BLOCKRUN_WALLET_KEY=0x...`
|
|
77
77
|
|
|
78
78
|
---
|
|
@@ -186,7 +186,7 @@ Compared to **$25/M** for Claude Opus = **92% savings** on a typical workload.
|
|
|
186
186
|
| o3-mini | $1.10 | $4.40 | 128K | \* |
|
|
187
187
|
| **Anthropic** | | | | |
|
|
188
188
|
| claude-opus-4.5 | $5.00 | $25.00 | 200K | \* |
|
|
189
|
-
| claude-sonnet-4 | $3.00 | $15.00 | 200K | \* |
|
|
189
|
+
| claude-sonnet-4.6 | $3.00 | $15.00 | 200K | \* |
|
|
190
190
|
| claude-haiku-4.5 | $1.00 | $5.00 | 200K | |
|
|
191
191
|
| **Google** | | | | |
|
|
192
192
|
| gemini-2.5-pro | $1.25 | $10.00 | 1M | \* |
|
package/dist/cli.js
CHANGED
|
@@ -38,13 +38,11 @@ var PaymentCache = class {
|
|
|
38
38
|
|
|
39
39
|
// src/x402.ts
|
|
40
40
|
var BASE_CHAIN_ID = 8453;
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
verifyingContract: USDC_BASE
|
|
47
|
-
};
|
|
41
|
+
var BASE_SEPOLIA_CHAIN_ID = 84532;
|
|
42
|
+
var DEFAULT_TOKEN_NAME = "USD Coin";
|
|
43
|
+
var DEFAULT_TOKEN_VERSION = "2";
|
|
44
|
+
var DEFAULT_NETWORK = "eip155:8453";
|
|
45
|
+
var DEFAULT_MAX_TIMEOUT_SECONDS = 300;
|
|
48
46
|
var TRANSFER_TYPES = {
|
|
49
47
|
TransferWithAuthorization: [
|
|
50
48
|
{ name: "from", type: "address" },
|
|
@@ -60,18 +58,78 @@ function createNonce() {
|
|
|
60
58
|
crypto.getRandomValues(bytes);
|
|
61
59
|
return `0x${Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
62
60
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
61
|
+
function decodeBase64Json(value) {
|
|
62
|
+
const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
63
|
+
const padding = (4 - normalized.length % 4) % 4;
|
|
64
|
+
const padded = normalized + "=".repeat(padding);
|
|
65
|
+
const decoded = Buffer.from(padded, "base64").toString("utf8");
|
|
65
66
|
return JSON.parse(decoded);
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
+
function encodeBase64Json(value) {
|
|
69
|
+
return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
|
|
70
|
+
}
|
|
71
|
+
function parsePaymentRequired(headerValue) {
|
|
72
|
+
return decodeBase64Json(headerValue);
|
|
73
|
+
}
|
|
74
|
+
function normalizeNetwork(network) {
|
|
75
|
+
if (!network || network.trim().length === 0) {
|
|
76
|
+
return DEFAULT_NETWORK;
|
|
77
|
+
}
|
|
78
|
+
return network.trim().toLowerCase();
|
|
79
|
+
}
|
|
80
|
+
function resolveChainId(network) {
|
|
81
|
+
const eip155Match = network.match(/^eip155:(\d+)$/i);
|
|
82
|
+
if (eip155Match) {
|
|
83
|
+
const parsed = Number.parseInt(eip155Match[1], 10);
|
|
84
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
85
|
+
return parsed;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (network === "base") return BASE_CHAIN_ID;
|
|
89
|
+
if (network === "base-sepolia") return BASE_SEPOLIA_CHAIN_ID;
|
|
90
|
+
return BASE_CHAIN_ID;
|
|
91
|
+
}
|
|
92
|
+
function parseHexAddress(value) {
|
|
93
|
+
if (!value) return void 0;
|
|
94
|
+
const direct = value.match(/^0x[a-fA-F0-9]{40}$/);
|
|
95
|
+
if (direct) {
|
|
96
|
+
return direct[0];
|
|
97
|
+
}
|
|
98
|
+
const caipSuffix = value.match(/0x[a-fA-F0-9]{40}$/);
|
|
99
|
+
if (caipSuffix) {
|
|
100
|
+
return caipSuffix[0];
|
|
101
|
+
}
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
function requireHexAddress(value, field) {
|
|
105
|
+
const parsed = parseHexAddress(value);
|
|
106
|
+
if (!parsed) {
|
|
107
|
+
throw new Error(`Invalid ${field} in payment requirements: ${String(value)}`);
|
|
108
|
+
}
|
|
109
|
+
return parsed;
|
|
110
|
+
}
|
|
111
|
+
function setPaymentHeaders(headers, payload) {
|
|
112
|
+
headers.set("payment-signature", payload);
|
|
113
|
+
headers.set("x-payment", payload);
|
|
114
|
+
}
|
|
115
|
+
async function createPaymentPayload(privateKey, fromAddress, option, amount, requestUrl, resource) {
|
|
116
|
+
const network = normalizeNetwork(option.network);
|
|
117
|
+
const chainId = resolveChainId(network);
|
|
118
|
+
const recipient = requireHexAddress(option.payTo, "payTo");
|
|
119
|
+
const verifyingContract = requireHexAddress(option.asset, "asset");
|
|
120
|
+
const maxTimeoutSeconds = typeof option.maxTimeoutSeconds === "number" && option.maxTimeoutSeconds > 0 ? Math.floor(option.maxTimeoutSeconds) : DEFAULT_MAX_TIMEOUT_SECONDS;
|
|
68
121
|
const now = Math.floor(Date.now() / 1e3);
|
|
69
122
|
const validAfter = now - 600;
|
|
70
|
-
const validBefore = now +
|
|
123
|
+
const validBefore = now + maxTimeoutSeconds;
|
|
71
124
|
const nonce = createNonce();
|
|
72
125
|
const signature = await signTypedData({
|
|
73
126
|
privateKey,
|
|
74
|
-
domain:
|
|
127
|
+
domain: {
|
|
128
|
+
name: option.extra?.name || DEFAULT_TOKEN_NAME,
|
|
129
|
+
version: option.extra?.version || DEFAULT_TOKEN_VERSION,
|
|
130
|
+
chainId,
|
|
131
|
+
verifyingContract
|
|
132
|
+
},
|
|
75
133
|
types: TRANSFER_TYPES,
|
|
76
134
|
primaryType: "TransferWithAuthorization",
|
|
77
135
|
message: {
|
|
@@ -86,18 +144,18 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
|
|
|
86
144
|
const paymentData = {
|
|
87
145
|
x402Version: 2,
|
|
88
146
|
resource: {
|
|
89
|
-
url:
|
|
90
|
-
description: "BlockRun AI API call",
|
|
147
|
+
url: resource?.url || requestUrl,
|
|
148
|
+
description: resource?.description || "BlockRun AI API call",
|
|
91
149
|
mimeType: "application/json"
|
|
92
150
|
},
|
|
93
151
|
accepted: {
|
|
94
|
-
scheme:
|
|
95
|
-
network
|
|
152
|
+
scheme: option.scheme,
|
|
153
|
+
network,
|
|
96
154
|
amount,
|
|
97
|
-
asset:
|
|
98
|
-
payTo:
|
|
99
|
-
maxTimeoutSeconds:
|
|
100
|
-
extra:
|
|
155
|
+
asset: option.asset,
|
|
156
|
+
payTo: option.payTo,
|
|
157
|
+
maxTimeoutSeconds: option.maxTimeoutSeconds,
|
|
158
|
+
extra: option.extra
|
|
101
159
|
},
|
|
102
160
|
payload: {
|
|
103
161
|
signature,
|
|
@@ -112,7 +170,7 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
|
|
|
112
170
|
},
|
|
113
171
|
extensions: {}
|
|
114
172
|
};
|
|
115
|
-
return
|
|
173
|
+
return encodeBase64Json(paymentData);
|
|
116
174
|
}
|
|
117
175
|
function createPaymentFetch(privateKey) {
|
|
118
176
|
const account = privateKeyToAccount(privateKey);
|
|
@@ -126,12 +184,23 @@ function createPaymentFetch(privateKey) {
|
|
|
126
184
|
const paymentPayload = await createPaymentPayload(
|
|
127
185
|
privateKey,
|
|
128
186
|
walletAddress,
|
|
129
|
-
|
|
187
|
+
{
|
|
188
|
+
scheme: cached.scheme,
|
|
189
|
+
network: cached.network,
|
|
190
|
+
asset: cached.asset,
|
|
191
|
+
payTo: cached.payTo,
|
|
192
|
+
maxTimeoutSeconds: cached.maxTimeoutSeconds,
|
|
193
|
+
extra: cached.extra
|
|
194
|
+
},
|
|
130
195
|
preAuth.estimatedAmount,
|
|
131
|
-
url
|
|
196
|
+
url,
|
|
197
|
+
{
|
|
198
|
+
url: cached.resourceUrl,
|
|
199
|
+
description: cached.resourceDescription
|
|
200
|
+
}
|
|
132
201
|
);
|
|
133
202
|
const preAuthHeaders = new Headers(init?.headers);
|
|
134
|
-
preAuthHeaders
|
|
203
|
+
setPaymentHeaders(preAuthHeaders, paymentPayload);
|
|
135
204
|
const response2 = await fetch(input, { ...init, headers: preAuthHeaders });
|
|
136
205
|
if (response2.status !== 402) {
|
|
137
206
|
return response2;
|
|
@@ -177,17 +246,20 @@ function createPaymentFetch(privateKey) {
|
|
|
177
246
|
scheme: option.scheme,
|
|
178
247
|
network: option.network,
|
|
179
248
|
extra: option.extra,
|
|
180
|
-
maxTimeoutSeconds: option.maxTimeoutSeconds
|
|
249
|
+
maxTimeoutSeconds: option.maxTimeoutSeconds,
|
|
250
|
+
resourceUrl: paymentRequired.resource?.url,
|
|
251
|
+
resourceDescription: paymentRequired.resource?.description
|
|
181
252
|
});
|
|
182
253
|
const paymentPayload = await createPaymentPayload(
|
|
183
254
|
privateKey,
|
|
184
255
|
walletAddress,
|
|
185
|
-
option
|
|
256
|
+
option,
|
|
186
257
|
amount,
|
|
187
|
-
url
|
|
258
|
+
url,
|
|
259
|
+
paymentRequired.resource
|
|
188
260
|
);
|
|
189
261
|
const retryHeaders = new Headers(init?.headers);
|
|
190
|
-
retryHeaders
|
|
262
|
+
setPaymentHeaders(retryHeaders, paymentPayload);
|
|
191
263
|
return fetch(input, {
|
|
192
264
|
...init,
|
|
193
265
|
headers: retryHeaders
|
|
@@ -1159,7 +1231,7 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
1159
1231
|
"openai/gpt-5.2",
|
|
1160
1232
|
// Newer and cheaper input than gpt-4o
|
|
1161
1233
|
"openai/gpt-4o",
|
|
1162
|
-
"anthropic/claude-sonnet-4"
|
|
1234
|
+
"anthropic/claude-sonnet-4.6"
|
|
1163
1235
|
]
|
|
1164
1236
|
},
|
|
1165
1237
|
REASONING: {
|
|
@@ -1212,22 +1284,22 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
1212
1284
|
"moonshot/kimi-k2.5",
|
|
1213
1285
|
"google/gemini-2.5-pro",
|
|
1214
1286
|
"xai/grok-4-0709",
|
|
1215
|
-
"anthropic/claude-sonnet-4"
|
|
1287
|
+
"anthropic/claude-sonnet-4.6"
|
|
1216
1288
|
]
|
|
1217
1289
|
},
|
|
1218
1290
|
COMPLEX: {
|
|
1219
1291
|
primary: "anthropic/claude-opus-4.6",
|
|
1220
1292
|
// Best quality for complex tasks
|
|
1221
1293
|
fallback: [
|
|
1222
|
-
"anthropic/claude-opus-4.5",
|
|
1223
|
-
"anthropic/claude-sonnet-4",
|
|
1224
1294
|
"openai/gpt-5.2-codex",
|
|
1295
|
+
"anthropic/claude-opus-4.5",
|
|
1296
|
+
"anthropic/claude-sonnet-4.6",
|
|
1225
1297
|
"google/gemini-3-pro-preview",
|
|
1226
1298
|
"moonshot/kimi-k2.5"
|
|
1227
1299
|
]
|
|
1228
1300
|
},
|
|
1229
1301
|
REASONING: {
|
|
1230
|
-
primary: "anthropic/claude-sonnet-4",
|
|
1302
|
+
primary: "anthropic/claude-sonnet-4.6",
|
|
1231
1303
|
// $3/$15 - best for reasoning/instructions
|
|
1232
1304
|
fallback: [
|
|
1233
1305
|
"anthropic/claude-opus-4.6",
|
|
@@ -1253,10 +1325,10 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
1253
1325
|
MEDIUM: {
|
|
1254
1326
|
primary: "xai/grok-code-fast-1",
|
|
1255
1327
|
// Code specialist for agentic coding
|
|
1256
|
-
fallback: ["moonshot/kimi-k2.5", "anthropic/claude-haiku-4.5", "anthropic/claude-sonnet-4"]
|
|
1328
|
+
fallback: ["moonshot/kimi-k2.5", "anthropic/claude-haiku-4.5", "anthropic/claude-sonnet-4.6"]
|
|
1257
1329
|
},
|
|
1258
1330
|
COMPLEX: {
|
|
1259
|
-
primary: "anthropic/claude-sonnet-4",
|
|
1331
|
+
primary: "anthropic/claude-sonnet-4.6",
|
|
1260
1332
|
fallback: [
|
|
1261
1333
|
"anthropic/claude-opus-4.6",
|
|
1262
1334
|
// Latest Opus - best agentic
|
|
@@ -1266,7 +1338,7 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
1266
1338
|
]
|
|
1267
1339
|
},
|
|
1268
1340
|
REASONING: {
|
|
1269
|
-
primary: "anthropic/claude-sonnet-4",
|
|
1341
|
+
primary: "anthropic/claude-sonnet-4.6",
|
|
1270
1342
|
// Strong tool use + reasoning for agentic tasks
|
|
1271
1343
|
fallback: [
|
|
1272
1344
|
"anthropic/claude-opus-4.6",
|
|
@@ -1357,18 +1429,18 @@ function route(prompt, systemPrompt, maxOutputTokens, options) {
|
|
|
1357
1429
|
// src/models.ts
|
|
1358
1430
|
var MODEL_ALIASES = {
|
|
1359
1431
|
// Claude - short names
|
|
1360
|
-
claude: "anthropic/claude-sonnet-4",
|
|
1361
|
-
sonnet: "anthropic/claude-sonnet-4",
|
|
1432
|
+
claude: "anthropic/claude-sonnet-4.6",
|
|
1433
|
+
sonnet: "anthropic/claude-sonnet-4.6",
|
|
1362
1434
|
opus: "anthropic/claude-opus-4.6",
|
|
1363
1435
|
// Updated to latest Opus 4.6
|
|
1364
1436
|
"opus-46": "anthropic/claude-opus-4.6",
|
|
1365
1437
|
"opus-45": "anthropic/claude-opus-4.5",
|
|
1366
1438
|
haiku: "anthropic/claude-haiku-4.5",
|
|
1367
1439
|
// Claude - provider/shortname patterns (common in agent frameworks)
|
|
1368
|
-
"anthropic/sonnet": "anthropic/claude-sonnet-4",
|
|
1440
|
+
"anthropic/sonnet": "anthropic/claude-sonnet-4.6",
|
|
1369
1441
|
"anthropic/opus": "anthropic/claude-opus-4.6",
|
|
1370
1442
|
"anthropic/haiku": "anthropic/claude-haiku-4.5",
|
|
1371
|
-
"anthropic/claude": "anthropic/claude-sonnet-4",
|
|
1443
|
+
"anthropic/claude": "anthropic/claude-sonnet-4.6",
|
|
1372
1444
|
// OpenAI
|
|
1373
1445
|
gpt: "openai/gpt-4o",
|
|
1374
1446
|
gpt4: "openai/gpt-4o",
|
|
@@ -1564,8 +1636,8 @@ var BLOCKRUN_MODELS = [
|
|
|
1564
1636
|
agentic: true
|
|
1565
1637
|
},
|
|
1566
1638
|
{
|
|
1567
|
-
id: "anthropic/claude-sonnet-4",
|
|
1568
|
-
name: "Claude Sonnet 4",
|
|
1639
|
+
id: "anthropic/claude-sonnet-4.6",
|
|
1640
|
+
name: "Claude Sonnet 4.6",
|
|
1569
1641
|
inputPrice: 3,
|
|
1570
1642
|
outputPrice: 15,
|
|
1571
1643
|
contextWindow: 2e5,
|
|
@@ -2294,7 +2366,7 @@ var RpcError = class extends Error {
|
|
|
2294
2366
|
};
|
|
2295
2367
|
|
|
2296
2368
|
// src/balance.ts
|
|
2297
|
-
var
|
|
2369
|
+
var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
2298
2370
|
var CACHE_TTL_MS = 3e4;
|
|
2299
2371
|
var BALANCE_THRESHOLDS = {
|
|
2300
2372
|
/** Low balance warning threshold: $1.00 */
|
|
@@ -2393,7 +2465,7 @@ var BalanceMonitor = class {
|
|
|
2393
2465
|
async fetchBalance() {
|
|
2394
2466
|
try {
|
|
2395
2467
|
const balance = await this.client.readContract({
|
|
2396
|
-
address:
|
|
2468
|
+
address: USDC_BASE,
|
|
2397
2469
|
abi: erc20Abi,
|
|
2398
2470
|
functionName: "balanceOf",
|
|
2399
2471
|
args: [this.walletAddress]
|