@blockrun/clawrouter 0.9.19 → 0.9.21

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 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 USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
42
- var USDC_DOMAIN = {
43
- name: "USD Coin",
44
- version: "2",
45
- chainId: BASE_CHAIN_ID,
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 parsePaymentRequired(headerValue) {
64
- const decoded = atob(headerValue);
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
- async function createPaymentPayload(privateKey, fromAddress, recipient, amount, resourceUrl) {
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 + 300;
123
+ const validBefore = now + maxTimeoutSeconds;
71
124
  const nonce = createNonce();
72
125
  const signature = await signTypedData({
73
126
  privateKey,
74
- domain: USDC_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: resourceUrl,
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: "exact",
95
- network: "eip155:8453",
152
+ scheme: option.scheme,
153
+ network,
96
154
  amount,
97
- asset: USDC_BASE,
98
- payTo: recipient,
99
- maxTimeoutSeconds: 300,
100
- extra: { name: "USD Coin", version: "2" }
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 btoa(JSON.stringify(paymentData));
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
- cached.payTo,
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.set("payment-signature", paymentPayload);
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.payTo,
256
+ option,
186
257
  amount,
187
- url
258
+ url,
259
+ paymentRequired.resource
188
260
  );
189
261
  const retryHeaders = new Headers(init?.headers);
190
- retryHeaders.set("payment-signature", paymentPayload);
262
+ setPaymentHeaders(retryHeaders, paymentPayload);
191
263
  return fetch(input, {
192
264
  ...init,
193
265
  headers: retryHeaders
@@ -1128,6 +1200,8 @@ var DEFAULT_ROUTING_CONFIG = {
1128
1200
  primary: "moonshot/kimi-k2.5",
1129
1201
  // $0.50/$2.40 - best quality/price for simple tasks
1130
1202
  fallback: [
1203
+ "minimax/minimax-m2.5",
1204
+ // $0.30/$1.20 - cheap with reasoning
1131
1205
  "google/gemini-2.5-flash",
1132
1206
  // 1M context, cost-effective
1133
1207
  "nvidia/gpt-oss-120b",
@@ -1139,6 +1213,8 @@ var DEFAULT_ROUTING_CONFIG = {
1139
1213
  primary: "xai/grok-code-fast-1",
1140
1214
  // Code specialist, $0.20/$1.50
1141
1215
  fallback: [
1216
+ "minimax/minimax-m2.5",
1217
+ // $0.30/$1.20 - cheap with reasoning
1142
1218
  "google/gemini-2.5-flash",
1143
1219
  // 1M context, cost-effective
1144
1220
  "deepseek/deepseek-chat",
@@ -1153,21 +1229,25 @@ var DEFAULT_ROUTING_CONFIG = {
1153
1229
  "google/gemini-2.5-flash",
1154
1230
  // CRITICAL: 1M context, cheap failsafe before expensive models
1155
1231
  "google/gemini-2.5-pro",
1232
+ "minimax/minimax-m2.5",
1233
+ // $0.30/$1.20 - cheap with reasoning
1156
1234
  "deepseek/deepseek-chat",
1157
1235
  // Another cheap option
1158
1236
  "xai/grok-4-0709",
1159
1237
  "openai/gpt-5.2",
1160
1238
  // Newer and cheaper input than gpt-4o
1161
1239
  "openai/gpt-4o",
1162
- "anthropic/claude-sonnet-4"
1240
+ "anthropic/claude-sonnet-4.6"
1163
1241
  ]
1164
1242
  },
1165
1243
  REASONING: {
1166
1244
  primary: "xai/grok-4-1-fast-reasoning",
1167
1245
  // Upgraded Grok 4.1 reasoning $0.20/$0.50
1168
1246
  fallback: [
1247
+ "minimax/minimax-m2.5",
1248
+ // $0.30/$1.20 - reasoning capable
1169
1249
  "deepseek/deepseek-reasoner",
1170
- // Cheap reasoning model as first fallback
1250
+ // Cheap reasoning model
1171
1251
  "openai/o4-mini",
1172
1252
  // Newer and cheaper than o3 ($1.10 vs $2.00)
1173
1253
  "openai/o3"
@@ -1177,24 +1257,44 @@ var DEFAULT_ROUTING_CONFIG = {
1177
1257
  // Eco tier configs - ultra cost-optimized (blockrun/eco)
1178
1258
  ecoTiers: {
1179
1259
  SIMPLE: {
1180
- primary: "moonshot/kimi-k2.5",
1181
- // $0.50/$2.40
1182
- fallback: ["nvidia/gpt-oss-120b", "deepseek/deepseek-chat", "google/gemini-2.5-flash"]
1260
+ primary: "minimax/minimax-m2.5",
1261
+ // $0.30/$1.20 - cheapest with reasoning
1262
+ fallback: [
1263
+ "moonshot/kimi-k2.5",
1264
+ "nvidia/gpt-oss-120b",
1265
+ "deepseek/deepseek-chat",
1266
+ "google/gemini-2.5-flash"
1267
+ ]
1183
1268
  },
1184
1269
  MEDIUM: {
1185
1270
  primary: "deepseek/deepseek-chat",
1186
1271
  // $0.14/$0.28
1187
- fallback: ["xai/grok-code-fast-1", "google/gemini-2.5-flash", "moonshot/kimi-k2.5"]
1272
+ fallback: [
1273
+ "minimax/minimax-m2.5",
1274
+ // $0.30/$1.20 - cheap with reasoning
1275
+ "xai/grok-code-fast-1",
1276
+ "google/gemini-2.5-flash",
1277
+ "moonshot/kimi-k2.5"
1278
+ ]
1188
1279
  },
1189
1280
  COMPLEX: {
1190
1281
  primary: "xai/grok-4-0709",
1191
1282
  // $0.20/$1.50
1192
- fallback: ["deepseek/deepseek-chat", "google/gemini-2.5-flash", "openai/gpt-4o-mini"]
1283
+ fallback: [
1284
+ "minimax/minimax-m2.5",
1285
+ // $0.30/$1.20 - cheap with reasoning
1286
+ "deepseek/deepseek-chat",
1287
+ "google/gemini-2.5-flash",
1288
+ "openai/gpt-4o-mini"
1289
+ ]
1193
1290
  },
1194
1291
  REASONING: {
1195
- primary: "deepseek/deepseek-reasoner",
1196
- // $0.55/$2.19
1197
- fallback: ["xai/grok-4-1-fast-reasoning"]
1292
+ primary: "minimax/minimax-m2.5",
1293
+ // $0.30/$1.20 - cheapest reasoning model
1294
+ fallback: [
1295
+ "deepseek/deepseek-reasoner",
1296
+ "xai/grok-4-1-fast-reasoning"
1297
+ ]
1198
1298
  }
1199
1299
  },
1200
1300
  // Premium tier configs - best quality (blockrun/premium)
@@ -1212,7 +1312,7 @@ var DEFAULT_ROUTING_CONFIG = {
1212
1312
  "moonshot/kimi-k2.5",
1213
1313
  "google/gemini-2.5-pro",
1214
1314
  "xai/grok-4-0709",
1215
- "anthropic/claude-sonnet-4"
1315
+ "anthropic/claude-sonnet-4.6"
1216
1316
  ]
1217
1317
  },
1218
1318
  COMPLEX: {
@@ -1221,13 +1321,13 @@ var DEFAULT_ROUTING_CONFIG = {
1221
1321
  fallback: [
1222
1322
  "openai/gpt-5.2-codex",
1223
1323
  "anthropic/claude-opus-4.5",
1224
- "anthropic/claude-sonnet-4",
1324
+ "anthropic/claude-sonnet-4.6",
1225
1325
  "google/gemini-3-pro-preview",
1226
1326
  "moonshot/kimi-k2.5"
1227
1327
  ]
1228
1328
  },
1229
1329
  REASONING: {
1230
- primary: "anthropic/claude-sonnet-4",
1330
+ primary: "anthropic/claude-sonnet-4.6",
1231
1331
  // $3/$15 - best for reasoning/instructions
1232
1332
  fallback: [
1233
1333
  "anthropic/claude-opus-4.6",
@@ -1245,6 +1345,8 @@ var DEFAULT_ROUTING_CONFIG = {
1245
1345
  primary: "moonshot/kimi-k2.5",
1246
1346
  // Cheaper than Haiku ($0.5/$2.4 vs $1/$5), larger context
1247
1347
  fallback: [
1348
+ "minimax/minimax-m2.5",
1349
+ // $0.30/$1.20 - agentic capable, cheaper than kimi
1248
1350
  "anthropic/claude-haiku-4.5",
1249
1351
  "xai/grok-4-1-fast-non-reasoning",
1250
1352
  "openai/gpt-4o-mini"
@@ -1253,23 +1355,33 @@ var DEFAULT_ROUTING_CONFIG = {
1253
1355
  MEDIUM: {
1254
1356
  primary: "xai/grok-code-fast-1",
1255
1357
  // Code specialist for agentic coding
1256
- fallback: ["moonshot/kimi-k2.5", "anthropic/claude-haiku-4.5", "anthropic/claude-sonnet-4"]
1358
+ fallback: [
1359
+ "minimax/minimax-m2.5",
1360
+ // $0.30/$1.20 - agentic capable
1361
+ "moonshot/kimi-k2.5",
1362
+ "anthropic/claude-haiku-4.5",
1363
+ "anthropic/claude-sonnet-4.6"
1364
+ ]
1257
1365
  },
1258
1366
  COMPLEX: {
1259
- primary: "anthropic/claude-sonnet-4",
1367
+ primary: "anthropic/claude-sonnet-4.6",
1260
1368
  fallback: [
1261
1369
  "anthropic/claude-opus-4.6",
1262
1370
  // Latest Opus - best agentic
1371
+ "minimax/minimax-m2.5",
1372
+ // $0.30/$1.20 - cheap agentic fallback
1263
1373
  "openai/gpt-5.2",
1264
1374
  "google/gemini-3-pro-preview",
1265
1375
  "xai/grok-4-0709"
1266
1376
  ]
1267
1377
  },
1268
1378
  REASONING: {
1269
- primary: "anthropic/claude-sonnet-4",
1379
+ primary: "anthropic/claude-sonnet-4.6",
1270
1380
  // Strong tool use + reasoning for agentic tasks
1271
1381
  fallback: [
1272
1382
  "anthropic/claude-opus-4.6",
1383
+ "minimax/minimax-m2.5",
1384
+ // $0.30/$1.20 - reasoning + agentic
1273
1385
  "xai/grok-4-1-fast-reasoning",
1274
1386
  "deepseek/deepseek-reasoner"
1275
1387
  ]
@@ -1357,18 +1469,18 @@ function route(prompt, systemPrompt, maxOutputTokens, options) {
1357
1469
  // src/models.ts
1358
1470
  var MODEL_ALIASES = {
1359
1471
  // Claude - short names
1360
- claude: "anthropic/claude-sonnet-4",
1361
- sonnet: "anthropic/claude-sonnet-4",
1472
+ claude: "anthropic/claude-sonnet-4.6",
1473
+ sonnet: "anthropic/claude-sonnet-4.6",
1362
1474
  opus: "anthropic/claude-opus-4.6",
1363
1475
  // Updated to latest Opus 4.6
1364
1476
  "opus-46": "anthropic/claude-opus-4.6",
1365
1477
  "opus-45": "anthropic/claude-opus-4.5",
1366
1478
  haiku: "anthropic/claude-haiku-4.5",
1367
1479
  // Claude - provider/shortname patterns (common in agent frameworks)
1368
- "anthropic/sonnet": "anthropic/claude-sonnet-4",
1480
+ "anthropic/sonnet": "anthropic/claude-sonnet-4.6",
1369
1481
  "anthropic/opus": "anthropic/claude-opus-4.6",
1370
1482
  "anthropic/haiku": "anthropic/claude-haiku-4.5",
1371
- "anthropic/claude": "anthropic/claude-sonnet-4",
1483
+ "anthropic/claude": "anthropic/claude-sonnet-4.6",
1372
1484
  // OpenAI
1373
1485
  gpt: "openai/gpt-4o",
1374
1486
  gpt4: "openai/gpt-4o",
@@ -1390,7 +1502,9 @@ var MODEL_ALIASES = {
1390
1502
  "grok-code": "xai/grok-code-fast-1",
1391
1503
  // NVIDIA
1392
1504
  nvidia: "nvidia/gpt-oss-120b",
1393
- "gpt-120b": "nvidia/gpt-oss-120b"
1505
+ "gpt-120b": "nvidia/gpt-oss-120b",
1506
+ // MiniMax
1507
+ minimax: "minimax/minimax-m2.5"
1394
1508
  // Note: auto, free, eco, premium are virtual routing profiles registered in BLOCKRUN_MODELS
1395
1509
  // They don't need aliases since they're already top-level model IDs
1396
1510
  };
@@ -1564,8 +1678,8 @@ var BLOCKRUN_MODELS = [
1564
1678
  agentic: true
1565
1679
  },
1566
1680
  {
1567
- id: "anthropic/claude-sonnet-4",
1568
- name: "Claude Sonnet 4",
1681
+ id: "anthropic/claude-sonnet-4.6",
1682
+ name: "Claude Sonnet 4.6",
1569
1683
  inputPrice: 3,
1570
1684
  outputPrice: 15,
1571
1685
  contextWindow: 2e5,
@@ -1737,6 +1851,17 @@ var BLOCKRUN_MODELS = [
1737
1851
  reasoning: true
1738
1852
  },
1739
1853
  // grok-2-vision removed - old, 0 transactions
1854
+ // MiniMax
1855
+ {
1856
+ id: "minimax/minimax-m2.5",
1857
+ name: "MiniMax M2.5",
1858
+ inputPrice: 0.3,
1859
+ outputPrice: 1.2,
1860
+ contextWindow: 204800,
1861
+ maxOutput: 16384,
1862
+ reasoning: true,
1863
+ agentic: true
1864
+ },
1740
1865
  // NVIDIA - Free/cheap models
1741
1866
  {
1742
1867
  id: "nvidia/gpt-oss-120b",
@@ -2294,7 +2419,7 @@ var RpcError = class extends Error {
2294
2419
  };
2295
2420
 
2296
2421
  // src/balance.ts
2297
- var USDC_BASE2 = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
2422
+ var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
2298
2423
  var CACHE_TTL_MS = 3e4;
2299
2424
  var BALANCE_THRESHOLDS = {
2300
2425
  /** Low balance warning threshold: $1.00 */
@@ -2393,7 +2518,7 @@ var BalanceMonitor = class {
2393
2518
  async fetchBalance() {
2394
2519
  try {
2395
2520
  const balance = await this.client.readContract({
2396
- address: USDC_BASE2,
2521
+ address: USDC_BASE,
2397
2522
  abi: erc20Abi,
2398
2523
  functionName: "balanceOf",
2399
2524
  args: [this.walletAddress]