@blockrun/clawrouter 0.12.256 → 0.12.258
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 +28 -26
- package/dist/cli.js +1321 -741
- package/dist/index.d.ts +235 -113
- package/dist/index.js +1307 -727
- package/dist/router/index.js +43 -30
- package/docs/9-free-ai-models-zero-cost-blockrun.md +73 -86
- package/docs/anthropic-cost-savings.md +4 -4
- package/docs/anthropic-third-party-harness-changes.md +3 -3
- package/docs/clawrouter-cuts-llm-api-costs-500x.md +1 -1
- package/docs/clawrouter-vs-openrouter-llm-routing-comparison.md +3 -3
- package/docs/configuration.md +81 -0
- package/docs/features.md +9 -8
- package/docs/routing-profiles.md +24 -22
- package/docs/subscription-failover.md +1 -1
- package/package.json +3 -3
- package/scripts/benchmark.py +2 -2
- package/scripts/reinstall.sh +7 -5
- package/skills/clawrouter/SKILL.md +4 -4
- package/src/top-models.json +8 -4
package/dist/cli.js
CHANGED
|
@@ -27426,8 +27426,8 @@ var init_parseUtil = __esm({
|
|
|
27426
27426
|
init_errors4();
|
|
27427
27427
|
init_en();
|
|
27428
27428
|
makeIssue = (params) => {
|
|
27429
|
-
const { data, path:
|
|
27430
|
-
const fullPath = [...
|
|
27429
|
+
const { data, path: path5, errorMaps, issueData } = params;
|
|
27430
|
+
const fullPath = [...path5, ...issueData.path || []];
|
|
27431
27431
|
const fullIssue = {
|
|
27432
27432
|
...issueData,
|
|
27433
27433
|
path: fullPath
|
|
@@ -27738,11 +27738,11 @@ var init_types = __esm({
|
|
|
27738
27738
|
init_parseUtil();
|
|
27739
27739
|
init_util();
|
|
27740
27740
|
ParseInputLazyPath = class {
|
|
27741
|
-
constructor(parent, value,
|
|
27741
|
+
constructor(parent, value, path5, key2) {
|
|
27742
27742
|
this._cachedPath = [];
|
|
27743
27743
|
this.parent = parent;
|
|
27744
27744
|
this.data = value;
|
|
27745
|
-
this._path =
|
|
27745
|
+
this._path = path5;
|
|
27746
27746
|
this._key = key2;
|
|
27747
27747
|
}
|
|
27748
27748
|
get path() {
|
|
@@ -32235,6 +32235,613 @@ var init_max_tokens = __esm({
|
|
|
32235
32235
|
}
|
|
32236
32236
|
});
|
|
32237
32237
|
|
|
32238
|
+
// src/fs-read.ts
|
|
32239
|
+
import { open } from "fs/promises";
|
|
32240
|
+
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
32241
|
+
async function readTextFile(filePath) {
|
|
32242
|
+
const fh = await open(filePath, "r");
|
|
32243
|
+
try {
|
|
32244
|
+
const size5 = (await fh.stat()).size;
|
|
32245
|
+
const buf = Buffer.alloc(size5);
|
|
32246
|
+
let offset = 0;
|
|
32247
|
+
while (offset < size5) {
|
|
32248
|
+
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
32249
|
+
if (bytesRead === 0) break;
|
|
32250
|
+
offset += bytesRead;
|
|
32251
|
+
}
|
|
32252
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
32253
|
+
} finally {
|
|
32254
|
+
await fh.close();
|
|
32255
|
+
}
|
|
32256
|
+
}
|
|
32257
|
+
function readTextFileSync(filePath) {
|
|
32258
|
+
const fd = openSync(filePath, "r");
|
|
32259
|
+
try {
|
|
32260
|
+
const size5 = fstatSync(fd).size;
|
|
32261
|
+
const buf = Buffer.alloc(size5);
|
|
32262
|
+
let offset = 0;
|
|
32263
|
+
while (offset < size5) {
|
|
32264
|
+
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
32265
|
+
if (bytesRead === 0) break;
|
|
32266
|
+
offset += bytesRead;
|
|
32267
|
+
}
|
|
32268
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
32269
|
+
} finally {
|
|
32270
|
+
closeSync(fd);
|
|
32271
|
+
}
|
|
32272
|
+
}
|
|
32273
|
+
var init_fs_read = __esm({
|
|
32274
|
+
"src/fs-read.ts"() {
|
|
32275
|
+
"use strict";
|
|
32276
|
+
}
|
|
32277
|
+
});
|
|
32278
|
+
|
|
32279
|
+
// src/spend-control.ts
|
|
32280
|
+
import * as fs from "fs";
|
|
32281
|
+
import * as path from "path";
|
|
32282
|
+
import { homedir } from "os";
|
|
32283
|
+
function normalizePayee(value) {
|
|
32284
|
+
return EVM_ADDRESS.test(value) ? value.toLowerCase() : value;
|
|
32285
|
+
}
|
|
32286
|
+
function isAddressList(list) {
|
|
32287
|
+
return ADDRESS_LISTS.includes(list);
|
|
32288
|
+
}
|
|
32289
|
+
function normalizePolicyValues(list, values) {
|
|
32290
|
+
return isAddressList(list) ? values.map(normalizePayee) : [...values];
|
|
32291
|
+
}
|
|
32292
|
+
function isValidPolicyValues(values) {
|
|
32293
|
+
return Array.isArray(values) && values.every((v) => typeof v === "string" && v.length > 0);
|
|
32294
|
+
}
|
|
32295
|
+
function isPolicyList(value) {
|
|
32296
|
+
return POLICY_LISTS.includes(value);
|
|
32297
|
+
}
|
|
32298
|
+
function cloneLimits(limits) {
|
|
32299
|
+
const clone = { ...limits };
|
|
32300
|
+
for (const key2 of POLICY_LISTS) {
|
|
32301
|
+
const val = limits[key2];
|
|
32302
|
+
if (val !== void 0) {
|
|
32303
|
+
clone[key2] = [...val];
|
|
32304
|
+
}
|
|
32305
|
+
}
|
|
32306
|
+
return clone;
|
|
32307
|
+
}
|
|
32308
|
+
function parseQuotedAmountUsd(selected) {
|
|
32309
|
+
const raw = selected.amount ?? selected.maxAmountRequired;
|
|
32310
|
+
if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
|
|
32311
|
+
return void 0;
|
|
32312
|
+
}
|
|
32313
|
+
const micros = Number(raw);
|
|
32314
|
+
if (!Number.isSafeInteger(micros)) {
|
|
32315
|
+
return void 0;
|
|
32316
|
+
}
|
|
32317
|
+
return micros / 1e6;
|
|
32318
|
+
}
|
|
32319
|
+
function assertSpendPolicyAllows(control, selected) {
|
|
32320
|
+
const quoted = parseQuotedAmountUsd(selected);
|
|
32321
|
+
if (quoted === void 0 && control.hasAmountLimits()) {
|
|
32322
|
+
throw new SpendPolicyError(
|
|
32323
|
+
`Payment quote carries no usable amount (${JSON.stringify(
|
|
32324
|
+
selected.amount ?? selected.maxAmountRequired
|
|
32325
|
+
)}); refusing to sign against a configured spend limit`
|
|
32326
|
+
);
|
|
32327
|
+
}
|
|
32328
|
+
const estimatedCost2 = quoted ?? 0;
|
|
32329
|
+
const result = control.check(estimatedCost2, {
|
|
32330
|
+
payTo: selected.payTo,
|
|
32331
|
+
network: selected.network,
|
|
32332
|
+
asset: selected.asset
|
|
32333
|
+
});
|
|
32334
|
+
if (!result.allowed) {
|
|
32335
|
+
throw new SpendPolicyError(result.reason ?? "blocked by spend policy", {
|
|
32336
|
+
blockedBy: result.blockedBy,
|
|
32337
|
+
blockedByPolicy: result.blockedByPolicy
|
|
32338
|
+
});
|
|
32339
|
+
}
|
|
32340
|
+
if (!control.hasAggregateLimits()) {
|
|
32341
|
+
return void 0;
|
|
32342
|
+
}
|
|
32343
|
+
return control.reserve(estimatedCost2);
|
|
32344
|
+
}
|
|
32345
|
+
function registerSpendPolicyHook(x402, control) {
|
|
32346
|
+
const reservations = /* @__PURE__ */ new WeakMap();
|
|
32347
|
+
x402.onBeforePaymentCreation(async (ctx) => {
|
|
32348
|
+
const selected = ctx.selectedRequirements;
|
|
32349
|
+
const reservationId = assertSpendPolicyAllows(control, selected);
|
|
32350
|
+
if (reservationId !== void 0) {
|
|
32351
|
+
reservations.set(ctx.selectedRequirements, reservationId);
|
|
32352
|
+
}
|
|
32353
|
+
});
|
|
32354
|
+
x402.onAfterPaymentCreation(async (ctx) => {
|
|
32355
|
+
const key2 = ctx.selectedRequirements;
|
|
32356
|
+
const id2 = reservations.get(key2);
|
|
32357
|
+
if (id2 !== void 0) {
|
|
32358
|
+
reservations.delete(key2);
|
|
32359
|
+
control.settleReservation(id2, { action: "x402 payment" });
|
|
32360
|
+
}
|
|
32361
|
+
});
|
|
32362
|
+
x402.onPaymentCreationFailure(async (ctx) => {
|
|
32363
|
+
const key2 = ctx.selectedRequirements;
|
|
32364
|
+
const id2 = reservations.get(key2);
|
|
32365
|
+
if (id2 !== void 0) {
|
|
32366
|
+
reservations.delete(key2);
|
|
32367
|
+
control.releaseReservation(id2);
|
|
32368
|
+
}
|
|
32369
|
+
});
|
|
32370
|
+
}
|
|
32371
|
+
function formatDuration(seconds) {
|
|
32372
|
+
if (seconds < 60) {
|
|
32373
|
+
return `${seconds}s`;
|
|
32374
|
+
} else if (seconds < 3600) {
|
|
32375
|
+
const mins = Math.ceil(seconds / 60);
|
|
32376
|
+
return `${mins} min`;
|
|
32377
|
+
} else {
|
|
32378
|
+
const hours = Math.floor(seconds / 3600);
|
|
32379
|
+
const mins = Math.ceil(seconds % 3600 / 60);
|
|
32380
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
32381
|
+
}
|
|
32382
|
+
}
|
|
32383
|
+
var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
|
|
32384
|
+
var init_spend_control = __esm({
|
|
32385
|
+
"src/spend-control.ts"() {
|
|
32386
|
+
"use strict";
|
|
32387
|
+
init_fs_read();
|
|
32388
|
+
WALLET_DIR = path.join(homedir(), ".openclaw", "blockrun");
|
|
32389
|
+
HOUR_MS = 60 * 60 * 1e3;
|
|
32390
|
+
DAY_MS = 24 * HOUR_MS;
|
|
32391
|
+
CAIP2_BASE = "eip155:8453";
|
|
32392
|
+
CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
32393
|
+
POLICY_LISTS = [
|
|
32394
|
+
"allowedPayees",
|
|
32395
|
+
"blockedPayees",
|
|
32396
|
+
"allowedNetworks",
|
|
32397
|
+
"allowedAssets"
|
|
32398
|
+
];
|
|
32399
|
+
ADDRESS_LISTS = ["allowedPayees", "blockedPayees", "allowedAssets"];
|
|
32400
|
+
EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
32401
|
+
MalformedSpendPolicyError = class extends Error {
|
|
32402
|
+
constructor(key2) {
|
|
32403
|
+
super(
|
|
32404
|
+
`[ClawRouter] refusing to load spending.json: ${key2} is malformed; a corrupted policy file must not widen what the agent may pay`
|
|
32405
|
+
);
|
|
32406
|
+
this.name = "MalformedSpendPolicyError";
|
|
32407
|
+
}
|
|
32408
|
+
};
|
|
32409
|
+
FileSpendControlStorage = class {
|
|
32410
|
+
spendingFile;
|
|
32411
|
+
constructor() {
|
|
32412
|
+
this.spendingFile = path.join(WALLET_DIR, "spending.json");
|
|
32413
|
+
}
|
|
32414
|
+
load() {
|
|
32415
|
+
try {
|
|
32416
|
+
if (fs.existsSync(this.spendingFile)) {
|
|
32417
|
+
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
32418
|
+
const rawLimits = data.limits ?? {};
|
|
32419
|
+
const rawHistory = data.history ?? [];
|
|
32420
|
+
const limits = {};
|
|
32421
|
+
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
32422
|
+
const val = rawLimits[key2];
|
|
32423
|
+
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
32424
|
+
limits[key2] = val;
|
|
32425
|
+
}
|
|
32426
|
+
}
|
|
32427
|
+
for (const key2 of POLICY_LISTS) {
|
|
32428
|
+
if (!Object.prototype.hasOwnProperty.call(rawLimits, key2)) continue;
|
|
32429
|
+
const val = rawLimits[key2];
|
|
32430
|
+
if (!isValidPolicyValues(val)) {
|
|
32431
|
+
throw new MalformedSpendPolicyError(key2);
|
|
32432
|
+
}
|
|
32433
|
+
if (val.length === 0) continue;
|
|
32434
|
+
limits[key2] = normalizePolicyValues(key2, val);
|
|
32435
|
+
}
|
|
32436
|
+
const history = [];
|
|
32437
|
+
if (Array.isArray(rawHistory)) {
|
|
32438
|
+
for (const r2 of rawHistory) {
|
|
32439
|
+
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
32440
|
+
history.push({
|
|
32441
|
+
timestamp: r2.timestamp,
|
|
32442
|
+
amount: r2.amount,
|
|
32443
|
+
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
32444
|
+
action: typeof r2.action === "string" ? r2.action : void 0
|
|
32445
|
+
});
|
|
32446
|
+
}
|
|
32447
|
+
}
|
|
32448
|
+
}
|
|
32449
|
+
return { limits, history };
|
|
32450
|
+
}
|
|
32451
|
+
} catch (err) {
|
|
32452
|
+
if (err instanceof MalformedSpendPolicyError) {
|
|
32453
|
+
throw err;
|
|
32454
|
+
}
|
|
32455
|
+
console.error(
|
|
32456
|
+
`[ClawRouter] Failed to load spending data, starting fresh (any configured spend policy is NOT in effect until this file is repaired): ${err}`
|
|
32457
|
+
);
|
|
32458
|
+
}
|
|
32459
|
+
return null;
|
|
32460
|
+
}
|
|
32461
|
+
save(data) {
|
|
32462
|
+
try {
|
|
32463
|
+
if (!fs.existsSync(WALLET_DIR)) {
|
|
32464
|
+
fs.mkdirSync(WALLET_DIR, { recursive: true, mode: 448 });
|
|
32465
|
+
}
|
|
32466
|
+
const tmp = `${this.spendingFile}.${process.pid}.tmp`;
|
|
32467
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
32468
|
+
fs.renameSync(tmp, this.spendingFile);
|
|
32469
|
+
} catch (err) {
|
|
32470
|
+
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
32471
|
+
}
|
|
32472
|
+
}
|
|
32473
|
+
/**
|
|
32474
|
+
* Persist history while leaving the stored limits exactly as they are on
|
|
32475
|
+
* disk. Recording spend must not rewrite policy: the proxy reads limits once
|
|
32476
|
+
* at startup, so writing its in-memory copy back on every payment would
|
|
32477
|
+
* erase an operator's hand-edit to spending.json seconds after they made it.
|
|
32478
|
+
*/
|
|
32479
|
+
saveHistory(history) {
|
|
32480
|
+
let storedLimits = {};
|
|
32481
|
+
try {
|
|
32482
|
+
const current = this.load();
|
|
32483
|
+
if (current) storedLimits = current.limits;
|
|
32484
|
+
} catch {
|
|
32485
|
+
return;
|
|
32486
|
+
}
|
|
32487
|
+
this.save({ limits: storedLimits, history });
|
|
32488
|
+
}
|
|
32489
|
+
};
|
|
32490
|
+
InMemorySpendControlStorage = class {
|
|
32491
|
+
data = null;
|
|
32492
|
+
load() {
|
|
32493
|
+
return this.data ? {
|
|
32494
|
+
limits: cloneLimits(this.data.limits),
|
|
32495
|
+
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
32496
|
+
} : null;
|
|
32497
|
+
}
|
|
32498
|
+
save(data) {
|
|
32499
|
+
this.data = {
|
|
32500
|
+
limits: cloneLimits(data.limits),
|
|
32501
|
+
history: data.history.map((r2) => ({ ...r2 }))
|
|
32502
|
+
};
|
|
32503
|
+
}
|
|
32504
|
+
};
|
|
32505
|
+
RESERVATION_TTL_MS = 2 * 60 * 1e3;
|
|
32506
|
+
SpendControl = class {
|
|
32507
|
+
limits = {};
|
|
32508
|
+
history = [];
|
|
32509
|
+
sessionSpent = 0;
|
|
32510
|
+
sessionCalls = 0;
|
|
32511
|
+
pending = /* @__PURE__ */ new Map();
|
|
32512
|
+
reservationSeq = 0;
|
|
32513
|
+
/** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
|
|
32514
|
+
limitsDirty = false;
|
|
32515
|
+
/** Set when spending.json held an unusable policy list: refuse every payment. */
|
|
32516
|
+
policyFileBroken;
|
|
32517
|
+
storage;
|
|
32518
|
+
now;
|
|
32519
|
+
constructor(options) {
|
|
32520
|
+
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
32521
|
+
this.now = options?.now ?? (() => Date.now());
|
|
32522
|
+
this.load();
|
|
32523
|
+
}
|
|
32524
|
+
setLimit(window2, amount) {
|
|
32525
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
32526
|
+
throw new Error("Limit must be a finite positive number");
|
|
32527
|
+
}
|
|
32528
|
+
this.limits[window2] = amount;
|
|
32529
|
+
this.limitsDirty = true;
|
|
32530
|
+
this.save();
|
|
32531
|
+
}
|
|
32532
|
+
clearLimit(window2) {
|
|
32533
|
+
delete this.limits[window2];
|
|
32534
|
+
this.limitsDirty = true;
|
|
32535
|
+
this.save();
|
|
32536
|
+
}
|
|
32537
|
+
setPolicy(list, values) {
|
|
32538
|
+
if (!isPolicyList(list)) {
|
|
32539
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
32540
|
+
}
|
|
32541
|
+
if (!isValidPolicyValues(values) || values.length === 0) {
|
|
32542
|
+
throw new Error("Policy list must be a non-empty array of non-empty strings");
|
|
32543
|
+
}
|
|
32544
|
+
this.limits[list] = normalizePolicyValues(list, values);
|
|
32545
|
+
this.limitsDirty = true;
|
|
32546
|
+
this.save();
|
|
32547
|
+
}
|
|
32548
|
+
clearPolicy(list) {
|
|
32549
|
+
if (!isPolicyList(list)) {
|
|
32550
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
32551
|
+
}
|
|
32552
|
+
delete this.limits[list];
|
|
32553
|
+
this.limitsDirty = true;
|
|
32554
|
+
this.save();
|
|
32555
|
+
}
|
|
32556
|
+
getLimits() {
|
|
32557
|
+
return cloneLimits(this.limits);
|
|
32558
|
+
}
|
|
32559
|
+
check(estimatedCost2, counterparty) {
|
|
32560
|
+
if (this.policyFileBroken !== void 0) {
|
|
32561
|
+
return {
|
|
32562
|
+
allowed: false,
|
|
32563
|
+
reason: `Spend policy is unreadable, refusing all payments: ${this.policyFileBroken}`
|
|
32564
|
+
};
|
|
32565
|
+
}
|
|
32566
|
+
const payeePolicySet = this.limits.blockedPayees && this.limits.blockedPayees.length > 0 || this.limits.allowedPayees && this.limits.allowedPayees.length > 0;
|
|
32567
|
+
if (payeePolicySet) {
|
|
32568
|
+
if (counterparty?.payTo === void 0) {
|
|
32569
|
+
return {
|
|
32570
|
+
allowed: false,
|
|
32571
|
+
blockedByPolicy: this.limits.blockedPayees?.length ? "blockedPayees" : "allowedPayees",
|
|
32572
|
+
reason: "Payee policy is configured but no payTo was provided to check()"
|
|
32573
|
+
};
|
|
32574
|
+
}
|
|
32575
|
+
const payTo = normalizePayee(counterparty.payTo);
|
|
32576
|
+
if (this.limits.blockedPayees?.includes(payTo)) {
|
|
32577
|
+
return {
|
|
32578
|
+
allowed: false,
|
|
32579
|
+
blockedByPolicy: "blockedPayees",
|
|
32580
|
+
reason: `Payee is blocked by policy: ${counterparty.payTo}`
|
|
32581
|
+
};
|
|
32582
|
+
}
|
|
32583
|
+
if (this.limits.allowedPayees && this.limits.allowedPayees.length > 0 && !this.limits.allowedPayees.includes(payTo)) {
|
|
32584
|
+
return {
|
|
32585
|
+
allowed: false,
|
|
32586
|
+
blockedByPolicy: "allowedPayees",
|
|
32587
|
+
reason: `Payee is not in the configured allowlist: ${counterparty.payTo}`
|
|
32588
|
+
};
|
|
32589
|
+
}
|
|
32590
|
+
}
|
|
32591
|
+
if (this.limits.allowedNetworks && this.limits.allowedNetworks.length > 0) {
|
|
32592
|
+
if (counterparty?.network === void 0) {
|
|
32593
|
+
return {
|
|
32594
|
+
allowed: false,
|
|
32595
|
+
blockedByPolicy: "allowedNetworks",
|
|
32596
|
+
reason: "Network policy is configured but no network was provided to check()"
|
|
32597
|
+
};
|
|
32598
|
+
}
|
|
32599
|
+
if (!this.limits.allowedNetworks.includes(counterparty.network)) {
|
|
32600
|
+
return {
|
|
32601
|
+
allowed: false,
|
|
32602
|
+
blockedByPolicy: "allowedNetworks",
|
|
32603
|
+
reason: `Network is not in the configured allowlist: ${counterparty.network}`
|
|
32604
|
+
};
|
|
32605
|
+
}
|
|
32606
|
+
}
|
|
32607
|
+
if (this.limits.allowedAssets && this.limits.allowedAssets.length > 0) {
|
|
32608
|
+
if (counterparty?.asset === void 0) {
|
|
32609
|
+
return {
|
|
32610
|
+
allowed: false,
|
|
32611
|
+
blockedByPolicy: "allowedAssets",
|
|
32612
|
+
reason: "Asset policy is configured but no asset was provided to check()"
|
|
32613
|
+
};
|
|
32614
|
+
}
|
|
32615
|
+
if (!this.limits.allowedAssets.includes(normalizePayee(counterparty.asset))) {
|
|
32616
|
+
return {
|
|
32617
|
+
allowed: false,
|
|
32618
|
+
blockedByPolicy: "allowedAssets",
|
|
32619
|
+
reason: `Asset is not in the configured allowlist: ${counterparty.asset}`
|
|
32620
|
+
};
|
|
32621
|
+
}
|
|
32622
|
+
}
|
|
32623
|
+
const now2 = this.now();
|
|
32624
|
+
if (this.limits.perRequest !== void 0) {
|
|
32625
|
+
if (estimatedCost2 > this.limits.perRequest) {
|
|
32626
|
+
return {
|
|
32627
|
+
allowed: false,
|
|
32628
|
+
blockedBy: "perRequest",
|
|
32629
|
+
remaining: this.limits.perRequest,
|
|
32630
|
+
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
32631
|
+
};
|
|
32632
|
+
}
|
|
32633
|
+
}
|
|
32634
|
+
if (this.limits.hourly !== void 0) {
|
|
32635
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32636
|
+
const remaining = this.limits.hourly - hourlySpent;
|
|
32637
|
+
if (estimatedCost2 > remaining) {
|
|
32638
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
32639
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
32640
|
+
return {
|
|
32641
|
+
allowed: false,
|
|
32642
|
+
blockedBy: "hourly",
|
|
32643
|
+
remaining,
|
|
32644
|
+
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
32645
|
+
resetIn
|
|
32646
|
+
};
|
|
32647
|
+
}
|
|
32648
|
+
}
|
|
32649
|
+
if (this.limits.daily !== void 0) {
|
|
32650
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32651
|
+
const remaining = this.limits.daily - dailySpent;
|
|
32652
|
+
if (estimatedCost2 > remaining) {
|
|
32653
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
32654
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
32655
|
+
return {
|
|
32656
|
+
allowed: false,
|
|
32657
|
+
blockedBy: "daily",
|
|
32658
|
+
remaining,
|
|
32659
|
+
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
32660
|
+
resetIn
|
|
32661
|
+
};
|
|
32662
|
+
}
|
|
32663
|
+
}
|
|
32664
|
+
if (this.limits.session !== void 0) {
|
|
32665
|
+
const sessionSpent = this.sessionSpent + this.pendingTotal();
|
|
32666
|
+
const remaining = this.limits.session - sessionSpent;
|
|
32667
|
+
if (estimatedCost2 > remaining) {
|
|
32668
|
+
return {
|
|
32669
|
+
allowed: false,
|
|
32670
|
+
blockedBy: "session",
|
|
32671
|
+
remaining,
|
|
32672
|
+
reason: `Session limit exceeded: $${(sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
32673
|
+
};
|
|
32674
|
+
}
|
|
32675
|
+
}
|
|
32676
|
+
return { allowed: true };
|
|
32677
|
+
}
|
|
32678
|
+
record(amount, metadata) {
|
|
32679
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
32680
|
+
throw new Error("Record amount must be a non-negative finite number");
|
|
32681
|
+
}
|
|
32682
|
+
const record = {
|
|
32683
|
+
timestamp: this.now(),
|
|
32684
|
+
amount,
|
|
32685
|
+
model: metadata?.model,
|
|
32686
|
+
action: metadata?.action
|
|
32687
|
+
};
|
|
32688
|
+
this.history.push(record);
|
|
32689
|
+
this.sessionSpent += amount;
|
|
32690
|
+
this.sessionCalls += 1;
|
|
32691
|
+
this.cleanup();
|
|
32692
|
+
this.save();
|
|
32693
|
+
}
|
|
32694
|
+
/** True when any window that this module can compare an amount against is set. */
|
|
32695
|
+
hasAmountLimits() {
|
|
32696
|
+
return this.limits.perRequest !== void 0 || this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
32697
|
+
}
|
|
32698
|
+
/** True when a window spans more than one request, so reservations matter. */
|
|
32699
|
+
hasAggregateLimits() {
|
|
32700
|
+
return this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
32701
|
+
}
|
|
32702
|
+
/**
|
|
32703
|
+
* Hold `amount` against the aggregate windows before a payment is signed.
|
|
32704
|
+
*
|
|
32705
|
+
* Reservations live in memory only and are never persisted: an unsettled
|
|
32706
|
+
* reservation is not spend, and writing it to disk is what made a failed
|
|
32707
|
+
* signer permanently consume budget. They expire on their own so a caller
|
|
32708
|
+
* that never settles or releases (process killed mid-payment, a transport
|
|
32709
|
+
* that hangs past the payment timeout) cannot wedge the window shut.
|
|
32710
|
+
*/
|
|
32711
|
+
reserve(amount) {
|
|
32712
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
32713
|
+
throw new Error("Reservation amount must be a non-negative finite number");
|
|
32714
|
+
}
|
|
32715
|
+
const id2 = `${this.now()}-${this.reservationSeq += 1}`;
|
|
32716
|
+
this.pending.set(id2, { amount, expiresAt: this.now() + RESERVATION_TTL_MS });
|
|
32717
|
+
return id2;
|
|
32718
|
+
}
|
|
32719
|
+
/** Convert a reservation into recorded spend (the payment was signed). */
|
|
32720
|
+
settleReservation(id2, metadata) {
|
|
32721
|
+
const held = this.pending.get(id2);
|
|
32722
|
+
if (!held) return;
|
|
32723
|
+
this.pending.delete(id2);
|
|
32724
|
+
this.record(held.amount, metadata);
|
|
32725
|
+
}
|
|
32726
|
+
/** Drop a reservation without recording spend (the payment was never signed). */
|
|
32727
|
+
releaseReservation(id2) {
|
|
32728
|
+
this.pending.delete(id2);
|
|
32729
|
+
}
|
|
32730
|
+
/** Total currently held but not yet settled. */
|
|
32731
|
+
pendingTotal() {
|
|
32732
|
+
this.expireReservations();
|
|
32733
|
+
let total = 0;
|
|
32734
|
+
for (const held of this.pending.values()) {
|
|
32735
|
+
total += held.amount;
|
|
32736
|
+
}
|
|
32737
|
+
return total;
|
|
32738
|
+
}
|
|
32739
|
+
expireReservations() {
|
|
32740
|
+
const now2 = this.now();
|
|
32741
|
+
for (const [id2, held] of this.pending) {
|
|
32742
|
+
if (held.expiresAt <= now2) {
|
|
32743
|
+
this.pending.delete(id2);
|
|
32744
|
+
}
|
|
32745
|
+
}
|
|
32746
|
+
}
|
|
32747
|
+
getSpendingInWindow(from15, to) {
|
|
32748
|
+
const recorded = this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
32749
|
+
return recorded + (to >= this.now() ? this.pendingTotal() : 0);
|
|
32750
|
+
}
|
|
32751
|
+
getSpending(window2) {
|
|
32752
|
+
const now2 = this.now();
|
|
32753
|
+
switch (window2) {
|
|
32754
|
+
case "hourly":
|
|
32755
|
+
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32756
|
+
case "daily":
|
|
32757
|
+
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32758
|
+
case "session":
|
|
32759
|
+
return this.sessionSpent + this.pendingTotal();
|
|
32760
|
+
}
|
|
32761
|
+
}
|
|
32762
|
+
getRemaining(window2) {
|
|
32763
|
+
const limit = this.limits[window2];
|
|
32764
|
+
if (limit === void 0) return null;
|
|
32765
|
+
return Math.max(0, limit - this.getSpending(window2));
|
|
32766
|
+
}
|
|
32767
|
+
getStatus() {
|
|
32768
|
+
const now2 = this.now();
|
|
32769
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32770
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32771
|
+
return {
|
|
32772
|
+
limits: cloneLimits(this.limits),
|
|
32773
|
+
spending: {
|
|
32774
|
+
hourly: hourlySpent,
|
|
32775
|
+
daily: dailySpent,
|
|
32776
|
+
session: this.sessionSpent
|
|
32777
|
+
},
|
|
32778
|
+
remaining: {
|
|
32779
|
+
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
32780
|
+
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
32781
|
+
session: this.limits.session !== void 0 ? this.limits.session - (this.sessionSpent + this.pendingTotal()) : null
|
|
32782
|
+
},
|
|
32783
|
+
calls: this.sessionCalls
|
|
32784
|
+
};
|
|
32785
|
+
}
|
|
32786
|
+
getHistory(limit) {
|
|
32787
|
+
const records = [...this.history].reverse();
|
|
32788
|
+
return limit ? records.slice(0, limit) : records;
|
|
32789
|
+
}
|
|
32790
|
+
resetSession() {
|
|
32791
|
+
this.sessionSpent = 0;
|
|
32792
|
+
this.sessionCalls = 0;
|
|
32793
|
+
}
|
|
32794
|
+
cleanup() {
|
|
32795
|
+
const cutoff = this.now() - DAY_MS;
|
|
32796
|
+
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
32797
|
+
}
|
|
32798
|
+
save() {
|
|
32799
|
+
if (this.policyFileBroken !== void 0) {
|
|
32800
|
+
return;
|
|
32801
|
+
}
|
|
32802
|
+
if (!this.limitsDirty && this.storage.saveHistory) {
|
|
32803
|
+
this.storage.saveHistory([...this.history]);
|
|
32804
|
+
return;
|
|
32805
|
+
}
|
|
32806
|
+
this.storage.save({
|
|
32807
|
+
limits: cloneLimits(this.limits),
|
|
32808
|
+
history: [...this.history]
|
|
32809
|
+
});
|
|
32810
|
+
}
|
|
32811
|
+
load() {
|
|
32812
|
+
let data;
|
|
32813
|
+
try {
|
|
32814
|
+
data = this.storage.load();
|
|
32815
|
+
} catch (err) {
|
|
32816
|
+
if (!(err instanceof MalformedSpendPolicyError)) throw err;
|
|
32817
|
+
this.policyFileBroken = err.message;
|
|
32818
|
+
console.error(`[ClawRouter] ${err.message}`);
|
|
32819
|
+
console.error(
|
|
32820
|
+
"[ClawRouter] All paid requests will be refused until spending.json is repaired. Free models are unaffected."
|
|
32821
|
+
);
|
|
32822
|
+
return;
|
|
32823
|
+
}
|
|
32824
|
+
if (data) {
|
|
32825
|
+
this.limits = cloneLimits(data.limits);
|
|
32826
|
+
this.history = data.history;
|
|
32827
|
+
this.cleanup();
|
|
32828
|
+
}
|
|
32829
|
+
}
|
|
32830
|
+
};
|
|
32831
|
+
SpendPolicyError = class extends Error {
|
|
32832
|
+
blockedBy;
|
|
32833
|
+
blockedByPolicy;
|
|
32834
|
+
constructor(reason, blocked) {
|
|
32835
|
+
super(`Payment creation aborted: ${reason}`);
|
|
32836
|
+
this.name = "SpendPolicyError";
|
|
32837
|
+
this.blockedBy = blocked?.blockedBy;
|
|
32838
|
+
this.blockedByPolicy = blocked?.blockedByPolicy;
|
|
32839
|
+
}
|
|
32840
|
+
};
|
|
32841
|
+
CANONICAL_AMOUNT = /^\d+$/;
|
|
32842
|
+
}
|
|
32843
|
+
});
|
|
32844
|
+
|
|
32238
32845
|
// src/payment-preauth.ts
|
|
32239
32846
|
function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, options) {
|
|
32240
32847
|
const httpClient = new x402HTTPClient(client);
|
|
@@ -32279,8 +32886,11 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
32279
32886
|
return response2;
|
|
32280
32887
|
}
|
|
32281
32888
|
cache2.delete(cacheKey2);
|
|
32282
|
-
} catch {
|
|
32889
|
+
} catch (err) {
|
|
32283
32890
|
cache2.delete(cacheKey2);
|
|
32891
|
+
if (err instanceof SpendPolicyError) {
|
|
32892
|
+
throw err;
|
|
32893
|
+
}
|
|
32284
32894
|
}
|
|
32285
32895
|
}
|
|
32286
32896
|
const clonedRequest = request2.clone();
|
|
@@ -32324,6 +32934,7 @@ var init_payment_preauth = __esm({
|
|
|
32324
32934
|
"use strict";
|
|
32325
32935
|
init_esm4();
|
|
32326
32936
|
init_max_tokens();
|
|
32937
|
+
init_spend_control();
|
|
32327
32938
|
DEFAULT_TTL_MS = 36e5;
|
|
32328
32939
|
}
|
|
32329
32940
|
});
|
|
@@ -34422,6 +35033,13 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
34422
35033
|
supportsTools: true,
|
|
34423
35034
|
supportsVision: true
|
|
34424
35035
|
},
|
|
35036
|
+
"cohere/north-mini-code": {
|
|
35037
|
+
// supportsTools: not probed — fails closed
|
|
35038
|
+
contextWindow: 256e3,
|
|
35039
|
+
maxOutputTokens: 16384,
|
|
35040
|
+
supportsTools: false,
|
|
35041
|
+
supportsVision: false
|
|
35042
|
+
},
|
|
34425
35043
|
"deepseek/deepseek-chat": {
|
|
34426
35044
|
contextWindow: 1048576,
|
|
34427
35045
|
maxOutputTokens: 65536,
|
|
@@ -34512,8 +35130,15 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
34512
35130
|
supportsTools: true,
|
|
34513
35131
|
supportsVision: true
|
|
34514
35132
|
},
|
|
34515
|
-
"nvidia/
|
|
34516
|
-
// supportsTools:
|
|
35133
|
+
"nvidia/llama-3.2-11b-vision": {
|
|
35134
|
+
// supportsTools: not probed — fails closed
|
|
35135
|
+
contextWindow: 128e3,
|
|
35136
|
+
maxOutputTokens: 16384,
|
|
35137
|
+
supportsTools: false,
|
|
35138
|
+
supportsVision: true
|
|
35139
|
+
},
|
|
35140
|
+
"nvidia/nemotron-3-nano-30b": {
|
|
35141
|
+
// supportsTools: not probed — fails closed
|
|
34517
35142
|
contextWindow: 131072,
|
|
34518
35143
|
maxOutputTokens: 16384,
|
|
34519
35144
|
supportsTools: false,
|
|
@@ -34525,21 +35150,16 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
34525
35150
|
supportsTools: false,
|
|
34526
35151
|
supportsVision: true
|
|
34527
35152
|
},
|
|
34528
|
-
"nvidia/nemotron-
|
|
34529
|
-
// supportsTools:
|
|
34530
|
-
contextWindow:
|
|
34531
|
-
maxOutputTokens: 16384,
|
|
34532
|
-
supportsTools: false,
|
|
34533
|
-
supportsVision: true
|
|
34534
|
-
},
|
|
34535
|
-
"nvidia/nemotron-nano-9b-v2": {
|
|
34536
|
-
contextWindow: 131072,
|
|
35153
|
+
"nvidia/nemotron-3-ultra-550b": {
|
|
35154
|
+
// supportsTools: not probed — fails closed
|
|
35155
|
+
contextWindow: 1e6,
|
|
34537
35156
|
maxOutputTokens: 16384,
|
|
34538
35157
|
supportsTools: false,
|
|
34539
35158
|
supportsVision: false
|
|
34540
35159
|
},
|
|
34541
|
-
"nvidia/
|
|
34542
|
-
|
|
35160
|
+
"nvidia/nemotron-3.5-lightning": {
|
|
35161
|
+
// supportsTools: not probed — fails closed
|
|
35162
|
+
contextWindow: 1e6,
|
|
34543
35163
|
maxOutputTokens: 16384,
|
|
34544
35164
|
supportsTools: false,
|
|
34545
35165
|
supportsVision: false
|
|
@@ -34599,13 +35219,6 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
34599
35219
|
supportsTools: false,
|
|
34600
35220
|
supportsVision: true
|
|
34601
35221
|
},
|
|
34602
|
-
"openai/gpt-5.3": {
|
|
34603
|
-
// supportsTools: gateway unavailable at probe time — fails closed
|
|
34604
|
-
contextWindow: 128e3,
|
|
34605
|
-
maxOutputTokens: 128e3,
|
|
34606
|
-
supportsTools: false,
|
|
34607
|
-
supportsVision: true
|
|
34608
|
-
},
|
|
34609
35222
|
"openai/gpt-5.3-codex": {
|
|
34610
35223
|
// supportsTools: gateway unavailable at probe time — fails closed; override: 2026-08-29 probe: every request (6 plain + 3 tool attempts) returned a gateway 500, so the probe measured an incident, not the model. Codex's function calling is established by the 2026-07 Terminal-Bench / tau2 calibration trajectories in portfolio.ts. Hosts observing the 500s should drop it with RouterOptions.unavailableModels rather than this snapshot claiming the model cannot call tools.
|
|
34611
35224
|
contextWindow: 4e5,
|
|
@@ -34711,6 +35324,13 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
34711
35324
|
supportsTools: true,
|
|
34712
35325
|
supportsVision: false
|
|
34713
35326
|
},
|
|
35327
|
+
"poolside/laguna-xs-2.1": {
|
|
35328
|
+
// supportsTools: not probed — fails closed
|
|
35329
|
+
contextWindow: 131072,
|
|
35330
|
+
maxOutputTokens: 16384,
|
|
35331
|
+
supportsTools: false,
|
|
35332
|
+
supportsVision: false
|
|
35333
|
+
},
|
|
34714
35334
|
"qwen/qwen3.7-flash": {
|
|
34715
35335
|
contextWindow: 1e6,
|
|
34716
35336
|
maxOutputTokens: 65536,
|
|
@@ -36626,8 +37246,8 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36626
37246
|
// $0.20/$1.25, 1M ctx
|
|
36627
37247
|
"google/gemini-2.5-flash-lite",
|
|
36628
37248
|
// $0.10/$0.40
|
|
36629
|
-
"nvidia/
|
|
36630
|
-
// FREE backstop — NVIDIA free tier (probed 2026-08-
|
|
37249
|
+
"nvidia/nemotron-3.5-lightning"
|
|
37250
|
+
// FREE backstop — NVIDIA free tier (probed 2026-08-30)
|
|
36631
37251
|
]
|
|
36632
37252
|
},
|
|
36633
37253
|
MEDIUM: {
|
|
@@ -36716,15 +37336,19 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36716
37336
|
// Eco tier configs - absolute cheapest (blockrun/eco)
|
|
36717
37337
|
ecoTiers: {
|
|
36718
37338
|
SIMPLE: {
|
|
36719
|
-
primary: "nvidia/
|
|
36720
|
-
// FREE — NVIDIA free tier flagship
|
|
37339
|
+
primary: "nvidia/nemotron-3.5-lightning",
|
|
37340
|
+
// FREE — NVIDIA free tier flagship, 1M ctx
|
|
36721
37341
|
fallback: [
|
|
36722
|
-
"nvidia/nemotron-nano-
|
|
36723
|
-
// FREE —
|
|
37342
|
+
"nvidia/nemotron-3-nano-30b",
|
|
37343
|
+
// FREE — fastest free model (~121 tok/s)
|
|
36724
37344
|
// The free head keeps rotting with NVIDIA's hosting (deepseek-v4-flash
|
|
36725
37345
|
// 410 2026-08-12, seed-oss-36b 410 2026-08-03, gpt-oss-120b/20b 400
|
|
36726
|
-
// 2026-08-21
|
|
36727
|
-
//
|
|
37346
|
+
// 2026-08-21, and on 2026-08-30 FOUR of the five visible free models at
|
|
37347
|
+
// once — step-3.7-flash, nemotron-nano-9b-v2 and nemotron-nano-12b-v2-vl
|
|
37348
|
+
// all 410, mistral-nemotron hung). Each retirement retargets the two
|
|
37349
|
+
// free rungs to the current free tier; the paid rungs below never move.
|
|
37350
|
+
// The head follows blockrun's own redirect of the model it replaces, so
|
|
37351
|
+
// the router and the gateway never name different models.
|
|
36728
37352
|
"google/gemini-2.5-flash-lite",
|
|
36729
37353
|
// $0.10/$0.40 — cheapest paid rung
|
|
36730
37354
|
"zai/glm-5.3-flash",
|
|
@@ -36868,7 +37492,7 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36868
37492
|
// strongest open-weight reasoner
|
|
36869
37493
|
"deepseek/deepseek-chat",
|
|
36870
37494
|
// Cheap, reliable
|
|
36871
|
-
"nvidia/
|
|
37495
|
+
"nvidia/nemotron-3.5-lightning"
|
|
36872
37496
|
// NVIDIA free ultimate backstop
|
|
36873
37497
|
]
|
|
36874
37498
|
},
|
|
@@ -36972,7 +37596,7 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36972
37596
|
// retail high-risk 3/3
|
|
36973
37597
|
"deepseek/deepseek-chat",
|
|
36974
37598
|
// cheap, reliable
|
|
36975
|
-
"nvidia/
|
|
37599
|
+
"nvidia/nemotron-3.5-lightning"
|
|
36976
37600
|
// NVIDIA free ultimate backstop
|
|
36977
37601
|
]
|
|
36978
37602
|
},
|
|
@@ -37054,6 +37678,8 @@ var init_top_models = __esm({
|
|
|
37054
37678
|
"xai/grok-4.5",
|
|
37055
37679
|
"xai/grok-4.3",
|
|
37056
37680
|
"xai/grok-build-0.1",
|
|
37681
|
+
"zai/glm-5.3",
|
|
37682
|
+
"zai/glm-5.3-flash",
|
|
37057
37683
|
"zai/glm-5.2",
|
|
37058
37684
|
"zai/glm-5.1",
|
|
37059
37685
|
"zai/glm-5-turbo",
|
|
@@ -37065,11 +37691,13 @@ var init_top_models = __esm({
|
|
|
37065
37691
|
"deepseek/deepseek-v4-pro",
|
|
37066
37692
|
"deepseek/deepseek-chat",
|
|
37067
37693
|
"deepseek/deepseek-reasoner",
|
|
37694
|
+
"free/nemotron-3.5-lightning",
|
|
37695
|
+
"free/nemotron-3-nano-30b",
|
|
37696
|
+
"free/laguna-xs-2.1",
|
|
37697
|
+
"free/north-mini-code",
|
|
37068
37698
|
"free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37069
|
-
"free/
|
|
37070
|
-
"free/
|
|
37071
|
-
"free/nemotron-nano-9b-v2",
|
|
37072
|
-
"free/nemotron-nano-12b-v2-vl"
|
|
37699
|
+
"free/nemotron-3-ultra-550b",
|
|
37700
|
+
"free/llama-3.2-11b-vision"
|
|
37073
37701
|
];
|
|
37074
37702
|
}
|
|
37075
37703
|
});
|
|
@@ -37382,14 +38010,20 @@ var init_models = __esm({
|
|
|
37382
38010
|
"xai/grok-3-fast": "xai/grok-4-fast-reasoning",
|
|
37383
38011
|
// delisted (too expensive)
|
|
37384
38012
|
// NVIDIA — backward compat aliases (nvidia/xxx → free/xxx)
|
|
37385
|
-
// Default free model is
|
|
37386
|
-
// opens the eco SIMPLE tier on. It replaced
|
|
37387
|
-
//
|
|
37388
|
-
//
|
|
37389
|
-
//
|
|
37390
|
-
//
|
|
37391
|
-
//
|
|
37392
|
-
|
|
38013
|
+
// Default free model is nemotron-3.5-lightning — the same model
|
|
38014
|
+
// @blockrun/router-core opens the eco SIMPLE tier on. It replaced
|
|
38015
|
+
// step-3.7-flash on 2026-08-30, when NVIDIA retired FOUR of the five visible
|
|
38016
|
+
// free models in a single sweep (blockrun #448): step-3.7-flash,
|
|
38017
|
+
// nemotron-nano-9b-v2 and nemotron-nano-12b-v2-vl all published 410 Gone, and
|
|
38018
|
+
// mistral-nemotron went the quiet way — still listed, >150s and zero bytes.
|
|
38019
|
+
// We follow blockrun's own retarget of step-3.7-flash rather than picking a
|
|
38020
|
+
// different survivor, so the proxy and the gateway name the same model.
|
|
38021
|
+
//
|
|
38022
|
+
// gpt-oss-120b/20b RECOVERED on the same probe run and are reachable again,
|
|
38023
|
+
// but they stay withheld from blockrun's public catalog over NVIDIA's
|
|
38024
|
+
// prompt-retention terms — so pins that NAME gpt-oss stay routable below and
|
|
38025
|
+
// nothing generic may land on it.
|
|
38026
|
+
nvidia: "free/nemotron-3.5-lightning",
|
|
37393
38027
|
"gpt-120b": "free/gpt-oss-120b",
|
|
37394
38028
|
// names the model itself — gateway redirects
|
|
37395
38029
|
"gpt-20b": "free/gpt-oss-20b",
|
|
@@ -37402,10 +38036,10 @@ var init_models = __esm({
|
|
|
37402
38036
|
// straight to gpt-oss-120b. Ids naming v4-flash itself keep the real id (the
|
|
37403
38037
|
// gateway redirects them); the v3.2/v4-pro ids follow blockrun's retarget
|
|
37404
38038
|
// rather than chaining through a second dead model.
|
|
37405
|
-
"nvidia/deepseek-v3.2": "free/
|
|
37406
|
-
"free/deepseek-v3.2": "free/
|
|
37407
|
-
"nvidia/deepseek-v4-pro": "free/
|
|
37408
|
-
"free/deepseek-v4-pro": "free/
|
|
38039
|
+
"nvidia/deepseek-v3.2": "free/nemotron-3.5-lightning",
|
|
38040
|
+
"free/deepseek-v3.2": "free/nemotron-3.5-lightning",
|
|
38041
|
+
"nvidia/deepseek-v4-pro": "free/nemotron-3.5-lightning",
|
|
38042
|
+
"free/deepseek-v4-pro": "free/nemotron-3.5-lightning",
|
|
37409
38043
|
"nvidia/deepseek-v4-flash": "free/deepseek-v4-flash",
|
|
37410
38044
|
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37411
38045
|
// qwen3-coder-480b retired (NVIDIA EOL 2026-06-14). Its server-side redirect used
|
|
@@ -37432,16 +38066,16 @@ var init_models = __esm({
|
|
|
37432
38066
|
// Retired free IDs → successors (mirror blockrun's 2026-07-17 redirect map:
|
|
37433
38067
|
// ultra-253b redirects to gpt-oss-120b; the two supers have NO server redirect —
|
|
37434
38068
|
// they stay hidden-but-routable, so their pins pass through to the real ids).
|
|
37435
|
-
"nvidia/nemotron-ultra-253b": "free/
|
|
38069
|
+
"nvidia/nemotron-ultra-253b": "free/nemotron-3.5-lightning",
|
|
37436
38070
|
// mistral-large-3-675b un-retired 2026-06-14, then EOL'd for good 2026-07-28:
|
|
37437
38071
|
// blockrun's re-probe got HTTP 410 Gone from NVIDIA on both passes (baa967b).
|
|
37438
38072
|
// Pin stays routable — the gateway redirects it to gpt-oss-120b.
|
|
37439
38073
|
"nvidia/mistral-large-3-675b": "free/mistral-large-3-675b",
|
|
37440
38074
|
"nvidia/qwen3.5-122b-a10b": "free/qwen3.5-122b-a10b",
|
|
37441
38075
|
// devstral-2-123b died upstream; blockrun redirects it to gpt-oss-120b (2026-07-17 map)
|
|
37442
|
-
"nvidia/devstral-2-123b": "free/
|
|
37443
|
-
"free/nemotron-ultra-253b": "free/
|
|
37444
|
-
"free/devstral-2-123b": "free/
|
|
38076
|
+
"nvidia/devstral-2-123b": "free/nemotron-3.5-lightning",
|
|
38077
|
+
"free/nemotron-ultra-253b": "free/nemotron-3.5-lightning",
|
|
38078
|
+
"free/devstral-2-123b": "free/nemotron-3.5-lightning",
|
|
37445
38079
|
// Explicit-ish pins — dead upstream since 2026-07-28, gateway redirects to gpt-oss-120b
|
|
37446
38080
|
"mistral-large": "free/mistral-large-3-675b",
|
|
37447
38081
|
"mistral-large-3-675b": "free/mistral-large-3-675b",
|
|
@@ -37452,74 +38086,124 @@ var init_models = __esm({
|
|
|
37452
38086
|
// gateway's retarget (blockrun's /free-deepseek page points at gpt-oss-120b
|
|
37453
38087
|
// too). Shorthands naming v4-flash itself stay on the real id — the gateway
|
|
37454
38088
|
// redirects them, same treatment as seed-oss/mistral-large pins.
|
|
37455
|
-
"deepseek-free": "free/
|
|
37456
|
-
"deepseek-v4-pro": "free/
|
|
38089
|
+
"deepseek-free": "free/nemotron-3.5-lightning",
|
|
38090
|
+
"deepseek-v4-pro": "free/nemotron-3.5-lightning",
|
|
37457
38091
|
// free shorthand; pro dead upstream (410)
|
|
37458
38092
|
"deepseek-v4-flash": "free/deepseek-v4-flash",
|
|
37459
|
-
"v4-pro": "free/
|
|
38093
|
+
"v4-pro": "free/nemotron-3.5-lightning",
|
|
37460
38094
|
"v4-flash": "free/deepseek-v4-flash",
|
|
37461
|
-
|
|
37462
|
-
//
|
|
37463
|
-
|
|
38095
|
+
// mistral-nemotron died 2026-08-30 and it was the LAST free Mistral anywhere —
|
|
38096
|
+
// blockrun's own /free-mistral page now says so plainly instead of naming one.
|
|
38097
|
+
// Point the generic shorthand at the free default rather than advertise a
|
|
38098
|
+
// Mistral we cannot serve.
|
|
38099
|
+
"mistral-free": "free/nemotron-3.5-lightning",
|
|
38100
|
+
"glm-free": "free/nemotron-3.5-lightning",
|
|
37464
38101
|
// seed-oss-36b (the prior target) EOL'd 2026-08-03
|
|
37465
|
-
|
|
37466
|
-
//
|
|
38102
|
+
// A free Llama exists again: nemotron-super-49b (Llama-3.3-based) hit 410 on
|
|
38103
|
+
// 2026-08-30, and a 12-model sweep of what NVIDIA still serves found Llama 3.2
|
|
38104
|
+
// 11B Vision as the only one that finishes a real completion.
|
|
38105
|
+
"llama-free": "free/llama-3.2-11b-vision",
|
|
37467
38106
|
// qwen3-coder-480b retired 2026-06-14 → seed-oss-36b, which then EOL'd 2026-08-03.
|
|
37468
38107
|
// Follow the gateway's own retarget rather than chaining to a second dead model.
|
|
37469
|
-
"qwen-coder": "free/
|
|
38108
|
+
"qwen-coder": "free/nemotron-3.5-lightning",
|
|
37470
38109
|
// no live free Qwen; follows the free default
|
|
37471
|
-
"qwen-coder-free": "free/
|
|
37472
|
-
"qwen-thinking": "free/
|
|
38110
|
+
"qwen-coder-free": "free/nemotron-3.5-lightning",
|
|
38111
|
+
"qwen-thinking": "free/nemotron-3.5-lightning",
|
|
37473
38112
|
// qwen3-next died 2026-07-17; no live free Qwen left
|
|
37474
38113
|
"qwen3-next": "free/qwen3-next-80b-a3b-instruct",
|
|
37475
38114
|
// explicit-ish pin — gateway redirects
|
|
37476
38115
|
"qwen3-next-80b": "free/qwen3-next-80b-a3b-instruct",
|
|
37477
|
-
"mistral-small": "free/
|
|
37478
|
-
//
|
|
38116
|
+
"mistral-small": "free/nemotron-3.5-lightning",
|
|
38117
|
+
// no free Mistral left upstream (2026-08-30)
|
|
37479
38118
|
// New live free models (2026-06-14 BlockRun free-tier refresh)
|
|
37480
38119
|
// seed-oss pins name the model itself — kept routable, the gateway redirects them.
|
|
37481
38120
|
"seed-oss": "free/seed-oss-36b",
|
|
37482
38121
|
"seed-oss-36b": "free/seed-oss-36b",
|
|
37483
|
-
|
|
37484
|
-
//
|
|
38122
|
+
// A free coder exists again — two of them, both sub-second. north-mini-code is
|
|
38123
|
+
// the faster (607ms median) and 256K ctx against laguna's 131K.
|
|
38124
|
+
"coder-free": "free/north-mini-code",
|
|
37485
38125
|
"mistral-nemotron": "free/mistral-nemotron",
|
|
37486
38126
|
"step-flash": "free/step-3.7-flash",
|
|
37487
38127
|
"step-3.7-flash": "free/step-3.7-flash",
|
|
37488
|
-
|
|
37489
|
-
|
|
37490
|
-
|
|
37491
|
-
"nano-
|
|
38128
|
+
// nemotron-nano-9b-v2 hit 410 on 2026-08-30; the generic shorthands follow
|
|
38129
|
+
// blockrun's redirect to its replacement, while the 9b-naming pins above stay
|
|
38130
|
+
// on the real id (the gateway resolves them).
|
|
38131
|
+
"nemotron-nano-9b": "free/nemotron-3-nano-30b",
|
|
38132
|
+
"nemotron-nano": "free/nemotron-3-nano-30b",
|
|
38133
|
+
// nemotron-nano-12b-v2-vl hit 410 the same day; vision in, vision out — the
|
|
38134
|
+
// target is blockrun's own, and nano-omni is the only vision-capable free
|
|
38135
|
+
// model left.
|
|
38136
|
+
"nemotron-nano-vl": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
38137
|
+
"nano-vl": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37492
38138
|
// Vision-capable free models
|
|
37493
38139
|
"nemotron-omni": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37494
38140
|
"nano-omni": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37495
38141
|
"vision-free": "free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
37496
38142
|
// Retired shorthand aliases redirect to live successors. The catch-all target
|
|
37497
38143
|
// moved llama-4-maverick → gpt-oss-120b (2026-07-17) → step-3.7-flash
|
|
37498
|
-
// (2026-08-29
|
|
37499
|
-
nemotron: "free/nemotron-3-
|
|
38144
|
+
// (2026-08-29) → nemotron-3.5-lightning (2026-08-30, blockrun #448).
|
|
38145
|
+
nemotron: "free/nemotron-3.5-lightning",
|
|
37500
38146
|
// strongest live Nemotron
|
|
37501
|
-
"nemotron-ultra": "free/
|
|
37502
|
-
"nemotron-253b": "free/
|
|
37503
|
-
"nemotron-super": "free/
|
|
37504
|
-
"nemotron-49b": "free/
|
|
37505
|
-
"nemotron-120b": "free/
|
|
37506
|
-
devstral: "free/
|
|
38147
|
+
"nemotron-ultra": "free/nemotron-3.5-lightning",
|
|
38148
|
+
"nemotron-253b": "free/nemotron-3.5-lightning",
|
|
38149
|
+
"nemotron-super": "free/nemotron-3.5-lightning",
|
|
38150
|
+
"nemotron-49b": "free/nemotron-3.5-lightning",
|
|
38151
|
+
"nemotron-120b": "free/nemotron-3.5-lightning",
|
|
38152
|
+
devstral: "free/nemotron-3.5-lightning",
|
|
37507
38153
|
// seed-oss-36b EOL'd 2026-08-03
|
|
37508
|
-
"devstral-2": "free/
|
|
38154
|
+
"devstral-2": "free/nemotron-3.5-lightning",
|
|
37509
38155
|
maverick: "free/llama-4-maverick",
|
|
37510
38156
|
// explicit-ish pin — gateway redirects
|
|
38157
|
+
// ── The 2026-08-30 free lineup (blockrun #448) ────────────────────────────
|
|
38158
|
+
// nvidia/* bridges for the four NVIDIA-hosted additions.
|
|
38159
|
+
"nvidia/nemotron-3.5-lightning": "free/nemotron-3.5-lightning",
|
|
38160
|
+
"nvidia/nemotron-3-nano-30b": "free/nemotron-3-nano-30b",
|
|
38161
|
+
"nvidia/nemotron-3-ultra-550b": "free/nemotron-3-ultra-550b",
|
|
38162
|
+
"nvidia/llama-3.2-11b-vision": "free/llama-3.2-11b-vision",
|
|
38163
|
+
// The two non-NVIDIA free models keep the `free/` picker convention; their
|
|
38164
|
+
// real upstream ids are accepted as pins and rewritten in toUpstreamModelId
|
|
38165
|
+
// (see FREE_UPSTREAM_OVERRIDES in proxy.ts).
|
|
38166
|
+
"cohere/north-mini-code": "free/north-mini-code",
|
|
38167
|
+
"poolside/laguna-xs-2.1": "free/laguna-xs-2.1",
|
|
38168
|
+
// Shorthands.
|
|
38169
|
+
lightning: "free/nemotron-3.5-lightning",
|
|
38170
|
+
"nemotron-lightning": "free/nemotron-3.5-lightning",
|
|
38171
|
+
"nemotron-3.5-lightning": "free/nemotron-3.5-lightning",
|
|
38172
|
+
"nano-30b": "free/nemotron-3-nano-30b",
|
|
38173
|
+
"nemotron-nano-30b": "free/nemotron-3-nano-30b",
|
|
38174
|
+
"ultra-550b": "free/nemotron-3-ultra-550b",
|
|
38175
|
+
"nemotron-ultra-550b": "free/nemotron-3-ultra-550b",
|
|
38176
|
+
"llama-vision": "free/llama-3.2-11b-vision",
|
|
38177
|
+
"llama-3.2-vision": "free/llama-3.2-11b-vision",
|
|
38178
|
+
"north-mini": "free/north-mini-code",
|
|
38179
|
+
"north-mini-code": "free/north-mini-code",
|
|
38180
|
+
laguna: "free/laguna-xs-2.1",
|
|
38181
|
+
"laguna-xs": "free/laguna-xs-2.1",
|
|
37511
38182
|
// `free` = the free-tier default. Must equal router-core's ecoTiers.SIMPLE
|
|
37512
38183
|
// primary and the head of proxy.ts FREE_MODELS so `/model free`, the eco
|
|
37513
38184
|
// profile and the budget-cap free fallback all agree on one live model.
|
|
37514
|
-
free: "free/
|
|
38185
|
+
free: "free/nemotron-3.5-lightning",
|
|
37515
38186
|
// MiniMax (minimax → current flagship: M3)
|
|
37516
38187
|
minimax: "minimax/minimax-m3",
|
|
37517
38188
|
"minimax-m3": "minimax/minimax-m3",
|
|
37518
38189
|
"minimax-m2.7": "minimax/minimax-m2.7",
|
|
37519
38190
|
"minimax-m2.5": "minimax/minimax-m2.5",
|
|
37520
38191
|
// Z.AI GLM-5
|
|
37521
|
-
glm
|
|
37522
|
-
//
|
|
38192
|
+
// Bare `glm` PROMOTED 5.2 → 5.3 (2026-08-30). Same rule as `opus` 4.8 → 5: the
|
|
38193
|
+
// cost tradeoff is zero — identical $1.40/$4.40 AND an identical 1M ctx /
|
|
38194
|
+
// 131072 maxOutput envelope, so nothing can bill or truncate differently for a
|
|
38195
|
+
// caller who never typed a version. blockrun's own copy already names glm-5.3
|
|
38196
|
+
// the Z.AI flagship, so leaving `glm` on 5.2 would make the proxy disagree
|
|
38197
|
+
// with the gateway it fronts. `glm-5.2` and every other version pin still
|
|
38198
|
+
// resolve to their own model.
|
|
38199
|
+
glm: "zai/glm-5.3",
|
|
38200
|
+
"glm-5.3": "zai/glm-5.3",
|
|
38201
|
+
"glm-5-3": "zai/glm-5.3",
|
|
38202
|
+
// GLM-5.3 Flash — Z.AI's first natively multimodal GLM-5. Also router-core's
|
|
38203
|
+
// eco MEDIUM and COMPLEX primary.
|
|
38204
|
+
"glm-5.3-flash": "zai/glm-5.3-flash",
|
|
38205
|
+
"glm-5-3-flash": "zai/glm-5.3-flash",
|
|
38206
|
+
"glm-flash": "zai/glm-5.3-flash",
|
|
37523
38207
|
"glm-5.2": "zai/glm-5.2",
|
|
37524
38208
|
"glm-5": "zai/glm-5",
|
|
37525
38209
|
"glm-5.1": "zai/glm-5.1",
|
|
@@ -37581,10 +38265,10 @@ var init_models = __esm({
|
|
|
37581
38265
|
},
|
|
37582
38266
|
{
|
|
37583
38267
|
id: "free",
|
|
37584
|
-
name: "Free \u2192
|
|
38268
|
+
name: "Free \u2192 Nemotron 3.5 Lightning",
|
|
37585
38269
|
inputPrice: 0,
|
|
37586
38270
|
outputPrice: 0,
|
|
37587
|
-
contextWindow:
|
|
38271
|
+
contextWindow: 1e6,
|
|
37588
38272
|
maxOutput: 16384,
|
|
37589
38273
|
reasoning: true
|
|
37590
38274
|
},
|
|
@@ -37625,7 +38309,7 @@ var init_models = __esm({
|
|
|
37625
38309
|
inputPrice: 0.25,
|
|
37626
38310
|
outputPrice: 2,
|
|
37627
38311
|
contextWindow: 2e5,
|
|
37628
|
-
maxOutput:
|
|
38312
|
+
maxOutput: 128e3,
|
|
37629
38313
|
toolCalling: true
|
|
37630
38314
|
},
|
|
37631
38315
|
{
|
|
@@ -37635,7 +38319,7 @@ var init_models = __esm({
|
|
|
37635
38319
|
inputPrice: 0.05,
|
|
37636
38320
|
outputPrice: 0.4,
|
|
37637
38321
|
contextWindow: 128e3,
|
|
37638
|
-
maxOutput:
|
|
38322
|
+
maxOutput: 128e3,
|
|
37639
38323
|
toolCalling: true,
|
|
37640
38324
|
deprecated: true,
|
|
37641
38325
|
fallbackModel: "openai/gpt-5.4-nano"
|
|
@@ -37796,7 +38480,7 @@ var init_models = __esm({
|
|
|
37796
38480
|
version: "5.4",
|
|
37797
38481
|
inputPrice: 2.5,
|
|
37798
38482
|
outputPrice: 15,
|
|
37799
|
-
contextWindow:
|
|
38483
|
+
contextWindow: 105e4,
|
|
37800
38484
|
maxOutput: 128e3,
|
|
37801
38485
|
reasoning: true,
|
|
37802
38486
|
vision: true,
|
|
@@ -37821,7 +38505,7 @@ var init_models = __esm({
|
|
|
37821
38505
|
version: "5.4",
|
|
37822
38506
|
inputPrice: 30,
|
|
37823
38507
|
outputPrice: 180,
|
|
37824
|
-
contextWindow:
|
|
38508
|
+
contextWindow: 105e4,
|
|
37825
38509
|
maxOutput: 128e3,
|
|
37826
38510
|
reasoning: true,
|
|
37827
38511
|
vision: true,
|
|
@@ -37834,7 +38518,7 @@ var init_models = __esm({
|
|
|
37834
38518
|
inputPrice: 0.2,
|
|
37835
38519
|
outputPrice: 1.25,
|
|
37836
38520
|
contextWindow: 105e4,
|
|
37837
|
-
maxOutput:
|
|
38521
|
+
maxOutput: 128e3,
|
|
37838
38522
|
toolCalling: true
|
|
37839
38523
|
},
|
|
37840
38524
|
// OpenAI GPT-5.3 Family
|
|
@@ -37845,7 +38529,7 @@ var init_models = __esm({
|
|
|
37845
38529
|
inputPrice: 1.75,
|
|
37846
38530
|
outputPrice: 14,
|
|
37847
38531
|
contextWindow: 128e3,
|
|
37848
|
-
maxOutput:
|
|
38532
|
+
maxOutput: 128e3,
|
|
37849
38533
|
reasoning: true,
|
|
37850
38534
|
vision: true,
|
|
37851
38535
|
agentic: true,
|
|
@@ -37871,7 +38555,7 @@ var init_models = __esm({
|
|
|
37871
38555
|
inputPrice: 2,
|
|
37872
38556
|
outputPrice: 8,
|
|
37873
38557
|
contextWindow: 128e3,
|
|
37874
|
-
maxOutput:
|
|
38558
|
+
maxOutput: 32768,
|
|
37875
38559
|
vision: true,
|
|
37876
38560
|
toolCalling: true
|
|
37877
38561
|
},
|
|
@@ -37882,7 +38566,7 @@ var init_models = __esm({
|
|
|
37882
38566
|
inputPrice: 0.4,
|
|
37883
38567
|
outputPrice: 1.6,
|
|
37884
38568
|
contextWindow: 128e3,
|
|
37885
|
-
maxOutput:
|
|
38569
|
+
maxOutput: 32768,
|
|
37886
38570
|
toolCalling: true
|
|
37887
38571
|
},
|
|
37888
38572
|
{
|
|
@@ -37892,7 +38576,7 @@ var init_models = __esm({
|
|
|
37892
38576
|
inputPrice: 0.1,
|
|
37893
38577
|
outputPrice: 0.4,
|
|
37894
38578
|
contextWindow: 128e3,
|
|
37895
|
-
maxOutput:
|
|
38579
|
+
maxOutput: 32768,
|
|
37896
38580
|
toolCalling: true
|
|
37897
38581
|
},
|
|
37898
38582
|
{
|
|
@@ -37958,7 +38642,7 @@ var init_models = __esm({
|
|
|
37958
38642
|
inputPrice: 1.1,
|
|
37959
38643
|
outputPrice: 4.4,
|
|
37960
38644
|
contextWindow: 128e3,
|
|
37961
|
-
maxOutput:
|
|
38645
|
+
maxOutput: 1e5,
|
|
37962
38646
|
reasoning: true,
|
|
37963
38647
|
toolCalling: true
|
|
37964
38648
|
},
|
|
@@ -37969,7 +38653,7 @@ var init_models = __esm({
|
|
|
37969
38653
|
inputPrice: 1.1,
|
|
37970
38654
|
outputPrice: 4.4,
|
|
37971
38655
|
contextWindow: 128e3,
|
|
37972
|
-
maxOutput:
|
|
38656
|
+
maxOutput: 1e5,
|
|
37973
38657
|
reasoning: true,
|
|
37974
38658
|
toolCalling: true
|
|
37975
38659
|
},
|
|
@@ -37982,7 +38666,7 @@ var init_models = __esm({
|
|
|
37982
38666
|
inputPrice: 1,
|
|
37983
38667
|
outputPrice: 5,
|
|
37984
38668
|
contextWindow: 2e5,
|
|
37985
|
-
maxOutput:
|
|
38669
|
+
maxOutput: 64e3,
|
|
37986
38670
|
vision: true,
|
|
37987
38671
|
agentic: true,
|
|
37988
38672
|
toolCalling: true
|
|
@@ -38006,8 +38690,8 @@ var init_models = __esm({
|
|
|
38006
38690
|
version: "4.6",
|
|
38007
38691
|
inputPrice: 3,
|
|
38008
38692
|
outputPrice: 15,
|
|
38009
|
-
contextWindow:
|
|
38010
|
-
maxOutput:
|
|
38693
|
+
contextWindow: 1e6,
|
|
38694
|
+
maxOutput: 128e3,
|
|
38011
38695
|
reasoning: true,
|
|
38012
38696
|
vision: true,
|
|
38013
38697
|
agentic: true,
|
|
@@ -38037,7 +38721,7 @@ var init_models = __esm({
|
|
|
38037
38721
|
inputPrice: 5,
|
|
38038
38722
|
outputPrice: 25,
|
|
38039
38723
|
contextWindow: 2e5,
|
|
38040
|
-
maxOutput:
|
|
38724
|
+
maxOutput: 64e3,
|
|
38041
38725
|
reasoning: true,
|
|
38042
38726
|
vision: true,
|
|
38043
38727
|
agentic: true,
|
|
@@ -38121,7 +38805,7 @@ var init_models = __esm({
|
|
|
38121
38805
|
version: "3.1",
|
|
38122
38806
|
inputPrice: 2,
|
|
38123
38807
|
outputPrice: 12,
|
|
38124
|
-
contextWindow:
|
|
38808
|
+
contextWindow: 1048576,
|
|
38125
38809
|
maxOutput: 65536,
|
|
38126
38810
|
reasoning: true,
|
|
38127
38811
|
vision: true,
|
|
@@ -38133,7 +38817,7 @@ var init_models = __esm({
|
|
|
38133
38817
|
version: "3.0",
|
|
38134
38818
|
inputPrice: 2,
|
|
38135
38819
|
outputPrice: 12,
|
|
38136
|
-
contextWindow:
|
|
38820
|
+
contextWindow: 1048576,
|
|
38137
38821
|
maxOutput: 65536,
|
|
38138
38822
|
reasoning: true,
|
|
38139
38823
|
vision: true,
|
|
@@ -38185,7 +38869,7 @@ var init_models = __esm({
|
|
|
38185
38869
|
version: "3.0",
|
|
38186
38870
|
inputPrice: 0.5,
|
|
38187
38871
|
outputPrice: 3,
|
|
38188
|
-
contextWindow:
|
|
38872
|
+
contextWindow: 1048576,
|
|
38189
38873
|
maxOutput: 65536,
|
|
38190
38874
|
reasoning: true,
|
|
38191
38875
|
vision: true
|
|
@@ -38196,7 +38880,7 @@ var init_models = __esm({
|
|
|
38196
38880
|
version: "2.5",
|
|
38197
38881
|
inputPrice: 1.25,
|
|
38198
38882
|
outputPrice: 10,
|
|
38199
|
-
contextWindow:
|
|
38883
|
+
contextWindow: 1048576,
|
|
38200
38884
|
maxOutput: 65536,
|
|
38201
38885
|
reasoning: true,
|
|
38202
38886
|
vision: true,
|
|
@@ -38208,7 +38892,7 @@ var init_models = __esm({
|
|
|
38208
38892
|
version: "2.5",
|
|
38209
38893
|
inputPrice: 0.3,
|
|
38210
38894
|
outputPrice: 2.5,
|
|
38211
|
-
contextWindow:
|
|
38895
|
+
contextWindow: 1048576,
|
|
38212
38896
|
maxOutput: 65536,
|
|
38213
38897
|
vision: true,
|
|
38214
38898
|
toolCalling: true
|
|
@@ -38219,7 +38903,7 @@ var init_models = __esm({
|
|
|
38219
38903
|
version: "2.5",
|
|
38220
38904
|
inputPrice: 0.1,
|
|
38221
38905
|
outputPrice: 0.4,
|
|
38222
|
-
contextWindow:
|
|
38906
|
+
contextWindow: 1048576,
|
|
38223
38907
|
maxOutput: 65536,
|
|
38224
38908
|
toolCalling: true
|
|
38225
38909
|
},
|
|
@@ -38229,8 +38913,8 @@ var init_models = __esm({
|
|
|
38229
38913
|
version: "3.1",
|
|
38230
38914
|
inputPrice: 0.25,
|
|
38231
38915
|
outputPrice: 1.5,
|
|
38232
|
-
contextWindow:
|
|
38233
|
-
maxOutput:
|
|
38916
|
+
contextWindow: 1048576,
|
|
38917
|
+
maxOutput: 65536,
|
|
38234
38918
|
toolCalling: true
|
|
38235
38919
|
},
|
|
38236
38920
|
// DeepSeek — V4 family (2026-04-24). The legacy deepseek-chat/reasoner
|
|
@@ -38243,8 +38927,8 @@ var init_models = __esm({
|
|
|
38243
38927
|
version: "4-flash",
|
|
38244
38928
|
inputPrice: 0.14,
|
|
38245
38929
|
outputPrice: 0.28,
|
|
38246
|
-
contextWindow:
|
|
38247
|
-
maxOutput:
|
|
38930
|
+
contextWindow: 1048576,
|
|
38931
|
+
maxOutput: 65536,
|
|
38248
38932
|
toolCalling: true
|
|
38249
38933
|
},
|
|
38250
38934
|
{
|
|
@@ -38253,8 +38937,8 @@ var init_models = __esm({
|
|
|
38253
38937
|
version: "4-flash",
|
|
38254
38938
|
inputPrice: 0.14,
|
|
38255
38939
|
outputPrice: 0.28,
|
|
38256
|
-
contextWindow:
|
|
38257
|
-
maxOutput:
|
|
38940
|
+
contextWindow: 1048576,
|
|
38941
|
+
maxOutput: 65536,
|
|
38258
38942
|
reasoning: true,
|
|
38259
38943
|
toolCalling: true
|
|
38260
38944
|
},
|
|
@@ -38380,7 +39064,7 @@ var init_models = __esm({
|
|
|
38380
39064
|
inputPrice: 0.6,
|
|
38381
39065
|
outputPrice: 3,
|
|
38382
39066
|
contextWindow: 262144,
|
|
38383
|
-
maxOutput:
|
|
39067
|
+
maxOutput: 65536,
|
|
38384
39068
|
reasoning: true,
|
|
38385
39069
|
vision: true,
|
|
38386
39070
|
agentic: true,
|
|
@@ -38393,7 +39077,7 @@ var init_models = __esm({
|
|
|
38393
39077
|
inputPrice: 0.6,
|
|
38394
39078
|
outputPrice: 3,
|
|
38395
39079
|
contextWindow: 262144,
|
|
38396
|
-
maxOutput:
|
|
39080
|
+
maxOutput: 16384,
|
|
38397
39081
|
reasoning: true,
|
|
38398
39082
|
vision: true,
|
|
38399
39083
|
agentic: true,
|
|
@@ -38431,7 +39115,7 @@ var init_models = __esm({
|
|
|
38431
39115
|
version: "4",
|
|
38432
39116
|
inputPrice: 0.2,
|
|
38433
39117
|
outputPrice: 0.5,
|
|
38434
|
-
contextWindow:
|
|
39118
|
+
contextWindow: 2e6,
|
|
38435
39119
|
maxOutput: 16384,
|
|
38436
39120
|
reasoning: true,
|
|
38437
39121
|
toolCalling: true
|
|
@@ -38442,7 +39126,7 @@ var init_models = __esm({
|
|
|
38442
39126
|
version: "4",
|
|
38443
39127
|
inputPrice: 0.2,
|
|
38444
39128
|
outputPrice: 0.5,
|
|
38445
|
-
contextWindow:
|
|
39129
|
+
contextWindow: 2e6,
|
|
38446
39130
|
maxOutput: 16384,
|
|
38447
39131
|
toolCalling: true
|
|
38448
39132
|
},
|
|
@@ -38452,7 +39136,7 @@ var init_models = __esm({
|
|
|
38452
39136
|
version: "4.1",
|
|
38453
39137
|
inputPrice: 0.2,
|
|
38454
39138
|
outputPrice: 0.5,
|
|
38455
|
-
contextWindow:
|
|
39139
|
+
contextWindow: 2e6,
|
|
38456
39140
|
maxOutput: 16384,
|
|
38457
39141
|
reasoning: true,
|
|
38458
39142
|
toolCalling: true
|
|
@@ -38463,7 +39147,7 @@ var init_models = __esm({
|
|
|
38463
39147
|
version: "4.1",
|
|
38464
39148
|
inputPrice: 0.2,
|
|
38465
39149
|
outputPrice: 0.5,
|
|
38466
|
-
contextWindow:
|
|
39150
|
+
contextWindow: 2e6,
|
|
38467
39151
|
maxOutput: 16384,
|
|
38468
39152
|
toolCalling: true
|
|
38469
39153
|
},
|
|
@@ -38475,7 +39159,7 @@ var init_models = __esm({
|
|
|
38475
39159
|
version: "4-0709",
|
|
38476
39160
|
inputPrice: 3,
|
|
38477
39161
|
outputPrice: 15,
|
|
38478
|
-
contextWindow:
|
|
39162
|
+
contextWindow: 256e3,
|
|
38479
39163
|
maxOutput: 16384,
|
|
38480
39164
|
reasoning: true,
|
|
38481
39165
|
toolCalling: true
|
|
@@ -38486,7 +39170,7 @@ var init_models = __esm({
|
|
|
38486
39170
|
version: "2",
|
|
38487
39171
|
inputPrice: 2,
|
|
38488
39172
|
outputPrice: 10,
|
|
38489
|
-
contextWindow:
|
|
39173
|
+
contextWindow: 32768,
|
|
38490
39174
|
maxOutput: 16384,
|
|
38491
39175
|
vision: true,
|
|
38492
39176
|
toolCalling: true
|
|
@@ -38791,7 +39475,13 @@ var init_models = __esm({
|
|
|
38791
39475
|
maxOutput: 16384
|
|
38792
39476
|
},
|
|
38793
39477
|
{
|
|
38794
|
-
// Mistral × NVIDIA hybrid
|
|
39478
|
+
// Mistral × NVIDIA hybrid, 131K context. DEAD 2026-08-30 — the QUIET kind:
|
|
39479
|
+
// NVIDIA still LISTS it but a completion returns zero bytes after >150s on
|
|
39480
|
+
// both of blockrun's probe passes (blockrun #448, the #391 shape). Upstream
|
|
39481
|
+
// hid it and redirects callers to a live workhorse. Entry kept so explicit
|
|
39482
|
+
// pins stay routable; off the picker and the FREE_MODELS cascade.
|
|
39483
|
+
// There is no free Mistral left on NVIDIA — do not point a generic
|
|
39484
|
+
// "a free mistral" shorthand at one.
|
|
38795
39485
|
id: "free/mistral-nemotron",
|
|
38796
39486
|
name: "[Free] Mistral Nemotron",
|
|
38797
39487
|
version: "nemotron",
|
|
@@ -38801,7 +39491,13 @@ var init_models = __esm({
|
|
|
38801
39491
|
maxOutput: 16384
|
|
38802
39492
|
},
|
|
38803
39493
|
{
|
|
38804
|
-
// StepFun Step 3.7 Flash: reasoning-focused, 131K context.
|
|
39494
|
+
// StepFun Step 3.7 Flash: reasoning-focused, 131K context. EOL'd 2026-08-30
|
|
39495
|
+
// — NVIDIA published 410 Gone on both of blockrun's probe passes (#448), in
|
|
39496
|
+
// the same sweep that took nemotron-nano-9b-v2, nemotron-nano-12b-v2-vl and
|
|
39497
|
+
// (hidden) nemotron-super-49b. It had been ClawRouter's free default since
|
|
39498
|
+
// 2026-08-29; the gateway redirects it to nemotron-3.5-lightning, which is
|
|
39499
|
+
// exactly why nothing looked broken. Entry kept so explicit pins stay
|
|
39500
|
+
// routable; off the picker and the FREE_MODELS cascade.
|
|
38805
39501
|
id: "free/step-3.7-flash",
|
|
38806
39502
|
name: "[Free] StepFun Step 3.7 Flash",
|
|
38807
39503
|
version: "3.7-flash",
|
|
@@ -38813,6 +39509,8 @@ var init_models = __esm({
|
|
|
38813
39509
|
},
|
|
38814
39510
|
{
|
|
38815
39511
|
// NVIDIA Nemotron Nano 9B v2: fast lightweight generalist, 131K context.
|
|
39512
|
+
// EOL'd 2026-08-30 (410 Gone, same sweep). Gateway redirects it to
|
|
39513
|
+
// nemotron-3-nano-30b. Entry kept for pins; off the picker and the cascade.
|
|
38816
39514
|
id: "free/nemotron-nano-9b-v2",
|
|
38817
39515
|
name: "[Free] Nemotron Nano 9B v2",
|
|
38818
39516
|
version: "nano-9b-v2",
|
|
@@ -38824,6 +39522,9 @@ var init_models = __esm({
|
|
|
38824
39522
|
},
|
|
38825
39523
|
{
|
|
38826
39524
|
// NVIDIA Nemotron Nano 12B v2 VL: vision-language (text + image), 131K context.
|
|
39525
|
+
// EOL'd 2026-08-30 (410 Gone, same sweep). Gateway redirects it to
|
|
39526
|
+
// nemotron-3-nano-omni, the only vision-capable free model left. Entry kept
|
|
39527
|
+
// for pins; off the picker and the cascade.
|
|
38827
39528
|
id: "free/nemotron-nano-12b-v2-vl",
|
|
38828
39529
|
name: "[Free] Nemotron Nano 12B v2 VL",
|
|
38829
39530
|
version: "nano-12b-v2-vl",
|
|
@@ -38834,9 +39535,155 @@ var init_models = __esm({
|
|
|
38834
39535
|
reasoning: true,
|
|
38835
39536
|
vision: true
|
|
38836
39537
|
},
|
|
39538
|
+
// ── 2026-08-30 free-tier rebuild (blockrun #448) ─────────────────────────
|
|
39539
|
+
// NVIDIA retired FOUR of the five VISIBLE free models in one sweep. blockrun
|
|
39540
|
+
// replaced them and moved two survivors onto OpenRouter's $0 ":free" pool,
|
|
39541
|
+
// taking the visible free set from 5 to 7 and spanning three hosts for the
|
|
39542
|
+
// first time (NVIDIA, OpenRouter, and two non-NVIDIA makers).
|
|
39543
|
+
//
|
|
39544
|
+
// All seven live free models were tool-probed through the gateway on
|
|
39545
|
+
// 2026-08-30 and every one returned a structured `tool_calls` array with
|
|
39546
|
+
// valid JSON args and finish_reason: "tool_calls" (nemotron-3-nano-30b looked
|
|
39547
|
+
// like a textual leak at max_tokens:120 — that was truncation; at 300 it is
|
|
39548
|
+
// structured). The evidence is recorded here on purpose, but `toolCalling` is
|
|
39549
|
+
// deliberately NOT set: no free entry has ever carried it, filterByToolCalling
|
|
39550
|
+
// keeps the free tier out of tool-bearing requests, and the budget pre-check
|
|
39551
|
+
// at proxy.ts:5217 is written on the same assumption. Flipping the tier into
|
|
39552
|
+
// agentic eligibility is its own change with its own evidence bar.
|
|
39553
|
+
{
|
|
39554
|
+
// Nemotron 3.5 Lightning 30B-A3B — the new free default. blockrun's own
|
|
39555
|
+
// redirect target for the retired step-3.7-flash, so following it keeps the
|
|
39556
|
+
// proxy and the gateway naming the same model. Served from OpenRouter's $0
|
|
39557
|
+
// pool (4.9s median vs 16.3s direct) which also publishes a 1M window
|
|
39558
|
+
// against the 131K the NVIDIA NIM path gives; blockrun carries a hidden
|
|
39559
|
+
// "-nim" twin as its fallback. Probed 1.3s with tools.
|
|
39560
|
+
id: "free/nemotron-3.5-lightning",
|
|
39561
|
+
name: "[Free] Nemotron 3.5 Lightning",
|
|
39562
|
+
version: "3.5-lightning",
|
|
39563
|
+
inputPrice: 0,
|
|
39564
|
+
outputPrice: 0,
|
|
39565
|
+
contextWindow: 1e6,
|
|
39566
|
+
maxOutput: 16384,
|
|
39567
|
+
reasoning: true
|
|
39568
|
+
},
|
|
39569
|
+
{
|
|
39570
|
+
// Nemotron 3 Nano 30B-A3B — the fastest free model in the catalog
|
|
39571
|
+
// (~121 tok/s on a realistic workload, not a 16-token ping). Returns
|
|
39572
|
+
// reasoning_content. Also the tertiary rung of blockrun's own free cascade.
|
|
39573
|
+
id: "free/nemotron-3-nano-30b",
|
|
39574
|
+
name: "[Free] Nemotron 3 Nano 30B",
|
|
39575
|
+
version: "3-nano-30b",
|
|
39576
|
+
inputPrice: 0,
|
|
39577
|
+
outputPrice: 0,
|
|
39578
|
+
contextWindow: 131072,
|
|
39579
|
+
maxOutput: 16384,
|
|
39580
|
+
reasoning: true
|
|
39581
|
+
},
|
|
39582
|
+
{
|
|
39583
|
+
// Nemotron 3 Ultra 550B-A55B — the largest free model ever listed, 1M ctx,
|
|
39584
|
+
// reachable ONLY through OpenRouter's $0 pool (build.nvidia.com answers 503).
|
|
39585
|
+
// Deliberately LOW in the cascade: 16.8s on the tools probe, and blockrun
|
|
39586
|
+
// measured 3 of 15 calls coming back as an HTTP 200 carrying an upstream
|
|
39587
|
+
// 502/503 error object instead of choices.
|
|
39588
|
+
id: "free/nemotron-3-ultra-550b",
|
|
39589
|
+
name: "[Free] Nemotron 3 Ultra 550B",
|
|
39590
|
+
version: "3-ultra-550b",
|
|
39591
|
+
inputPrice: 0,
|
|
39592
|
+
outputPrice: 0,
|
|
39593
|
+
contextWindow: 1e6,
|
|
39594
|
+
maxOutput: 16384,
|
|
39595
|
+
reasoning: true
|
|
39596
|
+
},
|
|
39597
|
+
{
|
|
39598
|
+
// Meta Llama 3.2 11B Vision — restores a free Llama after nemotron-super-49b
|
|
39599
|
+
// (Llama-3.3-based) hit NVIDIA's 410 EOL. A 12-model sweep found exactly two
|
|
39600
|
+
// survivors and only the 11B finishes a real completion. Older than the rest
|
|
39601
|
+
// of the tier and deliberately so: it is a real Llama that actually answers.
|
|
39602
|
+
// Slowest in the tier (~18 tok/s) — last rung of the cascade.
|
|
39603
|
+
id: "free/llama-3.2-11b-vision",
|
|
39604
|
+
name: "[Free] Llama 3.2 11B Vision",
|
|
39605
|
+
version: "3.2-11b-vision",
|
|
39606
|
+
inputPrice: 0,
|
|
39607
|
+
outputPrice: 0,
|
|
39608
|
+
contextWindow: 128e3,
|
|
39609
|
+
maxOutput: 16384,
|
|
39610
|
+
vision: true
|
|
39611
|
+
},
|
|
39612
|
+
{
|
|
39613
|
+
// Cohere North Mini Code, on OpenRouter's $0 pool — 607ms median, the
|
|
39614
|
+
// fastest thing in the tier. Emits reasoning_content (content is clean once
|
|
39615
|
+
// the budget is large enough to finish, verified live).
|
|
39616
|
+
// NOTE: NOT an nvidia/* id upstream — see FREE_UPSTREAM_OVERRIDES in proxy.ts.
|
|
39617
|
+
id: "free/north-mini-code",
|
|
39618
|
+
name: "[Free] Cohere North Mini Code",
|
|
39619
|
+
version: "north-mini-code",
|
|
39620
|
+
inputPrice: 0,
|
|
39621
|
+
outputPrice: 0,
|
|
39622
|
+
contextWindow: 256e3,
|
|
39623
|
+
maxOutput: 16384,
|
|
39624
|
+
reasoning: true
|
|
39625
|
+
},
|
|
39626
|
+
{
|
|
39627
|
+
// Poolside Laguna XS 2.1 on OUR NVIDIA key (~161 tok/s). Deliberately not
|
|
39628
|
+
// the OpenRouter twin, which 429s on every attempt — so this rung and
|
|
39629
|
+
// north-mini-code sit on DIFFERENT capacity pools, which is why they are
|
|
39630
|
+
// adjacent in the cascade.
|
|
39631
|
+
// NOTE: NOT an nvidia/* id upstream — see FREE_UPSTREAM_OVERRIDES in proxy.ts.
|
|
39632
|
+
id: "free/laguna-xs-2.1",
|
|
39633
|
+
name: "[Free] Poolside Laguna XS 2.1",
|
|
39634
|
+
version: "xs-2.1",
|
|
39635
|
+
inputPrice: 0,
|
|
39636
|
+
outputPrice: 0,
|
|
39637
|
+
contextWindow: 131072,
|
|
39638
|
+
maxOutput: 16384
|
|
39639
|
+
},
|
|
38837
39640
|
// Z.AI GLM-5 Models
|
|
38838
39641
|
{
|
|
38839
|
-
//
|
|
39642
|
+
// Z.AI's flagship, live-probed by blockrun 2026-08-19 against api.z.ai
|
|
39643
|
+
// (real completion in 2s, content alongside reasoning tokens). $1.40/$4.40,
|
|
39644
|
+
// cached input $0.26, off the international USD price list.
|
|
39645
|
+
// maxOutput is 131072, NOT the 1M context: that is the hard ceiling the API
|
|
39646
|
+
// enforces (error 1210 above it), the same on every GLM-5 SKU.
|
|
39647
|
+
// Thinking is ALWAYS ON here and cannot be disabled.
|
|
39648
|
+
id: "zai/glm-5.3",
|
|
39649
|
+
name: "GLM-5.3",
|
|
39650
|
+
version: "5.3",
|
|
39651
|
+
inputPrice: 1.4,
|
|
39652
|
+
outputPrice: 4.4,
|
|
39653
|
+
contextWindow: 1e6,
|
|
39654
|
+
maxOutput: 131072,
|
|
39655
|
+
reasoning: true,
|
|
39656
|
+
toolCalling: true
|
|
39657
|
+
},
|
|
39658
|
+
{
|
|
39659
|
+
// Z.AI's first natively multimodal GLM-5 — 320B/18B MoE. blockrun probed
|
|
39660
|
+
// text, vision (base64 data URL → correct answer), tools
|
|
39661
|
+
// (finish_reason=tool_calls with well-formed arguments) and streaming live
|
|
39662
|
+
// on 2026-08-27 before listing it.
|
|
39663
|
+
//
|
|
39664
|
+
// MUST be in this catalog, not just router-core's: it is router-core's eco
|
|
39665
|
+
// MEDIUM and COMPLEX primary, and estimateAmount() returns undefined for an
|
|
39666
|
+
// id we do not carry — which makes the request skip the maxCostPerRun filter
|
|
39667
|
+
// AND never accumulate into session cost. An uncatalogued routing target is
|
|
39668
|
+
// a cost-cap hole, not a logging gap.
|
|
39669
|
+
//
|
|
39670
|
+
// Price is the LIST rate. Z.AI is running a 50% launch promo ($0.075/$0.25)
|
|
39671
|
+
// that ENDS 2026-09-09; listing the promo rate would put us under COGS the
|
|
39672
|
+
// morning it lapses. Thinking is always on, as on glm-5.3.
|
|
39673
|
+
id: "zai/glm-5.3-flash",
|
|
39674
|
+
name: "GLM-5.3 Flash",
|
|
39675
|
+
version: "5.3-flash",
|
|
39676
|
+
inputPrice: 0.15,
|
|
39677
|
+
outputPrice: 0.5,
|
|
39678
|
+
contextWindow: 1e6,
|
|
39679
|
+
maxOutput: 131072,
|
|
39680
|
+
reasoning: true,
|
|
39681
|
+
vision: true,
|
|
39682
|
+
toolCalling: true
|
|
39683
|
+
},
|
|
39684
|
+
{
|
|
39685
|
+
// Launched 2026-06-16. Was Z.AI's flagship until glm-5.3 (above) took the
|
|
39686
|
+
// slot on 2026-08-19. 1M-token context,
|
|
38840
39687
|
// beats GPT-5.5 on long-horizon coding at a fraction of the cost.
|
|
38841
39688
|
// Paid per-token at $1.40/$4.40 (same as glm-5.1, cached $0.26).
|
|
38842
39689
|
id: "zai/glm-5.2",
|
|
@@ -38845,7 +39692,7 @@ var init_models = __esm({
|
|
|
38845
39692
|
inputPrice: 1.4,
|
|
38846
39693
|
outputPrice: 4.4,
|
|
38847
39694
|
contextWindow: 1e6,
|
|
38848
|
-
maxOutput:
|
|
39695
|
+
maxOutput: 131072,
|
|
38849
39696
|
reasoning: true,
|
|
38850
39697
|
toolCalling: true
|
|
38851
39698
|
},
|
|
@@ -38908,8 +39755,8 @@ var init_models = __esm({
|
|
|
38908
39755
|
|
|
38909
39756
|
// src/logger.ts
|
|
38910
39757
|
import { appendFile, mkdir } from "fs/promises";
|
|
38911
|
-
import { join as
|
|
38912
|
-
import { homedir } from "os";
|
|
39758
|
+
import { join as join3 } from "path";
|
|
39759
|
+
import { homedir as homedir2 } from "os";
|
|
38913
39760
|
async function ensureDir() {
|
|
38914
39761
|
if (dirReady) return;
|
|
38915
39762
|
await mkdir(LOG_DIR, { recursive: true });
|
|
@@ -38919,7 +39766,7 @@ async function logUsage(entry) {
|
|
|
38919
39766
|
try {
|
|
38920
39767
|
await ensureDir();
|
|
38921
39768
|
const date = entry.timestamp.slice(0, 10);
|
|
38922
|
-
const file =
|
|
39769
|
+
const file = join3(LOG_DIR, `usage-${date}.jsonl`);
|
|
38923
39770
|
await appendFile(file, JSON.stringify(entry) + "\n");
|
|
38924
39771
|
} catch {
|
|
38925
39772
|
}
|
|
@@ -38928,56 +39775,15 @@ var LOG_DIR, dirReady;
|
|
|
38928
39775
|
var init_logger = __esm({
|
|
38929
39776
|
"src/logger.ts"() {
|
|
38930
39777
|
"use strict";
|
|
38931
|
-
LOG_DIR =
|
|
39778
|
+
LOG_DIR = join3(homedir2(), ".openclaw", "blockrun", "logs");
|
|
38932
39779
|
dirReady = false;
|
|
38933
39780
|
}
|
|
38934
39781
|
});
|
|
38935
39782
|
|
|
38936
|
-
// src/fs-read.ts
|
|
38937
|
-
import { open } from "fs/promises";
|
|
38938
|
-
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
38939
|
-
async function readTextFile(filePath) {
|
|
38940
|
-
const fh = await open(filePath, "r");
|
|
38941
|
-
try {
|
|
38942
|
-
const size5 = (await fh.stat()).size;
|
|
38943
|
-
const buf = Buffer.alloc(size5);
|
|
38944
|
-
let offset = 0;
|
|
38945
|
-
while (offset < size5) {
|
|
38946
|
-
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
38947
|
-
if (bytesRead === 0) break;
|
|
38948
|
-
offset += bytesRead;
|
|
38949
|
-
}
|
|
38950
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38951
|
-
} finally {
|
|
38952
|
-
await fh.close();
|
|
38953
|
-
}
|
|
38954
|
-
}
|
|
38955
|
-
function readTextFileSync(filePath) {
|
|
38956
|
-
const fd = openSync(filePath, "r");
|
|
38957
|
-
try {
|
|
38958
|
-
const size5 = fstatSync(fd).size;
|
|
38959
|
-
const buf = Buffer.alloc(size5);
|
|
38960
|
-
let offset = 0;
|
|
38961
|
-
while (offset < size5) {
|
|
38962
|
-
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
38963
|
-
if (bytesRead === 0) break;
|
|
38964
|
-
offset += bytesRead;
|
|
38965
|
-
}
|
|
38966
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38967
|
-
} finally {
|
|
38968
|
-
closeSync(fd);
|
|
38969
|
-
}
|
|
38970
|
-
}
|
|
38971
|
-
var init_fs_read = __esm({
|
|
38972
|
-
"src/fs-read.ts"() {
|
|
38973
|
-
"use strict";
|
|
38974
|
-
}
|
|
38975
|
-
});
|
|
38976
|
-
|
|
38977
39783
|
// src/version.ts
|
|
38978
39784
|
import { createRequire } from "module";
|
|
38979
39785
|
import { fileURLToPath } from "url";
|
|
38980
|
-
import { dirname, join as
|
|
39786
|
+
import { dirname, join as join4 } from "path";
|
|
38981
39787
|
function clientTag() {
|
|
38982
39788
|
const raw = (process.env.CLAWROUTER_CLIENT ?? "").trim();
|
|
38983
39789
|
if (!raw) return "";
|
|
@@ -38991,7 +39797,7 @@ var init_version4 = __esm({
|
|
|
38991
39797
|
__filename2 = fileURLToPath(import.meta.url);
|
|
38992
39798
|
__dirname = dirname(__filename2);
|
|
38993
39799
|
require2 = createRequire(import.meta.url);
|
|
38994
|
-
pkg = require2(
|
|
39800
|
+
pkg = require2(join4(__dirname, "..", "package.json"));
|
|
38995
39801
|
VERSION = pkg.version;
|
|
38996
39802
|
USER_AGENT = `clawrouter/${VERSION}${clientTag()}`;
|
|
38997
39803
|
}
|
|
@@ -38999,8 +39805,8 @@ var init_version4 = __esm({
|
|
|
38999
39805
|
|
|
39000
39806
|
// src/stats.ts
|
|
39001
39807
|
import { readdir, unlink } from "fs/promises";
|
|
39002
|
-
import { join as
|
|
39003
|
-
import { homedir as
|
|
39808
|
+
import { join as join5 } from "path";
|
|
39809
|
+
import { homedir as homedir3 } from "os";
|
|
39004
39810
|
async function parseLogFile(filePath) {
|
|
39005
39811
|
try {
|
|
39006
39812
|
const content = await readTextFile(filePath);
|
|
@@ -39072,7 +39878,7 @@ async function getStats(days = 7) {
|
|
|
39072
39878
|
let totalLatency = 0;
|
|
39073
39879
|
for (const file of filesToRead) {
|
|
39074
39880
|
const date = file.replace("usage-", "").replace(".jsonl", "");
|
|
39075
|
-
const filePath =
|
|
39881
|
+
const filePath = join5(LOG_DIR2, file);
|
|
39076
39882
|
const entries = await parseLogFile(filePath);
|
|
39077
39883
|
if (entries.length === 0) continue;
|
|
39078
39884
|
const dayStats = aggregateDay(date, entries);
|
|
@@ -39191,7 +39997,7 @@ async function formatRecentLogs(days = 1) {
|
|
|
39191
39997
|
const filesToRead = logFiles.slice(0, days);
|
|
39192
39998
|
const allEntries = [];
|
|
39193
39999
|
for (const file of filesToRead) {
|
|
39194
|
-
const entries = await parseLogFile(
|
|
40000
|
+
const entries = await parseLogFile(join5(LOG_DIR2, file));
|
|
39195
40001
|
allEntries.push(...entries);
|
|
39196
40002
|
}
|
|
39197
40003
|
allEntries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
@@ -39236,7 +40042,7 @@ async function clearStats() {
|
|
|
39236
40042
|
try {
|
|
39237
40043
|
const files = await readdir(LOG_DIR2);
|
|
39238
40044
|
const logFiles = files.filter((f) => f.startsWith("usage-") && f.endsWith(".jsonl"));
|
|
39239
|
-
await Promise.all(logFiles.map((f) => unlink(
|
|
40045
|
+
await Promise.all(logFiles.map((f) => unlink(join5(LOG_DIR2, f))));
|
|
39240
40046
|
return { deletedFiles: logFiles.length };
|
|
39241
40047
|
} catch {
|
|
39242
40048
|
return { deletedFiles: 0 };
|
|
@@ -39248,7 +40054,7 @@ var init_stats = __esm({
|
|
|
39248
40054
|
"use strict";
|
|
39249
40055
|
init_fs_read();
|
|
39250
40056
|
init_version4();
|
|
39251
|
-
LOG_DIR2 =
|
|
40057
|
+
LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
|
|
39252
40058
|
}
|
|
39253
40059
|
});
|
|
39254
40060
|
|
|
@@ -43067,7 +43873,7 @@ function alphabet2(letters) {
|
|
|
43067
43873
|
};
|
|
43068
43874
|
}
|
|
43069
43875
|
// @__NO_SIDE_EFFECTS__
|
|
43070
|
-
function
|
|
43876
|
+
function join6(separator = "") {
|
|
43071
43877
|
astr2("join", separator);
|
|
43072
43878
|
return {
|
|
43073
43879
|
encode: (from15) => {
|
|
@@ -43177,7 +43983,7 @@ var genBase58, base58, createBase58check;
|
|
|
43177
43983
|
var init_base3 = __esm({
|
|
43178
43984
|
"node_modules/@scure/base/index.js"() {
|
|
43179
43985
|
"use strict";
|
|
43180
|
-
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */
|
|
43986
|
+
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join6(""));
|
|
43181
43987
|
base58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
|
|
43182
43988
|
createBase58check = (sha25610) => {
|
|
43183
43989
|
afn2(sha25610);
|
|
@@ -43326,14 +44132,14 @@ var init_bip32 = __esm({
|
|
|
43326
44132
|
}
|
|
43327
44133
|
this.pubHash = hash160(this._publicKey);
|
|
43328
44134
|
}
|
|
43329
|
-
derive(
|
|
43330
|
-
if (!/^[mM]'?/.test(
|
|
44135
|
+
derive(path5) {
|
|
44136
|
+
if (!/^[mM]'?/.test(path5)) {
|
|
43331
44137
|
throw new Error('Path must start with "m" or "M"');
|
|
43332
44138
|
}
|
|
43333
|
-
if (/^[mM]'?$/.test(
|
|
44139
|
+
if (/^[mM]'?$/.test(path5)) {
|
|
43334
44140
|
return this;
|
|
43335
44141
|
}
|
|
43336
|
-
const parts =
|
|
44142
|
+
const parts = path5.replace(/^[mM]'?\//, "").split("/");
|
|
43337
44143
|
let child = this;
|
|
43338
44144
|
for (const c of parts) {
|
|
43339
44145
|
const m = /^(\d+)('?)$/.exec(c);
|
|
@@ -51623,14 +52429,14 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
|
|
|
51623
52429
|
} else {
|
|
51624
52430
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
51625
52431
|
}
|
|
51626
|
-
const
|
|
52432
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
51627
52433
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
51628
52434
|
argumentLabel,
|
|
51629
52435
|
keyPath,
|
|
51630
52436
|
methodName,
|
|
51631
|
-
optionalPathLabel:
|
|
52437
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
51632
52438
|
value,
|
|
51633
|
-
...
|
|
52439
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
51634
52440
|
});
|
|
51635
52441
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
|
|
51636
52442
|
return error;
|
|
@@ -56294,14 +57100,14 @@ function createSolanaJsonRpcIntegerOverflowError2(methodName, keyPath, value) {
|
|
|
56294
57100
|
} else {
|
|
56295
57101
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
56296
57102
|
}
|
|
56297
|
-
const
|
|
57103
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
56298
57104
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
56299
57105
|
argumentLabel,
|
|
56300
57106
|
keyPath,
|
|
56301
57107
|
methodName,
|
|
56302
|
-
optionalPathLabel:
|
|
57108
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
56303
57109
|
value,
|
|
56304
|
-
...
|
|
57110
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
56305
57111
|
});
|
|
56306
57112
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError2);
|
|
56307
57113
|
return error;
|
|
@@ -58381,8 +59187,8 @@ __export(auth_exports, {
|
|
|
58381
59187
|
setupSolana: () => setupSolana
|
|
58382
59188
|
});
|
|
58383
59189
|
import { writeFile, mkdir as mkdir2 } from "fs/promises";
|
|
58384
|
-
import { join as
|
|
58385
|
-
import { homedir as
|
|
59190
|
+
import { join as join7 } from "path";
|
|
59191
|
+
import { homedir as homedir4 } from "os";
|
|
58386
59192
|
async function loadSavedWallet() {
|
|
58387
59193
|
try {
|
|
58388
59194
|
const key2 = (await readTextFile(WALLET_FILE)).trim();
|
|
@@ -58431,7 +59237,7 @@ async function loadMnemonic() {
|
|
|
58431
59237
|
return void 0;
|
|
58432
59238
|
}
|
|
58433
59239
|
async function saveMnemonic(mnemonic) {
|
|
58434
|
-
await mkdir2(
|
|
59240
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58435
59241
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58436
59242
|
}
|
|
58437
59243
|
async function generateAndSaveWallet() {
|
|
@@ -58450,7 +59256,7 @@ Then run: npx @blockrun/clawrouter`
|
|
|
58450
59256
|
}
|
|
58451
59257
|
const mnemonic = generateWalletMnemonic();
|
|
58452
59258
|
const derived = deriveAllKeys(mnemonic);
|
|
58453
|
-
await mkdir2(
|
|
59259
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58454
59260
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
58455
59261
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58456
59262
|
try {
|
|
@@ -58583,7 +59389,7 @@ async function recoverWalletFromMnemonic() {
|
|
|
58583
59389
|
console.log(`[ClawRouter] wallet, recovery is safe to proceed.`);
|
|
58584
59390
|
console.log(`[ClawRouter] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`);
|
|
58585
59391
|
console.log(`[ClawRouter]`);
|
|
58586
|
-
await mkdir2(
|
|
59392
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58587
59393
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
58588
59394
|
console.log(`[ClawRouter] \u2713 wallet.key restored at ${WALLET_FILE}`);
|
|
58589
59395
|
console.log(`[ClawRouter] Run: npx @blockrun/clawrouter`);
|
|
@@ -58609,7 +59415,7 @@ async function setupSolana() {
|
|
|
58609
59415
|
return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
|
|
58610
59416
|
}
|
|
58611
59417
|
async function savePaymentChain(chain3) {
|
|
58612
|
-
await mkdir2(
|
|
59418
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58613
59419
|
await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
|
|
58614
59420
|
}
|
|
58615
59421
|
async function loadPaymentChain() {
|
|
@@ -58626,17 +59432,17 @@ async function resolvePaymentChain() {
|
|
|
58626
59432
|
if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
|
|
58627
59433
|
return loadPaymentChain();
|
|
58628
59434
|
}
|
|
58629
|
-
var
|
|
59435
|
+
var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
|
|
58630
59436
|
var init_auth = __esm({
|
|
58631
59437
|
"src/auth.ts"() {
|
|
58632
59438
|
"use strict";
|
|
58633
59439
|
init_fs_read();
|
|
58634
59440
|
init_accounts();
|
|
58635
59441
|
init_wallet2();
|
|
58636
|
-
|
|
58637
|
-
WALLET_FILE =
|
|
58638
|
-
MNEMONIC_FILE =
|
|
58639
|
-
CHAIN_FILE =
|
|
59442
|
+
WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
|
|
59443
|
+
WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
|
|
59444
|
+
MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
|
|
59445
|
+
CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
|
|
58640
59446
|
}
|
|
58641
59447
|
});
|
|
58642
59448
|
|
|
@@ -58795,7 +59601,7 @@ function generateCodebookHeader(usedCodes, pathMap = {}) {
|
|
|
58795
59601
|
parts.push(`[Dict: ${codeEntries}]`);
|
|
58796
59602
|
}
|
|
58797
59603
|
if (Object.keys(pathMap).length > 0) {
|
|
58798
|
-
const pathEntries = Object.entries(pathMap).map(([code,
|
|
59604
|
+
const pathEntries = Object.entries(pathMap).map(([code, path5]) => `${code}=${path5}`).join(", ");
|
|
58799
59605
|
parts.push(`[Paths: ${pathEntries}]`);
|
|
58800
59606
|
}
|
|
58801
59607
|
return parts.join("\n");
|
|
@@ -58943,8 +59749,8 @@ function extractPaths(messages) {
|
|
|
58943
59749
|
}
|
|
58944
59750
|
function findFrequentPrefixes(paths) {
|
|
58945
59751
|
const prefixCounts = /* @__PURE__ */ new Map();
|
|
58946
|
-
for (const
|
|
58947
|
-
const parts =
|
|
59752
|
+
for (const path5 of paths) {
|
|
59753
|
+
const parts = path5.split("/").filter(Boolean);
|
|
58948
59754
|
for (let i = 2; i < parts.length; i++) {
|
|
58949
59755
|
const prefix = "/" + parts.slice(0, i).join("/") + "/";
|
|
58950
59756
|
prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
|
|
@@ -59728,9 +60534,9 @@ var init_updater = __esm({
|
|
|
59728
60534
|
});
|
|
59729
60535
|
|
|
59730
60536
|
// src/exclude-models.ts
|
|
59731
|
-
import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
|
|
59732
|
-
import { join as
|
|
59733
|
-
import { homedir as
|
|
60537
|
+
import { readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
60538
|
+
import { join as join8, dirname as dirname2 } from "path";
|
|
60539
|
+
import { homedir as homedir5 } from "os";
|
|
59734
60540
|
function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
59735
60541
|
try {
|
|
59736
60542
|
const mtimeMs = statSync(filePath).mtimeMs;
|
|
@@ -59751,8 +60557,8 @@ function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
|
59751
60557
|
function saveExcludeList(set, filePath) {
|
|
59752
60558
|
const sorted = [...set].sort();
|
|
59753
60559
|
const dir = dirname2(filePath);
|
|
59754
|
-
|
|
59755
|
-
|
|
60560
|
+
mkdirSync2(dir, { recursive: true });
|
|
60561
|
+
writeFileSync2(filePath, JSON.stringify(sorted, null, 2) + "\n", "utf-8");
|
|
59756
60562
|
loadCache.delete(filePath);
|
|
59757
60563
|
}
|
|
59758
60564
|
function addExclusion(model, filePath = DEFAULT_FILE_PATH) {
|
|
@@ -59779,7 +60585,7 @@ var init_exclude_models = __esm({
|
|
|
59779
60585
|
"src/exclude-models.ts"() {
|
|
59780
60586
|
"use strict";
|
|
59781
60587
|
init_models();
|
|
59782
|
-
DEFAULT_FILE_PATH =
|
|
60588
|
+
DEFAULT_FILE_PATH = join8(homedir5(), ".openclaw", "blockrun", "exclude-models.json");
|
|
59783
60589
|
loadCache = /* @__PURE__ */ new Map();
|
|
59784
60590
|
}
|
|
59785
60591
|
});
|
|
@@ -61084,14 +61890,14 @@ var require_util = __commonJS({
|
|
|
61084
61890
|
}
|
|
61085
61891
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
61086
61892
|
let origin2 = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
61087
|
-
let
|
|
61893
|
+
let path5 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
61088
61894
|
if (origin2[origin2.length - 1] === "/") {
|
|
61089
61895
|
origin2 = origin2.slice(0, origin2.length - 1);
|
|
61090
61896
|
}
|
|
61091
|
-
if (
|
|
61092
|
-
|
|
61897
|
+
if (path5 && path5[0] !== "/") {
|
|
61898
|
+
path5 = `/${path5}`;
|
|
61093
61899
|
}
|
|
61094
|
-
return new URL(`${origin2}${
|
|
61900
|
+
return new URL(`${origin2}${path5}`);
|
|
61095
61901
|
}
|
|
61096
61902
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
61097
61903
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -61962,9 +62768,9 @@ var require_diagnostics = __commonJS({
|
|
|
61962
62768
|
"undici:client:sendHeaders",
|
|
61963
62769
|
(evt) => {
|
|
61964
62770
|
const {
|
|
61965
|
-
request: { method, path:
|
|
62771
|
+
request: { method, path: path5, origin: origin2 }
|
|
61966
62772
|
} = evt;
|
|
61967
|
-
debugLog("sending request to %s %s%s", method, origin2,
|
|
62773
|
+
debugLog("sending request to %s %s%s", method, origin2, path5);
|
|
61968
62774
|
}
|
|
61969
62775
|
);
|
|
61970
62776
|
}
|
|
@@ -61982,14 +62788,14 @@ var require_diagnostics = __commonJS({
|
|
|
61982
62788
|
"undici:request:headers",
|
|
61983
62789
|
(evt) => {
|
|
61984
62790
|
const {
|
|
61985
|
-
request: { method, path:
|
|
62791
|
+
request: { method, path: path5, origin: origin2 },
|
|
61986
62792
|
response: { statusCode }
|
|
61987
62793
|
} = evt;
|
|
61988
62794
|
debugLog(
|
|
61989
62795
|
"received response to %s %s%s - HTTP %d",
|
|
61990
62796
|
method,
|
|
61991
62797
|
origin2,
|
|
61992
|
-
|
|
62798
|
+
path5,
|
|
61993
62799
|
statusCode
|
|
61994
62800
|
);
|
|
61995
62801
|
}
|
|
@@ -61998,23 +62804,23 @@ var require_diagnostics = __commonJS({
|
|
|
61998
62804
|
"undici:request:trailers",
|
|
61999
62805
|
(evt) => {
|
|
62000
62806
|
const {
|
|
62001
|
-
request: { method, path:
|
|
62807
|
+
request: { method, path: path5, origin: origin2 }
|
|
62002
62808
|
} = evt;
|
|
62003
|
-
debugLog("trailers received from %s %s%s", method, origin2,
|
|
62809
|
+
debugLog("trailers received from %s %s%s", method, origin2, path5);
|
|
62004
62810
|
}
|
|
62005
62811
|
);
|
|
62006
62812
|
diagnosticsChannel.subscribe(
|
|
62007
62813
|
"undici:request:error",
|
|
62008
62814
|
(evt) => {
|
|
62009
62815
|
const {
|
|
62010
|
-
request: { method, path:
|
|
62816
|
+
request: { method, path: path5, origin: origin2 },
|
|
62011
62817
|
error
|
|
62012
62818
|
} = evt;
|
|
62013
62819
|
debugLog(
|
|
62014
62820
|
"request to %s %s%s errored - %s",
|
|
62015
62821
|
method,
|
|
62016
62822
|
origin2,
|
|
62017
|
-
|
|
62823
|
+
path5,
|
|
62018
62824
|
error.message
|
|
62019
62825
|
);
|
|
62020
62826
|
}
|
|
@@ -62169,7 +62975,7 @@ var require_request = __commonJS({
|
|
|
62169
62975
|
};
|
|
62170
62976
|
var Request2 = class {
|
|
62171
62977
|
constructor(origin2, {
|
|
62172
|
-
path:
|
|
62978
|
+
path: path5,
|
|
62173
62979
|
method,
|
|
62174
62980
|
body,
|
|
62175
62981
|
headers,
|
|
@@ -62186,11 +62992,11 @@ var require_request = __commonJS({
|
|
|
62186
62992
|
maxRedirections,
|
|
62187
62993
|
typeOfService
|
|
62188
62994
|
}, handler) {
|
|
62189
|
-
if (typeof
|
|
62995
|
+
if (typeof path5 !== "string") {
|
|
62190
62996
|
throw new InvalidArgumentError("path must be a string");
|
|
62191
|
-
} else if (
|
|
62997
|
+
} else if (path5[0] !== "/" && !(path5.startsWith("http://") || path5.startsWith("https://")) && method !== "CONNECT") {
|
|
62192
62998
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
62193
|
-
} else if (invalidPathRegex.test(
|
|
62999
|
+
} else if (invalidPathRegex.test(path5)) {
|
|
62194
63000
|
throw new InvalidArgumentError("invalid request path");
|
|
62195
63001
|
}
|
|
62196
63002
|
if (typeof method !== "string") {
|
|
@@ -62265,7 +63071,7 @@ var require_request = __commonJS({
|
|
|
62265
63071
|
this.completed = false;
|
|
62266
63072
|
this.aborted = false;
|
|
62267
63073
|
this.upgrade = upgrade || null;
|
|
62268
|
-
this.path = query ? serializePathWithQuery(
|
|
63074
|
+
this.path = query ? serializePathWithQuery(path5, query) : path5;
|
|
62269
63075
|
this.origin = origin2;
|
|
62270
63076
|
this.protocol = getProtocolFromUrlString(origin2);
|
|
62271
63077
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent;
|
|
@@ -67351,7 +68157,7 @@ var require_client_h1 = __commonJS({
|
|
|
67351
68157
|
}
|
|
67352
68158
|
}
|
|
67353
68159
|
function writeH1(client, request2) {
|
|
67354
|
-
const { method, path:
|
|
68160
|
+
const { method, path: path5, host, upgrade, blocking, reset } = request2;
|
|
67355
68161
|
let { body, headers, contentLength } = request2;
|
|
67356
68162
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
67357
68163
|
if (util5.isFormDataLike(body)) {
|
|
@@ -67427,7 +68233,7 @@ var require_client_h1 = __commonJS({
|
|
|
67427
68233
|
socket[kBlocking] = true;
|
|
67428
68234
|
}
|
|
67429
68235
|
setTypeOfService(socket, request2);
|
|
67430
|
-
let header = `${method} ${
|
|
68236
|
+
let header = `${method} ${path5} HTTP/1.1\r
|
|
67431
68237
|
`;
|
|
67432
68238
|
if (typeof host === "string") {
|
|
67433
68239
|
header += `host: ${host}\r
|
|
@@ -68508,7 +69314,7 @@ var require_client_h2 = __commonJS({
|
|
|
68508
69314
|
const headersTimeout = request2.headersTimeout ?? client[kHeadersTimeout];
|
|
68509
69315
|
const bodyTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
|
|
68510
69316
|
const session = client[kHTTP2Session];
|
|
68511
|
-
const { method, path:
|
|
69317
|
+
const { method, path: path5, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
|
|
68512
69318
|
if (upgrade != null && upgrade !== "websocket") {
|
|
68513
69319
|
util5.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
68514
69320
|
return false;
|
|
@@ -68571,7 +69377,7 @@ var require_client_h2 = __commonJS({
|
|
|
68571
69377
|
}
|
|
68572
69378
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
68573
69379
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
68574
|
-
headers[HTTP2_HEADER_PATH] =
|
|
69380
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68575
69381
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
68576
69382
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
68577
69383
|
} else {
|
|
@@ -68593,7 +69399,7 @@ var require_client_h2 = __commonJS({
|
|
|
68593
69399
|
setupUpgradeStream(stream4, state);
|
|
68594
69400
|
return true;
|
|
68595
69401
|
}
|
|
68596
|
-
headers[HTTP2_HEADER_PATH] =
|
|
69402
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68597
69403
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
68598
69404
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
68599
69405
|
let body = state.body;
|
|
@@ -71263,10 +72069,10 @@ var require_proxy_agent = __commonJS({
|
|
|
71263
72069
|
};
|
|
71264
72070
|
const {
|
|
71265
72071
|
origin: origin2,
|
|
71266
|
-
path:
|
|
72072
|
+
path: path5 = "/",
|
|
71267
72073
|
headers = {}
|
|
71268
72074
|
} = opts;
|
|
71269
|
-
opts.path = origin2 +
|
|
72075
|
+
opts.path = origin2 + path5;
|
|
71270
72076
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
71271
72077
|
const { host } = new URL(origin2);
|
|
71272
72078
|
headers.host = host;
|
|
@@ -73531,20 +74337,20 @@ var require_mock_utils = __commonJS({
|
|
|
73531
74337
|
}
|
|
73532
74338
|
return normalizedQp;
|
|
73533
74339
|
}
|
|
73534
|
-
function safeUrl(
|
|
73535
|
-
if (typeof
|
|
73536
|
-
return
|
|
74340
|
+
function safeUrl(path5) {
|
|
74341
|
+
if (typeof path5 !== "string") {
|
|
74342
|
+
return path5;
|
|
73537
74343
|
}
|
|
73538
|
-
const pathSegments =
|
|
74344
|
+
const pathSegments = path5.split("?", 3);
|
|
73539
74345
|
if (pathSegments.length !== 2) {
|
|
73540
|
-
return
|
|
74346
|
+
return path5;
|
|
73541
74347
|
}
|
|
73542
74348
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
73543
74349
|
qp.sort();
|
|
73544
74350
|
return [...pathSegments, qp.toString()].join("?");
|
|
73545
74351
|
}
|
|
73546
|
-
function matchKey(mockDispatch2, { path:
|
|
73547
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
74352
|
+
function matchKey(mockDispatch2, { path: path5, method, body, headers }) {
|
|
74353
|
+
const pathMatch = matchValue(mockDispatch2.path, path5);
|
|
73548
74354
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
73549
74355
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
73550
74356
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -73571,8 +74377,8 @@ var require_mock_utils = __commonJS({
|
|
|
73571
74377
|
const basePath = key2.query ? serializePathWithQuery(key2.path, key2.query) : key2.path;
|
|
73572
74378
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
73573
74379
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
73574
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
73575
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
74380
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path5, ignoreTrailingSlash }) => {
|
|
74381
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path5)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path5), resolvedPath);
|
|
73576
74382
|
});
|
|
73577
74383
|
if (matchedMockDispatches.length === 0) {
|
|
73578
74384
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -73611,22 +74417,22 @@ var require_mock_utils = __commonJS({
|
|
|
73611
74417
|
mockDispatches.splice(index2, 1);
|
|
73612
74418
|
}
|
|
73613
74419
|
}
|
|
73614
|
-
function removeTrailingSlash(
|
|
73615
|
-
if (typeof
|
|
73616
|
-
return
|
|
74420
|
+
function removeTrailingSlash(path5) {
|
|
74421
|
+
if (typeof path5 !== "string") {
|
|
74422
|
+
return path5;
|
|
73617
74423
|
}
|
|
73618
|
-
while (
|
|
73619
|
-
|
|
74424
|
+
while (path5.endsWith("/")) {
|
|
74425
|
+
path5 = path5.slice(0, -1);
|
|
73620
74426
|
}
|
|
73621
|
-
if (
|
|
73622
|
-
|
|
74427
|
+
if (path5.length === 0) {
|
|
74428
|
+
path5 = "/";
|
|
73623
74429
|
}
|
|
73624
|
-
return
|
|
74430
|
+
return path5;
|
|
73625
74431
|
}
|
|
73626
74432
|
function buildKey(opts) {
|
|
73627
|
-
const { path:
|
|
74433
|
+
const { path: path5, method, body, headers, query } = opts;
|
|
73628
74434
|
return {
|
|
73629
|
-
path:
|
|
74435
|
+
path: path5,
|
|
73630
74436
|
method,
|
|
73631
74437
|
body,
|
|
73632
74438
|
headers,
|
|
@@ -74497,10 +75303,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
74497
75303
|
}
|
|
74498
75304
|
format(pendingInterceptors) {
|
|
74499
75305
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
74500
|
-
({ method, path:
|
|
75306
|
+
({ method, path: path5, data: { statusCode }, persist, times, timesInvoked, origin: origin2 }) => ({
|
|
74501
75307
|
Method: method,
|
|
74502
75308
|
Origin: origin2,
|
|
74503
|
-
Path:
|
|
75309
|
+
Path: path5,
|
|
74504
75310
|
"Status code": statusCode,
|
|
74505
75311
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
74506
75312
|
Invocations: timesInvoked,
|
|
@@ -74582,9 +75388,9 @@ var require_mock_agent = __commonJS({
|
|
|
74582
75388
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
74583
75389
|
const dispatchOpts = { ...opts };
|
|
74584
75390
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
74585
|
-
const [
|
|
75391
|
+
const [path5, searchParams] = dispatchOpts.path.split("?");
|
|
74586
75392
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
74587
|
-
dispatchOpts.path = `${
|
|
75393
|
+
dispatchOpts.path = `${path5}?${normalizedSearchParams}`;
|
|
74588
75394
|
}
|
|
74589
75395
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
74590
75396
|
}
|
|
@@ -75000,12 +75806,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75000
75806
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
75001
75807
|
*/
|
|
75002
75808
|
async loadSnapshots(filePath) {
|
|
75003
|
-
const
|
|
75004
|
-
if (!
|
|
75809
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75810
|
+
if (!path5) {
|
|
75005
75811
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
75006
75812
|
}
|
|
75007
75813
|
try {
|
|
75008
|
-
const data = await readFile3(resolve(
|
|
75814
|
+
const data = await readFile3(resolve(path5), "utf8");
|
|
75009
75815
|
const parsed = JSON.parse(data);
|
|
75010
75816
|
if (Array.isArray(parsed)) {
|
|
75011
75817
|
this.#snapshots.clear();
|
|
@@ -75019,7 +75825,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75019
75825
|
if (error.code === "ENOENT") {
|
|
75020
75826
|
this.#snapshots.clear();
|
|
75021
75827
|
} else {
|
|
75022
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
75828
|
+
throw new UndiciError(`Failed to load snapshots from ${path5}`, { cause: error });
|
|
75023
75829
|
}
|
|
75024
75830
|
}
|
|
75025
75831
|
}
|
|
@@ -75030,11 +75836,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75030
75836
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
75031
75837
|
*/
|
|
75032
75838
|
async saveSnapshots(filePath) {
|
|
75033
|
-
const
|
|
75034
|
-
if (!
|
|
75839
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75840
|
+
if (!path5) {
|
|
75035
75841
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
75036
75842
|
}
|
|
75037
|
-
const resolvedPath = resolve(
|
|
75843
|
+
const resolvedPath = resolve(path5);
|
|
75038
75844
|
await mkdir5(dirname5(resolvedPath), { recursive: true });
|
|
75039
75845
|
const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
|
|
75040
75846
|
hash: hash5,
|
|
@@ -75671,15 +76477,15 @@ var require_redirect_handler = __commonJS({
|
|
|
75671
76477
|
return;
|
|
75672
76478
|
}
|
|
75673
76479
|
const { origin: origin2, pathname, search } = util5.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
75674
|
-
const
|
|
75675
|
-
const redirectUrlString = `${origin2}${
|
|
76480
|
+
const path5 = search ? `${pathname}${search}` : pathname;
|
|
76481
|
+
const redirectUrlString = `${origin2}${path5}`;
|
|
75676
76482
|
for (const historyUrl of this.history) {
|
|
75677
76483
|
if (historyUrl.toString() === redirectUrlString) {
|
|
75678
76484
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin2}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
75679
76485
|
}
|
|
75680
76486
|
}
|
|
75681
76487
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect);
|
|
75682
|
-
this.opts.path =
|
|
76488
|
+
this.opts.path = path5;
|
|
75683
76489
|
this.opts.origin = origin2;
|
|
75684
76490
|
this.opts.query = null;
|
|
75685
76491
|
}
|
|
@@ -77507,10 +78313,10 @@ var require_cache_handler = __commonJS({
|
|
|
77507
78313
|
}
|
|
77508
78314
|
return locationUrl.pathname + locationUrl.search;
|
|
77509
78315
|
}
|
|
77510
|
-
function deleteCachedUri(store, cacheKey2,
|
|
78316
|
+
function deleteCachedUri(store, cacheKey2, path5) {
|
|
77511
78317
|
deleteCachedValue(store, {
|
|
77512
78318
|
...cacheKey2,
|
|
77513
|
-
path:
|
|
78319
|
+
path: path5
|
|
77514
78320
|
});
|
|
77515
78321
|
for (let i = 0; i < util5.safeHTTPMethods.length; i++) {
|
|
77516
78322
|
const method = util5.safeHTTPMethods[i];
|
|
@@ -77518,7 +78324,7 @@ var require_cache_handler = __commonJS({
|
|
|
77518
78324
|
deleteCachedValue(store, {
|
|
77519
78325
|
...cacheKey2,
|
|
77520
78326
|
method,
|
|
77521
|
-
path:
|
|
78327
|
+
path: path5
|
|
77522
78328
|
});
|
|
77523
78329
|
}
|
|
77524
78330
|
}
|
|
@@ -77529,9 +78335,9 @@ var require_cache_handler = __commonJS({
|
|
|
77529
78335
|
}
|
|
77530
78336
|
const values = Array.isArray(headerValue) ? headerValue : [headerValue];
|
|
77531
78337
|
for (let i = 0; i < values.length; i++) {
|
|
77532
|
-
const
|
|
77533
|
-
if (
|
|
77534
|
-
deleteCachedUri(store, cacheKey2,
|
|
78338
|
+
const path5 = getSameOriginPath(cacheKey2, values[i]);
|
|
78339
|
+
if (path5 !== void 0) {
|
|
78340
|
+
deleteCachedUri(store, cacheKey2, path5);
|
|
77535
78341
|
}
|
|
77536
78342
|
}
|
|
77537
78343
|
}
|
|
@@ -82528,13 +83334,13 @@ var require_fetch = __commonJS({
|
|
|
82528
83334
|
function dispatch({ body }) {
|
|
82529
83335
|
const url2 = requestCurrentURL(request2);
|
|
82530
83336
|
const agent = fetchParams.controller.dispatcher;
|
|
82531
|
-
const
|
|
83337
|
+
const path5 = url2.pathname + url2.search;
|
|
82532
83338
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
82533
83339
|
return dispatchWithProtocolPreference(body);
|
|
82534
83340
|
function dispatchWithProtocolPreference(body2, allowH2) {
|
|
82535
83341
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
82536
83342
|
{
|
|
82537
|
-
path: hasTrailingQuestionMark ? `${
|
|
83343
|
+
path: hasTrailingQuestionMark ? `${path5}?` : path5,
|
|
82538
83344
|
origin: url2.origin,
|
|
82539
83345
|
method: request2.method,
|
|
82540
83346
|
body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body2,
|
|
@@ -83446,9 +84252,9 @@ var require_util4 = __commonJS({
|
|
|
83446
84252
|
}
|
|
83447
84253
|
}
|
|
83448
84254
|
}
|
|
83449
|
-
function validateCookiePath(
|
|
83450
|
-
for (let i = 0; i <
|
|
83451
|
-
const code =
|
|
84255
|
+
function validateCookiePath(path5) {
|
|
84256
|
+
for (let i = 0; i < path5.length; ++i) {
|
|
84257
|
+
const code = path5.charCodeAt(i);
|
|
83452
84258
|
if (code < 32 || // exclude CTLs (0-31)
|
|
83453
84259
|
code > 126 || // exclude non-ascii and DEL
|
|
83454
84260
|
code === 59) {
|
|
@@ -86820,11 +87626,11 @@ var require_undici = __commonJS({
|
|
|
86820
87626
|
if (typeof opts.path !== "string") {
|
|
86821
87627
|
throw new InvalidArgumentError("invalid opts.path");
|
|
86822
87628
|
}
|
|
86823
|
-
let
|
|
87629
|
+
let path5 = opts.path;
|
|
86824
87630
|
if (!opts.path.startsWith("/")) {
|
|
86825
|
-
|
|
87631
|
+
path5 = `/${path5}`;
|
|
86826
87632
|
}
|
|
86827
|
-
url2 = new URL(util5.parseOrigin(url2).origin +
|
|
87633
|
+
url2 = new URL(util5.parseOrigin(url2).origin + path5);
|
|
86828
87634
|
} else {
|
|
86829
87635
|
if (!opts) {
|
|
86830
87636
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -87370,8 +88176,8 @@ var init_textual_tool_calls = __esm({
|
|
|
87370
88176
|
|
|
87371
88177
|
// src/response-store.ts
|
|
87372
88178
|
import { appendFile as appendFile2, mkdir as mkdir3, readFile, readdir as readdir2 } from "fs/promises";
|
|
87373
|
-
import { homedir as
|
|
87374
|
-
import { join as
|
|
88179
|
+
import { homedir as homedir6 } from "os";
|
|
88180
|
+
import { join as join9 } from "path";
|
|
87375
88181
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
87376
88182
|
function isEnabled() {
|
|
87377
88183
|
const v = process.env.BLOCKRUN_RESPONSE_STORE;
|
|
@@ -87384,7 +88190,7 @@ async function ensureDir2() {
|
|
|
87384
88190
|
}
|
|
87385
88191
|
function dailyFile(date = /* @__PURE__ */ new Date()) {
|
|
87386
88192
|
const iso = date.toISOString().slice(0, 10);
|
|
87387
|
-
return
|
|
88193
|
+
return join9(STORE_DIR, `responses-${iso}.jsonl`);
|
|
87388
88194
|
}
|
|
87389
88195
|
function genId() {
|
|
87390
88196
|
return `resp_${Date.now()}_${randomBytes7(3).toString("hex")}`;
|
|
@@ -87434,7 +88240,7 @@ async function listRecent(limit = 20, daysBack = 7) {
|
|
|
87434
88240
|
d.setUTCDate(d.getUTCDate() - i);
|
|
87435
88241
|
const iso = d.toISOString().slice(0, 10);
|
|
87436
88242
|
const name = `responses-${iso}.jsonl`;
|
|
87437
|
-
if (files.includes(name)) candidateFiles.push(
|
|
88243
|
+
if (files.includes(name)) candidateFiles.push(join9(STORE_DIR, name));
|
|
87438
88244
|
}
|
|
87439
88245
|
const all3 = [];
|
|
87440
88246
|
for (const f of candidateFiles) {
|
|
@@ -87463,7 +88269,7 @@ var STORE_DIR, dirReady2;
|
|
|
87463
88269
|
var init_response_store = __esm({
|
|
87464
88270
|
"src/response-store.ts"() {
|
|
87465
88271
|
"use strict";
|
|
87466
|
-
STORE_DIR =
|
|
88272
|
+
STORE_DIR = join9(homedir6(), ".openclaw", "blockrun", "responses");
|
|
87467
88273
|
dirReady2 = false;
|
|
87468
88274
|
}
|
|
87469
88275
|
});
|
|
@@ -89113,10 +89919,10 @@ var init_client3 = __esm({
|
|
|
89113
89919
|
import { AsyncLocalStorage } from "async_hooks";
|
|
89114
89920
|
import { createServer } from "http";
|
|
89115
89921
|
import { finished } from "stream";
|
|
89116
|
-
import { homedir as
|
|
89117
|
-
import { join as
|
|
89922
|
+
import { homedir as homedir7 } from "os";
|
|
89923
|
+
import { join as join10 } from "path";
|
|
89118
89924
|
import { mkdir as mkdir4, writeFile as writeFile2, readFile as readFile2, stat as fsStat } from "fs/promises";
|
|
89119
|
-
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
89925
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
89120
89926
|
function pickFreeModel(excludeList) {
|
|
89121
89927
|
for (const m of FREE_MODELS) {
|
|
89122
89928
|
if (!excludeList?.has(m)) return m;
|
|
@@ -89124,6 +89930,8 @@ function pickFreeModel(excludeList) {
|
|
|
89124
89930
|
return void 0;
|
|
89125
89931
|
}
|
|
89126
89932
|
function toUpstreamModelId(modelId) {
|
|
89933
|
+
const override = FREE_UPSTREAM_OVERRIDES[modelId];
|
|
89934
|
+
if (override) return override;
|
|
89127
89935
|
if (modelId.startsWith("free/")) {
|
|
89128
89936
|
return "nvidia/" + modelId.slice("free/".length);
|
|
89129
89937
|
}
|
|
@@ -89882,8 +90690,8 @@ async function proxyPaidApiRequest(req, res, apiBase, payFetch, getActualPayment
|
|
|
89882
90690
|
});
|
|
89883
90691
|
}
|
|
89884
90692
|
function readImageFileAsDataUri(filePath) {
|
|
89885
|
-
const resolved = filePath.startsWith("~/") ?
|
|
89886
|
-
if (!
|
|
90693
|
+
const resolved = filePath.startsWith("~/") ? join10(homedir7(), filePath.slice(2)) : filePath;
|
|
90694
|
+
if (!existsSync2(resolved)) {
|
|
89887
90695
|
throw new Error(`Image file not found: ${resolved}`);
|
|
89888
90696
|
}
|
|
89889
90697
|
const ext = resolved.split(".").pop()?.toLowerCase() ?? "png";
|
|
@@ -89997,6 +90805,8 @@ async function startProxy(options) {
|
|
|
89997
90805
|
const evmPublicClient = createPublicClient({ chain: base, transport: http() });
|
|
89998
90806
|
const evmSigner = toClientEvmSigner(account, evmPublicClient);
|
|
89999
90807
|
const x402 = new x402Client();
|
|
90808
|
+
const spendControl = options.spendControl ?? new SpendControl();
|
|
90809
|
+
registerSpendPolicyHook(x402, spendControl);
|
|
90000
90810
|
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
90001
90811
|
let solanaAddress;
|
|
90002
90812
|
if (solanaPrivateKeyBytes) {
|
|
@@ -90165,8 +90975,8 @@ async function startProxy(options) {
|
|
|
90165
90975
|
if (req.url?.startsWith("/share") && req.method === "GET") {
|
|
90166
90976
|
try {
|
|
90167
90977
|
const url2 = new URL(req.url, "http://localhost");
|
|
90168
|
-
const
|
|
90169
|
-
if (
|
|
90978
|
+
const path5 = url2.pathname;
|
|
90979
|
+
if (path5 === "/share/list") {
|
|
90170
90980
|
const limit = Math.min(parseInt(url2.searchParams.get("limit") || "20", 10), 100);
|
|
90171
90981
|
const entries = await listRecent(limit);
|
|
90172
90982
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -90184,7 +90994,7 @@ async function startProxy(options) {
|
|
|
90184
90994
|
);
|
|
90185
90995
|
return;
|
|
90186
90996
|
}
|
|
90187
|
-
if (
|
|
90997
|
+
if (path5 === "/share/last") {
|
|
90188
90998
|
const sessionId = url2.searchParams.get("sessionId") || void 0;
|
|
90189
90999
|
const entry = await getLast(sessionId);
|
|
90190
91000
|
if (!entry) {
|
|
@@ -90213,7 +91023,7 @@ async function startProxy(options) {
|
|
|
90213
91023
|
res.end(JSON.stringify(entry));
|
|
90214
91024
|
return;
|
|
90215
91025
|
}
|
|
90216
|
-
const idMatch =
|
|
91026
|
+
const idMatch = path5.match(/^\/share\/(resp_[A-Za-z0-9_]+)(?:\/render)?$/);
|
|
90217
91027
|
if (idMatch) {
|
|
90218
91028
|
const id2 = idMatch[1];
|
|
90219
91029
|
const entry = await getById(id2);
|
|
@@ -90259,7 +91069,7 @@ async function startProxy(options) {
|
|
|
90259
91069
|
res.end("Bad request");
|
|
90260
91070
|
return;
|
|
90261
91071
|
}
|
|
90262
|
-
const filePath =
|
|
91072
|
+
const filePath = join10(IMAGE_DIR, filename);
|
|
90263
91073
|
try {
|
|
90264
91074
|
const s3 = await fsStat(filePath);
|
|
90265
91075
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90290,7 +91100,7 @@ async function startProxy(options) {
|
|
|
90290
91100
|
res.end("Bad request");
|
|
90291
91101
|
return;
|
|
90292
91102
|
}
|
|
90293
|
-
const filePath =
|
|
91103
|
+
const filePath = join10(AUDIO_DIR, filename);
|
|
90294
91104
|
try {
|
|
90295
91105
|
const s3 = await fsStat(filePath);
|
|
90296
91106
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90320,7 +91130,7 @@ async function startProxy(options) {
|
|
|
90320
91130
|
res.end("Bad request");
|
|
90321
91131
|
return;
|
|
90322
91132
|
}
|
|
90323
|
-
const filePath =
|
|
91133
|
+
const filePath = join10(VIDEO_DIR, filename);
|
|
90324
91134
|
try {
|
|
90325
91135
|
const s3 = await fsStat(filePath);
|
|
90326
91136
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90461,7 +91271,7 @@ async function startProxy(options) {
|
|
|
90461
91271
|
const [, mimeType, b64] = dataUriMatch;
|
|
90462
91272
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90463
91273
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90464
|
-
await writeFile2(
|
|
91274
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90465
91275
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90466
91276
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90467
91277
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90472,7 +91282,7 @@ async function startProxy(options) {
|
|
|
90472
91282
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90473
91283
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90474
91284
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90475
|
-
await writeFile2(
|
|
91285
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90476
91286
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90477
91287
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90478
91288
|
}
|
|
@@ -90584,7 +91394,7 @@ async function startProxy(options) {
|
|
|
90584
91394
|
const [, mimeType, b64] = dataUriMatch;
|
|
90585
91395
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90586
91396
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90587
|
-
await writeFile2(
|
|
91397
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90588
91398
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90589
91399
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90590
91400
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90595,7 +91405,7 @@ async function startProxy(options) {
|
|
|
90595
91405
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90596
91406
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90597
91407
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90598
|
-
await writeFile2(
|
|
91408
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90599
91409
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90600
91410
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90601
91411
|
}
|
|
@@ -90681,7 +91491,7 @@ async function startProxy(options) {
|
|
|
90681
91491
|
const ext = contentType.includes("wav") ? "wav" : "mp3";
|
|
90682
91492
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90683
91493
|
const buf = Buffer.from(await audioResp.arrayBuffer());
|
|
90684
|
-
await writeFile2(
|
|
91494
|
+
await writeFile2(join10(AUDIO_DIR, filename), buf);
|
|
90685
91495
|
track.url = `http://localhost:${port2}/audio/${filename}`;
|
|
90686
91496
|
console.log(`[ClawRouter] Audio saved \u2192 ${track.url}`);
|
|
90687
91497
|
}
|
|
@@ -90841,7 +91651,7 @@ async function startProxy(options) {
|
|
|
90841
91651
|
const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
|
|
90842
91652
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90843
91653
|
const buf = Buffer.from(await videoResp.arrayBuffer());
|
|
90844
|
-
await writeFile2(
|
|
91654
|
+
await writeFile2(join10(VIDEO_DIR, filename), buf);
|
|
90845
91655
|
clip.url = `http://localhost:${port2}/videos/${filename}`;
|
|
90846
91656
|
console.log(`[ClawRouter] Video saved \u2192 ${clip.url}`);
|
|
90847
91657
|
}
|
|
@@ -91181,6 +91991,17 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
|
|
|
91181
91991
|
return { success: true, response };
|
|
91182
91992
|
} catch (err) {
|
|
91183
91993
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
91994
|
+
if (err instanceof SpendPolicyError) {
|
|
91995
|
+
return {
|
|
91996
|
+
success: false,
|
|
91997
|
+
errorBody: JSON.stringify({
|
|
91998
|
+
error: { message: errorMsg, type: "spend_policy_denied", status: 403 }
|
|
91999
|
+
}),
|
|
92000
|
+
errorStatus: 403,
|
|
92001
|
+
isProviderError: false,
|
|
92002
|
+
errorCategory: "payment_error"
|
|
92003
|
+
};
|
|
92004
|
+
}
|
|
91184
92005
|
return {
|
|
91185
92006
|
success: false,
|
|
91186
92007
|
errorBody: errorMsg,
|
|
@@ -93345,7 +94166,7 @@ data: [DONE]
|
|
|
93345
94166
|
});
|
|
93346
94167
|
}
|
|
93347
94168
|
}
|
|
93348
|
-
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
94169
|
+
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, FREE_MODEL, FREE_UPSTREAM_OVERRIDES, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
93349
94170
|
var init_proxy = __esm({
|
|
93350
94171
|
"src/proxy.ts"() {
|
|
93351
94172
|
"use strict";
|
|
@@ -93367,6 +94188,7 @@ var init_proxy = __esm({
|
|
|
93367
94188
|
init_response_cache();
|
|
93368
94189
|
init_balance();
|
|
93369
94190
|
init_auth();
|
|
94191
|
+
init_spend_control();
|
|
93370
94192
|
init_compression();
|
|
93371
94193
|
init_version4();
|
|
93372
94194
|
init_session();
|
|
@@ -93382,9 +94204,9 @@ var init_proxy = __esm({
|
|
|
93382
94204
|
paymentStore = new AsyncLocalStorage();
|
|
93383
94205
|
BLOCKRUN_API = "https://blockrun.ai/api";
|
|
93384
94206
|
BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
|
|
93385
|
-
IMAGE_DIR =
|
|
93386
|
-
AUDIO_DIR =
|
|
93387
|
-
VIDEO_DIR =
|
|
94207
|
+
IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
|
|
94208
|
+
AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
|
|
94209
|
+
VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
|
|
93388
94210
|
AUTO_MODEL = "blockrun/auto";
|
|
93389
94211
|
ROUTING_PROFILES = /* @__PURE__ */ new Set([
|
|
93390
94212
|
"blockrun/eco",
|
|
@@ -93395,18 +94217,26 @@ var init_proxy = __esm({
|
|
|
93395
94217
|
"premium"
|
|
93396
94218
|
]);
|
|
93397
94219
|
FREE_MODELS = /* @__PURE__ */ new Set([
|
|
93398
|
-
"free/
|
|
93399
|
-
//
|
|
93400
|
-
"free/nemotron-nano-
|
|
93401
|
-
//
|
|
93402
|
-
"free/
|
|
93403
|
-
//
|
|
94220
|
+
"free/nemotron-3.5-lightning",
|
|
94221
|
+
// free-tier default — 1M ctx, thinking mode
|
|
94222
|
+
"free/nemotron-3-nano-30b",
|
|
94223
|
+
// fastest free model (~121 tok/s)
|
|
94224
|
+
"free/laguna-xs-2.1",
|
|
94225
|
+
// coding, ~161 tok/s — on our NVIDIA key
|
|
94226
|
+
"free/north-mini-code",
|
|
94227
|
+
// coding, 607ms median — OpenRouter $0 pool
|
|
93404
94228
|
"free/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
93405
94229
|
// vision (text/image/video/audio)
|
|
93406
|
-
"free/nemotron-
|
|
93407
|
-
//
|
|
94230
|
+
"free/nemotron-3-ultra-550b",
|
|
94231
|
+
// largest free model, 1M ctx — but slow + flaky
|
|
94232
|
+
"free/llama-3.2-11b-vision"
|
|
94233
|
+
// only free Llama left; slowest, so last
|
|
93408
94234
|
]);
|
|
93409
|
-
FREE_MODEL = "free/
|
|
94235
|
+
FREE_MODEL = "free/nemotron-3.5-lightning";
|
|
94236
|
+
FREE_UPSTREAM_OVERRIDES = {
|
|
94237
|
+
"free/north-mini-code": "cohere/north-mini-code",
|
|
94238
|
+
"free/laguna-xs-2.1": "poolside/laguna-xs-2.1"
|
|
94239
|
+
};
|
|
93410
94240
|
MAX_MESSAGES = 200;
|
|
93411
94241
|
CONTEXT_LIMIT_KB = 5120;
|
|
93412
94242
|
HEARTBEAT_INTERVAL_MS = 2e3;
|
|
@@ -94449,7 +95279,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94449
95279
|
required
|
|
94450
95280
|
},
|
|
94451
95281
|
execute: async (_toolCallId, params) => {
|
|
94452
|
-
let
|
|
95282
|
+
let path5;
|
|
94453
95283
|
const leftoverParams = {};
|
|
94454
95284
|
let dynamicMethod = "GET";
|
|
94455
95285
|
let dynamicBody = void 0;
|
|
@@ -94461,7 +95291,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94461
95291
|
`predexon_endpoint_call: invalid path '${rawPath}' \u2014 must begin with '/pm/' and contain no '..'`
|
|
94462
95292
|
);
|
|
94463
95293
|
}
|
|
94464
|
-
|
|
95294
|
+
path5 = `/v1${normalized}`;
|
|
94465
95295
|
if (typeof params.method === "string") {
|
|
94466
95296
|
const upper = params.method.toUpperCase();
|
|
94467
95297
|
if (upper !== "GET" && upper !== "POST") {
|
|
@@ -94510,19 +95340,19 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94510
95340
|
}
|
|
94511
95341
|
}
|
|
94512
95342
|
} else {
|
|
94513
|
-
|
|
95343
|
+
path5 = `/v1${service.proxyPath}`;
|
|
94514
95344
|
for (const [key2, value] of Object.entries(params)) {
|
|
94515
95345
|
if (value === void 0 || value === null) continue;
|
|
94516
95346
|
const placeholder = `:${key2}`;
|
|
94517
|
-
if (
|
|
94518
|
-
|
|
95347
|
+
if (path5.includes(placeholder)) {
|
|
95348
|
+
path5 = path5.replace(placeholder, encodeURIComponent(String(value)));
|
|
94519
95349
|
} else {
|
|
94520
95350
|
leftoverParams[key2] = value;
|
|
94521
95351
|
}
|
|
94522
95352
|
}
|
|
94523
95353
|
}
|
|
94524
95354
|
const effectiveMethod = service.proxyPath === "/pm/__dynamic__" ? dynamicMethod : service.method;
|
|
94525
|
-
let url2 = `${proxyBaseUrl}${
|
|
95355
|
+
let url2 = `${proxyBaseUrl}${path5}`;
|
|
94526
95356
|
if (effectiveMethod === "GET" && Object.keys(leftoverParams).length > 0) {
|
|
94527
95357
|
const qs = new URLSearchParams();
|
|
94528
95358
|
for (const [key2, value] of Object.entries(leftoverParams)) {
|
|
@@ -106201,11 +107031,11 @@ var require_mime_types = __commonJS({
|
|
|
106201
107031
|
}
|
|
106202
107032
|
return exts[0];
|
|
106203
107033
|
}
|
|
106204
|
-
function lookup(
|
|
106205
|
-
if (!
|
|
107034
|
+
function lookup(path5) {
|
|
107035
|
+
if (!path5 || typeof path5 !== "string") {
|
|
106206
107036
|
return false;
|
|
106207
107037
|
}
|
|
106208
|
-
var extension3 = extname("x." +
|
|
107038
|
+
var extension3 = extname("x." + path5).toLowerCase().substr(1);
|
|
106209
107039
|
if (!extension3) {
|
|
106210
107040
|
return false;
|
|
106211
107041
|
}
|
|
@@ -107320,7 +108150,7 @@ var require_form_data = __commonJS({
|
|
|
107320
108150
|
"use strict";
|
|
107321
108151
|
var CombinedStream = require_combined_stream();
|
|
107322
108152
|
var util5 = __require("util");
|
|
107323
|
-
var
|
|
108153
|
+
var path5 = __require("path");
|
|
107324
108154
|
var http5 = __require("http");
|
|
107325
108155
|
var https2 = __require("https");
|
|
107326
108156
|
var parseUrl3 = __require("url").parse;
|
|
@@ -107451,11 +108281,11 @@ var require_form_data = __commonJS({
|
|
|
107451
108281
|
FormData3.prototype._getContentDisposition = function(value, options) {
|
|
107452
108282
|
var filename;
|
|
107453
108283
|
if (typeof options.filepath === "string") {
|
|
107454
|
-
filename =
|
|
108284
|
+
filename = path5.normalize(options.filepath).replace(/\\/g, "/");
|
|
107455
108285
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
107456
|
-
filename =
|
|
108286
|
+
filename = path5.basename(options.filename || value && (value.name || value.path));
|
|
107457
108287
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
107458
|
-
filename =
|
|
108288
|
+
filename = path5.basename(value.client._httpMessage.path || "");
|
|
107459
108289
|
}
|
|
107460
108290
|
if (filename) {
|
|
107461
108291
|
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
@@ -107669,9 +108499,9 @@ function isVisitable(thing) {
|
|
|
107669
108499
|
function removeBrackets(key2) {
|
|
107670
108500
|
return utils_default.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
107671
108501
|
}
|
|
107672
|
-
function renderKey(
|
|
107673
|
-
if (!
|
|
107674
|
-
return
|
|
108502
|
+
function renderKey(path5, key2, dots) {
|
|
108503
|
+
if (!path5) return key2;
|
|
108504
|
+
return path5.concat(key2).map(function each(token, i) {
|
|
107675
108505
|
token = removeBrackets(token);
|
|
107676
108506
|
return !dots && i ? "[" + token + "]" : token;
|
|
107677
108507
|
}).join(dots ? "." : "");
|
|
@@ -107754,13 +108584,13 @@ function toFormData(obj, formData, options) {
|
|
|
107754
108584
|
return currentValue;
|
|
107755
108585
|
});
|
|
107756
108586
|
}
|
|
107757
|
-
function defaultVisitor(value, key2,
|
|
108587
|
+
function defaultVisitor(value, key2, path5) {
|
|
107758
108588
|
let arr = value;
|
|
107759
108589
|
if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
|
|
107760
|
-
formData.append(renderKey(
|
|
108590
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107761
108591
|
return false;
|
|
107762
108592
|
}
|
|
107763
|
-
if (value && !
|
|
108593
|
+
if (value && !path5 && typeof value === "object") {
|
|
107764
108594
|
if (utils_default.endsWith(key2, "{}")) {
|
|
107765
108595
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
107766
108596
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -107779,7 +108609,7 @@ function toFormData(obj, formData, options) {
|
|
|
107779
108609
|
if (isVisitable(value)) {
|
|
107780
108610
|
return true;
|
|
107781
108611
|
}
|
|
107782
|
-
formData.append(renderKey(
|
|
108612
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107783
108613
|
return false;
|
|
107784
108614
|
}
|
|
107785
108615
|
const exposedHelpers = Object.assign(predicates, {
|
|
@@ -107787,17 +108617,17 @@ function toFormData(obj, formData, options) {
|
|
|
107787
108617
|
convertValue,
|
|
107788
108618
|
isVisitable
|
|
107789
108619
|
});
|
|
107790
|
-
function build(value,
|
|
108620
|
+
function build(value, path5, depth = 0) {
|
|
107791
108621
|
if (utils_default.isUndefined(value)) return;
|
|
107792
108622
|
throwIfMaxDepthExceeded(depth);
|
|
107793
108623
|
if (stack.indexOf(value) !== -1) {
|
|
107794
|
-
throw new Error("Circular reference detected in " +
|
|
108624
|
+
throw new Error("Circular reference detected in " + path5.join("."));
|
|
107795
108625
|
}
|
|
107796
108626
|
stack.push(value);
|
|
107797
108627
|
utils_default.forEach(value, function each(el, key2) {
|
|
107798
|
-
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2,
|
|
108628
|
+
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2, path5, exposedHelpers);
|
|
107799
108629
|
if (result === true) {
|
|
107800
|
-
build(el,
|
|
108630
|
+
build(el, path5 ? path5.concat(key2) : [key2], depth + 1);
|
|
107801
108631
|
}
|
|
107802
108632
|
});
|
|
107803
108633
|
stack.pop();
|
|
@@ -108076,7 +108906,7 @@ var init_platform = __esm({
|
|
|
108076
108906
|
// node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
108077
108907
|
function toURLEncodedForm(data, options) {
|
|
108078
108908
|
return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
|
|
108079
|
-
visitor: function(value, key2,
|
|
108909
|
+
visitor: function(value, key2, path5, helpers) {
|
|
108080
108910
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
108081
108911
|
this.append(key2, value.toString("base64"));
|
|
108082
108912
|
return false;
|
|
@@ -108105,14 +108935,14 @@ function throwIfDepthExceeded(index2) {
|
|
|
108105
108935
|
}
|
|
108106
108936
|
}
|
|
108107
108937
|
function parsePropPath(name) {
|
|
108108
|
-
const
|
|
108938
|
+
const path5 = [];
|
|
108109
108939
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
108110
108940
|
let match;
|
|
108111
108941
|
while ((match = pattern.exec(name)) !== null) {
|
|
108112
|
-
throwIfDepthExceeded(
|
|
108113
|
-
|
|
108942
|
+
throwIfDepthExceeded(path5.length);
|
|
108943
|
+
path5.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
108114
108944
|
}
|
|
108115
|
-
return
|
|
108945
|
+
return path5;
|
|
108116
108946
|
}
|
|
108117
108947
|
function arrayToObject(arr) {
|
|
108118
108948
|
const obj = {};
|
|
@@ -108127,12 +108957,12 @@ function arrayToObject(arr) {
|
|
|
108127
108957
|
return obj;
|
|
108128
108958
|
}
|
|
108129
108959
|
function formDataToJSON(formData) {
|
|
108130
|
-
function buildPath(
|
|
108960
|
+
function buildPath(path5, value, target, index2) {
|
|
108131
108961
|
throwIfDepthExceeded(index2);
|
|
108132
|
-
let name =
|
|
108962
|
+
let name = path5[index2++];
|
|
108133
108963
|
if (name === "__proto__") return true;
|
|
108134
108964
|
const isNumericKey = Number.isFinite(+name);
|
|
108135
|
-
const isLast = index2 >=
|
|
108965
|
+
const isLast = index2 >= path5.length;
|
|
108136
108966
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
108137
108967
|
if (isLast) {
|
|
108138
108968
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -108145,7 +108975,7 @@ function formDataToJSON(formData) {
|
|
|
108145
108975
|
if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
|
|
108146
108976
|
target[name] = [];
|
|
108147
108977
|
}
|
|
108148
|
-
const result = buildPath(
|
|
108978
|
+
const result = buildPath(path5, value, target[name], index2);
|
|
108149
108979
|
if (result && utils_default.isArray(target[name])) {
|
|
108150
108980
|
target[name] = arrayToObject(target[name]);
|
|
108151
108981
|
}
|
|
@@ -111692,9 +112522,9 @@ var init_http4 = __esm({
|
|
|
111692
112522
|
auth = urlUsername + ":" + urlPassword;
|
|
111693
112523
|
}
|
|
111694
112524
|
auth && headers.delete("authorization");
|
|
111695
|
-
let
|
|
112525
|
+
let path5;
|
|
111696
112526
|
try {
|
|
111697
|
-
|
|
112527
|
+
path5 = buildURL(
|
|
111698
112528
|
parsed.pathname + parsed.search,
|
|
111699
112529
|
own2("params"),
|
|
111700
112530
|
own2("paramsSerializer")
|
|
@@ -111713,7 +112543,7 @@ var init_http4 = __esm({
|
|
|
111713
112543
|
false
|
|
111714
112544
|
);
|
|
111715
112545
|
const options = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
111716
|
-
path:
|
|
112546
|
+
path: path5,
|
|
111717
112547
|
method,
|
|
111718
112548
|
headers: toByteStringHeaderObject(headers),
|
|
111719
112549
|
agents: { http: httpAgent, https: httpsAgent },
|
|
@@ -112130,14 +112960,14 @@ var init_cookies = __esm({
|
|
|
112130
112960
|
cookies_default = platform_default.hasStandardBrowserEnv ? (
|
|
112131
112961
|
// Standard browser envs support document.cookie
|
|
112132
112962
|
{
|
|
112133
|
-
write(name, value, expires,
|
|
112963
|
+
write(name, value, expires, path5, domain, secure, sameSite) {
|
|
112134
112964
|
if (typeof document === "undefined") return;
|
|
112135
112965
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
112136
112966
|
if (utils_default.isNumber(expires)) {
|
|
112137
112967
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
112138
112968
|
}
|
|
112139
|
-
if (utils_default.isString(
|
|
112140
|
-
cookie.push(`path=${
|
|
112969
|
+
if (utils_default.isString(path5)) {
|
|
112970
|
+
cookie.push(`path=${path5}`);
|
|
112141
112971
|
}
|
|
112142
112972
|
if (utils_default.isString(domain)) {
|
|
112143
112973
|
cookie.push(`domain=${domain}`);
|
|
@@ -115566,15 +116396,15 @@ var init_constants3 = __esm({
|
|
|
115566
116396
|
});
|
|
115567
116397
|
|
|
115568
116398
|
// src/polymarket/wallet-adapter.ts
|
|
115569
|
-
import
|
|
115570
|
-
import { homedir as
|
|
115571
|
-
import { join as
|
|
116399
|
+
import fs2 from "fs";
|
|
116400
|
+
import { homedir as homedir8 } from "os";
|
|
116401
|
+
import { join as join11 } from "path";
|
|
115572
116402
|
function getOrCreateWalletKey() {
|
|
115573
116403
|
const envKey = process.env.BLOCKRUN_WALLET_KEY?.trim();
|
|
115574
116404
|
if (envKey && /^0x[0-9a-fA-F]{64}$/.test(envKey)) return envKey;
|
|
115575
116405
|
let key2;
|
|
115576
116406
|
try {
|
|
115577
|
-
key2 =
|
|
116407
|
+
key2 = fs2.readFileSync(WALLET_FILE2, "utf-8").trim();
|
|
115578
116408
|
} catch (err) {
|
|
115579
116409
|
if (err.code === "ENOENT") {
|
|
115580
116410
|
throw new Error(
|
|
@@ -115616,7 +116446,7 @@ var init_wallet_adapter = __esm({
|
|
|
115616
116446
|
init_esm();
|
|
115617
116447
|
init_chains();
|
|
115618
116448
|
init_constants3();
|
|
115619
|
-
WALLET_FILE2 =
|
|
116449
|
+
WALLET_FILE2 = join11(homedir8(), ".openclaw", "blockrun", "wallet.key");
|
|
115620
116450
|
BASE_RPC_URLS = [
|
|
115621
116451
|
"https://mainnet.base.org",
|
|
115622
116452
|
"https://base.llamarpc.com",
|
|
@@ -115627,21 +116457,21 @@ var init_wallet_adapter = __esm({
|
|
|
115627
116457
|
});
|
|
115628
116458
|
|
|
115629
116459
|
// src/polymarket/creds.ts
|
|
115630
|
-
import
|
|
115631
|
-
import
|
|
116460
|
+
import fs3 from "fs";
|
|
116461
|
+
import path2 from "path";
|
|
115632
116462
|
import os from "os";
|
|
115633
116463
|
function readJsonFile(file) {
|
|
115634
116464
|
try {
|
|
115635
|
-
if (!
|
|
115636
|
-
const raw =
|
|
116465
|
+
if (!fs3.existsSync(file)) return null;
|
|
116466
|
+
const raw = fs3.readFileSync(file, "utf-8").trim();
|
|
115637
116467
|
return raw ? JSON.parse(raw) : null;
|
|
115638
116468
|
} catch {
|
|
115639
116469
|
return null;
|
|
115640
116470
|
}
|
|
115641
116471
|
}
|
|
115642
116472
|
function writeJsonFile(file, value) {
|
|
115643
|
-
|
|
115644
|
-
|
|
116473
|
+
fs3.mkdirSync(BLOCKRUN_DIR, { recursive: true });
|
|
116474
|
+
fs3.writeFileSync(file, JSON.stringify(value, null, 2), { mode: 384 });
|
|
115645
116475
|
}
|
|
115646
116476
|
function credsKey(address2, sigType) {
|
|
115647
116477
|
return `${address2.toLowerCase()}:${sigType}`;
|
|
@@ -115693,10 +116523,10 @@ var BLOCKRUN_DIR, CREDS_FILE, BUILDER_CREDS_FILE, STATE_FILE;
|
|
|
115693
116523
|
var init_creds = __esm({
|
|
115694
116524
|
"src/polymarket/creds.ts"() {
|
|
115695
116525
|
"use strict";
|
|
115696
|
-
BLOCKRUN_DIR =
|
|
115697
|
-
CREDS_FILE =
|
|
115698
|
-
BUILDER_CREDS_FILE =
|
|
115699
|
-
STATE_FILE =
|
|
116526
|
+
BLOCKRUN_DIR = path2.join(os.homedir(), ".openclaw", "blockrun");
|
|
116527
|
+
CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-creds");
|
|
116528
|
+
BUILDER_CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-builder-creds");
|
|
116529
|
+
STATE_FILE = path2.join(BLOCKRUN_DIR, ".polymarket.json");
|
|
115700
116530
|
}
|
|
115701
116531
|
});
|
|
115702
116532
|
|
|
@@ -116878,13 +117708,13 @@ function __disposeResources(env) {
|
|
|
116878
117708
|
}
|
|
116879
117709
|
return next();
|
|
116880
117710
|
}
|
|
116881
|
-
function __rewriteRelativeImportExtension(
|
|
116882
|
-
if (typeof
|
|
116883
|
-
return
|
|
117711
|
+
function __rewriteRelativeImportExtension(path5, preserveJsx) {
|
|
117712
|
+
if (typeof path5 === "string" && /^\.\.?\//.test(path5)) {
|
|
117713
|
+
return path5.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
116884
117714
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
|
|
116885
117715
|
});
|
|
116886
117716
|
}
|
|
116887
|
-
return
|
|
117717
|
+
return path5;
|
|
116888
117718
|
}
|
|
116889
117719
|
var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
|
|
116890
117720
|
var init_tslib_es6 = __esm({
|
|
@@ -149181,9 +150011,9 @@ var require_setupKzg = __commonJS({
|
|
|
149181
150011
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
149182
150012
|
exports.setupKzg = setupKzg;
|
|
149183
150013
|
var defineKzg_js_1 = require_defineKzg();
|
|
149184
|
-
function setupKzg(parameters,
|
|
150014
|
+
function setupKzg(parameters, path5) {
|
|
149185
150015
|
try {
|
|
149186
|
-
parameters.loadTrustedSetup(
|
|
150016
|
+
parameters.loadTrustedSetup(path5);
|
|
149187
150017
|
} catch (e7) {
|
|
149188
150018
|
const error = e7;
|
|
149189
150019
|
if (!error.message.includes("trusted setup is already loaded"))
|
|
@@ -197268,12 +198098,12 @@ var init_fragments = __esm({
|
|
|
197268
198098
|
// node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js
|
|
197269
198099
|
function checkResultErrors(result) {
|
|
197270
198100
|
const errors = [];
|
|
197271
|
-
const checkErrors = function(
|
|
198101
|
+
const checkErrors = function(path5, object) {
|
|
197272
198102
|
if (!Array.isArray(object)) {
|
|
197273
198103
|
return;
|
|
197274
198104
|
}
|
|
197275
198105
|
for (let key2 in object) {
|
|
197276
|
-
const childPath =
|
|
198106
|
+
const childPath = path5.slice();
|
|
197277
198107
|
childPath.push(key2);
|
|
197278
198108
|
try {
|
|
197279
198109
|
checkErrors(childPath, object[key2]);
|
|
@@ -203091,8 +203921,8 @@ function createCommonjsModule(fn, basedir, module) {
|
|
|
203091
203921
|
return module = {
|
|
203092
203922
|
path: basedir,
|
|
203093
203923
|
exports: {},
|
|
203094
|
-
require: function(
|
|
203095
|
-
return commonjsRequire(
|
|
203924
|
+
require: function(path5, base3) {
|
|
203925
|
+
return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
|
|
203096
203926
|
}
|
|
203097
203927
|
}, fn(module, module.exports), module.exports;
|
|
203098
203928
|
}
|
|
@@ -206942,9 +207772,9 @@ var init_lib23 = __esm({
|
|
|
206942
207772
|
if (index2 > 4294967295) {
|
|
206943
207773
|
throw new Error("invalid index - " + String(index2));
|
|
206944
207774
|
}
|
|
206945
|
-
let
|
|
206946
|
-
if (
|
|
206947
|
-
|
|
207775
|
+
let path5 = this.path;
|
|
207776
|
+
if (path5) {
|
|
207777
|
+
path5 += "/" + (index2 & ~HardenedBit);
|
|
206948
207778
|
}
|
|
206949
207779
|
const data = new Uint8Array(37);
|
|
206950
207780
|
if (index2 & HardenedBit) {
|
|
@@ -206952,8 +207782,8 @@ var init_lib23 = __esm({
|
|
|
206952
207782
|
throw new Error("cannot derive child of neutered node");
|
|
206953
207783
|
}
|
|
206954
207784
|
data.set(arrayify(this.privateKey), 1);
|
|
206955
|
-
if (
|
|
206956
|
-
|
|
207785
|
+
if (path5) {
|
|
207786
|
+
path5 += "'";
|
|
206957
207787
|
}
|
|
206958
207788
|
} else {
|
|
206959
207789
|
data.set(arrayify(this.publicKey));
|
|
@@ -206972,21 +207802,21 @@ var init_lib23 = __esm({
|
|
|
206972
207802
|
const ek = new SigningKey(hexlify(IL));
|
|
206973
207803
|
Ki = ek._addPoint(this.publicKey);
|
|
206974
207804
|
}
|
|
206975
|
-
let mnemonicOrPath =
|
|
207805
|
+
let mnemonicOrPath = path5;
|
|
206976
207806
|
const srcMnemonic = this.mnemonic;
|
|
206977
207807
|
if (srcMnemonic) {
|
|
206978
207808
|
mnemonicOrPath = Object.freeze({
|
|
206979
207809
|
phrase: srcMnemonic.phrase,
|
|
206980
|
-
path:
|
|
207810
|
+
path: path5,
|
|
206981
207811
|
locale: srcMnemonic.locale || "en"
|
|
206982
207812
|
});
|
|
206983
207813
|
}
|
|
206984
207814
|
return new _HDNode(_constructorGuard4, ki, Ki, this.fingerprint, bytes32(IR), index2, this.depth + 1, mnemonicOrPath);
|
|
206985
207815
|
}
|
|
206986
|
-
derivePath(
|
|
206987
|
-
const components =
|
|
207816
|
+
derivePath(path5) {
|
|
207817
|
+
const components = path5.split("/");
|
|
206988
207818
|
if (components.length === 0 || components[0] === "m" && this.depth !== 0) {
|
|
206989
|
-
throw new Error("invalid path - " +
|
|
207819
|
+
throw new Error("invalid path - " + path5);
|
|
206990
207820
|
}
|
|
206991
207821
|
if (components[0] === "m") {
|
|
206992
207822
|
components.shift();
|
|
@@ -207721,9 +208551,9 @@ function getPassword(password) {
|
|
|
207721
208551
|
}
|
|
207722
208552
|
return arrayify(password);
|
|
207723
208553
|
}
|
|
207724
|
-
function searchPath(object,
|
|
208554
|
+
function searchPath(object, path5) {
|
|
207725
208555
|
let currentChild = object;
|
|
207726
|
-
const comps =
|
|
208556
|
+
const comps = path5.toLowerCase().split("/");
|
|
207727
208557
|
for (let i = 0; i < comps.length; i++) {
|
|
207728
208558
|
let matchingChild = null;
|
|
207729
208559
|
for (const key2 in currentChild) {
|
|
@@ -208372,12 +209202,12 @@ function _getAccount(data, key2) {
|
|
|
208372
209202
|
const mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
|
|
208373
209203
|
const mnemonicCounter = new import_aes_js2.default.Counter(mnemonicIv);
|
|
208374
209204
|
const mnemonicAesCtr = new import_aes_js2.default.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
|
208375
|
-
const
|
|
209205
|
+
const path5 = searchPath(data, "x-ethers/path") || defaultPath;
|
|
208376
209206
|
const locale = searchPath(data, "x-ethers/locale") || "en";
|
|
208377
209207
|
const entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
|
|
208378
209208
|
try {
|
|
208379
209209
|
const mnemonic = entropyToMnemonic2(entropy, locale);
|
|
208380
|
-
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(
|
|
209210
|
+
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path5);
|
|
208381
209211
|
if (node.privateKey != account.privateKey) {
|
|
208382
209212
|
throw new Error("mnemonic mismatch");
|
|
208383
209213
|
}
|
|
@@ -208477,12 +209307,12 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208477
209307
|
const privateKey = arrayify(account.privateKey);
|
|
208478
209308
|
const passwordBytes = getPassword(password);
|
|
208479
209309
|
let entropy = null;
|
|
208480
|
-
let
|
|
209310
|
+
let path5 = null;
|
|
208481
209311
|
let locale = null;
|
|
208482
209312
|
if (hasMnemonic(account)) {
|
|
208483
209313
|
const srcMnemonic = account.mnemonic;
|
|
208484
209314
|
entropy = arrayify(mnemonicToEntropy2(srcMnemonic.phrase, srcMnemonic.locale || "en"));
|
|
208485
|
-
|
|
209315
|
+
path5 = srcMnemonic.path || defaultPath;
|
|
208486
209316
|
locale = srcMnemonic.locale || "en";
|
|
208487
209317
|
}
|
|
208488
209318
|
let client = options.client;
|
|
@@ -208568,7 +209398,7 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208568
209398
|
gethFilename: "UTC--" + timestamp + "--" + data.address,
|
|
208569
209399
|
mnemonicCounter: hexlify(mnemonicIv).substring(2),
|
|
208570
209400
|
mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),
|
|
208571
|
-
path:
|
|
209401
|
+
path: path5,
|
|
208572
209402
|
locale,
|
|
208573
209403
|
version: "0.1"
|
|
208574
209404
|
};
|
|
@@ -208862,11 +209692,11 @@ var init_lib26 = __esm({
|
|
|
208862
209692
|
static fromEncryptedJsonSync(json, password) {
|
|
208863
209693
|
return new _Wallet(decryptJsonWalletSync(json, password));
|
|
208864
209694
|
}
|
|
208865
|
-
static fromMnemonic(mnemonic,
|
|
208866
|
-
if (!
|
|
208867
|
-
|
|
209695
|
+
static fromMnemonic(mnemonic, path5, wordlist3) {
|
|
209696
|
+
if (!path5) {
|
|
209697
|
+
path5 = defaultPath;
|
|
208868
209698
|
}
|
|
208869
|
-
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(
|
|
209699
|
+
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(path5));
|
|
208870
209700
|
}
|
|
208871
209701
|
};
|
|
208872
209702
|
}
|
|
@@ -214862,21 +215692,21 @@ var init_web3_provider = __esm({
|
|
|
214862
215692
|
if (provider == null) {
|
|
214863
215693
|
logger43.throwArgumentError("missing provider", "provider", provider);
|
|
214864
215694
|
}
|
|
214865
|
-
let
|
|
215695
|
+
let path5 = null;
|
|
214866
215696
|
let jsonRpcFetchFunc = null;
|
|
214867
215697
|
let subprovider = null;
|
|
214868
215698
|
if (typeof provider === "function") {
|
|
214869
|
-
|
|
215699
|
+
path5 = "unknown:";
|
|
214870
215700
|
jsonRpcFetchFunc = provider;
|
|
214871
215701
|
} else {
|
|
214872
|
-
|
|
214873
|
-
if (!
|
|
214874
|
-
|
|
215702
|
+
path5 = provider.host || provider.path || "";
|
|
215703
|
+
if (!path5 && provider.isMetaMask) {
|
|
215704
|
+
path5 = "metamask";
|
|
214875
215705
|
}
|
|
214876
215706
|
subprovider = provider;
|
|
214877
215707
|
if (provider.request) {
|
|
214878
|
-
if (
|
|
214879
|
-
|
|
215708
|
+
if (path5 === "") {
|
|
215709
|
+
path5 = "eip-1193:";
|
|
214880
215710
|
}
|
|
214881
215711
|
jsonRpcFetchFunc = buildEip1193Fetcher(provider);
|
|
214882
215712
|
} else if (provider.sendAsync) {
|
|
@@ -214886,11 +215716,11 @@ var init_web3_provider = __esm({
|
|
|
214886
215716
|
} else {
|
|
214887
215717
|
logger43.throwArgumentError("unsupported provider", "provider", provider);
|
|
214888
215718
|
}
|
|
214889
|
-
if (!
|
|
214890
|
-
|
|
215719
|
+
if (!path5) {
|
|
215720
|
+
path5 = "unknown:";
|
|
214891
215721
|
}
|
|
214892
215722
|
}
|
|
214893
|
-
super(
|
|
215723
|
+
super(path5, network);
|
|
214894
215724
|
defineReadOnly(this, "jsonRpcFetchFunc", jsonRpcFetchFunc);
|
|
214895
215725
|
defineReadOnly(this, "provider", subprovider);
|
|
214896
215726
|
}
|
|
@@ -215728,7 +216558,7 @@ var require_axios = __commonJS({
|
|
|
215728
216558
|
var https2 = __require("https");
|
|
215729
216559
|
var http23 = __require("http2");
|
|
215730
216560
|
var util5 = __require("util");
|
|
215731
|
-
var
|
|
216561
|
+
var path5 = __require("path");
|
|
215732
216562
|
var followRedirects2 = require_follow_redirects();
|
|
215733
216563
|
var zlib2 = __require("zlib");
|
|
215734
216564
|
var stream4 = __require("stream");
|
|
@@ -216796,9 +217626,9 @@ var require_axios = __commonJS({
|
|
|
216796
217626
|
function removeBrackets2(key2) {
|
|
216797
217627
|
return utils$1.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
216798
217628
|
}
|
|
216799
|
-
function renderKey2(
|
|
216800
|
-
if (!
|
|
216801
|
-
return
|
|
217629
|
+
function renderKey2(path6, key2, dots) {
|
|
217630
|
+
if (!path6) return key2;
|
|
217631
|
+
return path6.concat(key2).map(function each(token, i) {
|
|
216802
217632
|
token = removeBrackets2(token);
|
|
216803
217633
|
return !dots && i ? "[" + token + "]" : token;
|
|
216804
217634
|
}).join(dots ? "." : "");
|
|
@@ -216876,13 +217706,13 @@ var require_axios = __commonJS({
|
|
|
216876
217706
|
return currentValue;
|
|
216877
217707
|
});
|
|
216878
217708
|
}
|
|
216879
|
-
function defaultVisitor(value, key2,
|
|
217709
|
+
function defaultVisitor(value, key2, path6) {
|
|
216880
217710
|
let arr = value;
|
|
216881
217711
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
216882
|
-
formData.append(renderKey2(
|
|
217712
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216883
217713
|
return false;
|
|
216884
217714
|
}
|
|
216885
|
-
if (value && !
|
|
217715
|
+
if (value && !path6 && typeof value === "object") {
|
|
216886
217716
|
if (utils$1.endsWith(key2, "{}")) {
|
|
216887
217717
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
216888
217718
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -216901,7 +217731,7 @@ var require_axios = __commonJS({
|
|
|
216901
217731
|
if (isVisitable2(value)) {
|
|
216902
217732
|
return true;
|
|
216903
217733
|
}
|
|
216904
|
-
formData.append(renderKey2(
|
|
217734
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216905
217735
|
return false;
|
|
216906
217736
|
}
|
|
216907
217737
|
const exposedHelpers = Object.assign(predicates2, {
|
|
@@ -216909,17 +217739,17 @@ var require_axios = __commonJS({
|
|
|
216909
217739
|
convertValue,
|
|
216910
217740
|
isVisitable: isVisitable2
|
|
216911
217741
|
});
|
|
216912
|
-
function build(value,
|
|
217742
|
+
function build(value, path6, depth = 0) {
|
|
216913
217743
|
if (utils$1.isUndefined(value)) return;
|
|
216914
217744
|
throwIfMaxDepthExceeded(depth);
|
|
216915
217745
|
if (stack.indexOf(value) !== -1) {
|
|
216916
|
-
throw new Error("Circular reference detected in " +
|
|
217746
|
+
throw new Error("Circular reference detected in " + path6.join("."));
|
|
216917
217747
|
}
|
|
216918
217748
|
stack.push(value);
|
|
216919
217749
|
utils$1.forEach(value, function each(el, key2) {
|
|
216920
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2,
|
|
217750
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2, path6, exposedHelpers);
|
|
216921
217751
|
if (result === true) {
|
|
216922
|
-
build(el,
|
|
217752
|
+
build(el, path6 ? path6.concat(key2) : [key2], depth + 1);
|
|
216923
217753
|
}
|
|
216924
217754
|
});
|
|
216925
217755
|
stack.pop();
|
|
@@ -217108,7 +217938,7 @@ var require_axios = __commonJS({
|
|
|
217108
217938
|
};
|
|
217109
217939
|
function toURLEncodedForm2(data, options) {
|
|
217110
217940
|
return toFormData3(data, new platform2.classes.URLSearchParams(), {
|
|
217111
|
-
visitor: function(value, key2,
|
|
217941
|
+
visitor: function(value, key2, path6, helpers) {
|
|
217112
217942
|
if (platform2.isNode && utils$1.isBuffer(value)) {
|
|
217113
217943
|
this.append(key2, value.toString("base64"));
|
|
217114
217944
|
return false;
|
|
@@ -217125,14 +217955,14 @@ var require_axios = __commonJS({
|
|
|
217125
217955
|
}
|
|
217126
217956
|
}
|
|
217127
217957
|
function parsePropPath2(name) {
|
|
217128
|
-
const
|
|
217958
|
+
const path6 = [];
|
|
217129
217959
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
217130
217960
|
let match;
|
|
217131
217961
|
while ((match = pattern.exec(name)) !== null) {
|
|
217132
|
-
throwIfDepthExceeded2(
|
|
217133
|
-
|
|
217962
|
+
throwIfDepthExceeded2(path6.length);
|
|
217963
|
+
path6.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
217134
217964
|
}
|
|
217135
|
-
return
|
|
217965
|
+
return path6;
|
|
217136
217966
|
}
|
|
217137
217967
|
function arrayToObject2(arr) {
|
|
217138
217968
|
const obj = {};
|
|
@@ -217147,12 +217977,12 @@ var require_axios = __commonJS({
|
|
|
217147
217977
|
return obj;
|
|
217148
217978
|
}
|
|
217149
217979
|
function formDataToJSON2(formData) {
|
|
217150
|
-
function buildPath(
|
|
217980
|
+
function buildPath(path6, value, target, index2) {
|
|
217151
217981
|
throwIfDepthExceeded2(index2);
|
|
217152
|
-
let name =
|
|
217982
|
+
let name = path6[index2++];
|
|
217153
217983
|
if (name === "__proto__") return true;
|
|
217154
217984
|
const isNumericKey = Number.isFinite(+name);
|
|
217155
|
-
const isLast = index2 >=
|
|
217985
|
+
const isLast = index2 >= path6.length;
|
|
217156
217986
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
217157
217987
|
if (isLast) {
|
|
217158
217988
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -217165,7 +217995,7 @@ var require_axios = __commonJS({
|
|
|
217165
217995
|
if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
|
|
217166
217996
|
target[name] = [];
|
|
217167
217997
|
}
|
|
217168
|
-
const result = buildPath(
|
|
217998
|
+
const result = buildPath(path6, value, target[name], index2);
|
|
217169
217999
|
if (result && utils$1.isArray(target[name])) {
|
|
217170
218000
|
target[name] = arrayToObject2(target[name]);
|
|
217171
218001
|
}
|
|
@@ -218776,8 +219606,8 @@ var require_axios = __commonJS({
|
|
|
218776
219606
|
const allowedSocketPaths = own3("allowedSocketPaths");
|
|
218777
219607
|
if (allowedSocketPaths != null) {
|
|
218778
219608
|
const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
|
|
218779
|
-
const resolvedSocket =
|
|
218780
|
-
const isAllowed = allowed.some((entry) => typeof entry === "string" &&
|
|
219609
|
+
const resolvedSocket = path5.resolve(socketPath);
|
|
219610
|
+
const isAllowed = allowed.some((entry) => typeof entry === "string" && path5.resolve(entry) === resolvedSocket);
|
|
218781
219611
|
if (!isAllowed) {
|
|
218782
219612
|
return reject(new AxiosError3(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError3.ERR_BAD_OPTION_VALUE, config));
|
|
218783
219613
|
}
|
|
@@ -219076,14 +219906,14 @@ var require_axios = __commonJS({
|
|
|
219076
219906
|
var cookies = platform2.hasStandardBrowserEnv ? (
|
|
219077
219907
|
// Standard browser envs support document.cookie
|
|
219078
219908
|
{
|
|
219079
|
-
write(name, value, expires,
|
|
219909
|
+
write(name, value, expires, path6, domain, secure, sameSite) {
|
|
219080
219910
|
if (typeof document === "undefined") return;
|
|
219081
219911
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
219082
219912
|
if (utils$1.isNumber(expires)) {
|
|
219083
219913
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
219084
219914
|
}
|
|
219085
|
-
if (utils$1.isString(
|
|
219086
|
-
cookie.push(`path=${
|
|
219915
|
+
if (utils$1.isString(path6)) {
|
|
219916
|
+
cookie.push(`path=${path6}`);
|
|
219087
219917
|
}
|
|
219088
219918
|
if (utils$1.isString(domain)) {
|
|
219089
219919
|
cookie.push(`domain=${domain}`);
|
|
@@ -223572,18 +224402,18 @@ var require_client2 = __commonJS({
|
|
|
223572
224402
|
}
|
|
223573
224403
|
console.log(`Transaction not found or not in given states, timing out!`);
|
|
223574
224404
|
}
|
|
223575
|
-
async sendAuthedRequest(method,
|
|
224405
|
+
async sendAuthedRequest(method, path5, body) {
|
|
223576
224406
|
if (this.canBuilderAuth()) {
|
|
223577
|
-
const builderHeaders = await this._generateBuilderHeaders(method,
|
|
224407
|
+
const builderHeaders = await this._generateBuilderHeaders(method, path5, body);
|
|
223578
224408
|
if (builderHeaders !== void 0) {
|
|
223579
|
-
return this.send(
|
|
224409
|
+
return this.send(path5, method, { headers: builderHeaders, data: body });
|
|
223580
224410
|
}
|
|
223581
224411
|
}
|
|
223582
|
-
return this.send(
|
|
224412
|
+
return this.send(path5, method, { data: body });
|
|
223583
224413
|
}
|
|
223584
|
-
async _generateBuilderHeaders(method,
|
|
224414
|
+
async _generateBuilderHeaders(method, path5, body) {
|
|
223585
224415
|
if (this.builderConfig !== void 0) {
|
|
223586
|
-
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method,
|
|
224416
|
+
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method, path5, body);
|
|
223587
224417
|
if (builderHeaders == void 0) {
|
|
223588
224418
|
return void 0;
|
|
223589
224419
|
}
|
|
@@ -223674,12 +224504,12 @@ var require_signer = __commonJS({
|
|
|
223674
224504
|
constructor(creds) {
|
|
223675
224505
|
this.creds = creds;
|
|
223676
224506
|
}
|
|
223677
|
-
createBuilderHeaderPayload(method,
|
|
224507
|
+
createBuilderHeaderPayload(method, path5, body, timestamp) {
|
|
223678
224508
|
let ts = Math.floor(Date.now() / 1e3);
|
|
223679
224509
|
if (timestamp !== void 0) {
|
|
223680
224510
|
ts = timestamp;
|
|
223681
224511
|
}
|
|
223682
|
-
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method,
|
|
224512
|
+
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method, path5, body);
|
|
223683
224513
|
return {
|
|
223684
224514
|
POLY_BUILDER_API_KEY: this.creds.key,
|
|
223685
224515
|
POLY_BUILDER_PASSPHRASE: this.creds.passphrase,
|
|
@@ -223768,17 +224598,17 @@ var require_config2 = __commonJS({
|
|
|
223768
224598
|
* @param path
|
|
223769
224599
|
* @param body
|
|
223770
224600
|
*/
|
|
223771
|
-
async generateBuilderHeaders(method,
|
|
224601
|
+
async generateBuilderHeaders(method, path5, body, timestamp) {
|
|
223772
224602
|
this.ensureValid();
|
|
223773
224603
|
const builderType = this.getBuilderType();
|
|
223774
224604
|
if (builderType == types_1.BuilderType.LOCAL) {
|
|
223775
|
-
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method,
|
|
224605
|
+
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method, path5, body, timestamp));
|
|
223776
224606
|
}
|
|
223777
224607
|
if (builderType == types_1.BuilderType.REMOTE) {
|
|
223778
224608
|
const url2 = this.remoteBuilderConfig.url;
|
|
223779
224609
|
const payload = {
|
|
223780
224610
|
method,
|
|
223781
|
-
path:
|
|
224611
|
+
path: path5,
|
|
223782
224612
|
body,
|
|
223783
224613
|
timestamp
|
|
223784
224614
|
};
|
|
@@ -224560,11 +225390,11 @@ var init_withdraw = __esm({
|
|
|
224560
225390
|
});
|
|
224561
225391
|
|
|
224562
225392
|
// node_modules/@blockrun/llm/dist/index.js
|
|
224563
|
-
import * as
|
|
225393
|
+
import * as path3 from "path";
|
|
224564
225394
|
import * as os2 from "os";
|
|
224565
225395
|
import * as path22 from "path";
|
|
224566
225396
|
import * as os22 from "os";
|
|
224567
|
-
import * as
|
|
225397
|
+
import * as path32 from "path";
|
|
224568
225398
|
import * as os3 from "os";
|
|
224569
225399
|
import * as path4 from "path";
|
|
224570
225400
|
import * as os4 from "os";
|
|
@@ -224738,7 +225568,7 @@ function resolveDefaultTimeout() {
|
|
|
224738
225568
|
function sleep2(ms) {
|
|
224739
225569
|
return new Promise((r2) => setTimeout(r2, ms));
|
|
224740
225570
|
}
|
|
224741
|
-
var BlockrunError, PaymentError, APIError, BASE_CHAIN_ID2, USDC_BASE2, USDC_DOMAIN, TRANSFER_TYPES, BLOCKRUN_SERVICE_CODE2, LOCALHOST_DOMAINS, BLOCKRUN_DIR2, COST_LOG_FILE, SDK_VERSION, USER_AGENT2, DEFAULT_TIMEOUT, PHONE_PRICES, DEFAULT_API_URL13, DEFAULT_TIMEOUT13, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_BUDGET_MS, MAX_SIGNED_AUTH_SECONDS, BlockrunClient,
|
|
225571
|
+
var BlockrunError, PaymentError, APIError, BASE_CHAIN_ID2, USDC_BASE2, USDC_DOMAIN, TRANSFER_TYPES, BLOCKRUN_SERVICE_CODE2, LOCALHOST_DOMAINS, BLOCKRUN_DIR2, COST_LOG_FILE, SDK_VERSION, USER_AGENT2, DEFAULT_TIMEOUT, PHONE_PRICES, DEFAULT_API_URL13, DEFAULT_TIMEOUT13, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_BUDGET_MS, MAX_SIGNED_AUTH_SECONDS, BlockrunClient, WALLET_DIR3, WALLET_FILE3, WALLET_DIR22, SOLANA_WALLET_FILE, CACHE_DIR, DATA_DIR, COST_LOG_FILE2, DEFAULT_TTL;
|
|
224742
225572
|
var init_dist7 = __esm({
|
|
224743
225573
|
"node_modules/@blockrun/llm/dist/index.js"() {
|
|
224744
225574
|
"use strict";
|
|
@@ -224786,8 +225616,8 @@ var init_dist7 = __esm({
|
|
|
224786
225616
|
};
|
|
224787
225617
|
BLOCKRUN_SERVICE_CODE2 = "blockrun";
|
|
224788
225618
|
LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
|
|
224789
|
-
BLOCKRUN_DIR2 =
|
|
224790
|
-
COST_LOG_FILE =
|
|
225619
|
+
BLOCKRUN_DIR2 = path3.join(os2.homedir(), ".blockrun");
|
|
225620
|
+
COST_LOG_FILE = path3.join(BLOCKRUN_DIR2, "cost_log.jsonl");
|
|
224791
225621
|
SDK_VERSION = "3.10.0";
|
|
224792
225622
|
USER_AGENT2 = `blockrun-ts/${SDK_VERSION}`;
|
|
224793
225623
|
DEFAULT_TIMEOUT = resolveDefaultTimeout();
|
|
@@ -224832,15 +225662,15 @@ var init_dist7 = __esm({
|
|
|
224832
225662
|
* `/api` is tolerated and stripped). Query params are URL-encoded; arrays
|
|
224833
225663
|
* become repeated keys (`?a=1&a=2`); undefined/null are dropped.
|
|
224834
225664
|
*/
|
|
224835
|
-
async get(
|
|
224836
|
-
const url2 = this.buildUrl(
|
|
225665
|
+
async get(path5, params) {
|
|
225666
|
+
const url2 = this.buildUrl(path5, params);
|
|
224837
225667
|
return this.requestWithPayment(url2, "GET");
|
|
224838
225668
|
}
|
|
224839
225669
|
/**
|
|
224840
225670
|
* POST a BlockRun endpoint with a JSON body.
|
|
224841
225671
|
*/
|
|
224842
|
-
async post(
|
|
224843
|
-
const url2 = this.buildUrl(
|
|
225672
|
+
async post(path5, body) {
|
|
225673
|
+
const url2 = this.buildUrl(path5);
|
|
224844
225674
|
return this.requestWithPayment(url2, "POST", body);
|
|
224845
225675
|
}
|
|
224846
225676
|
/**
|
|
@@ -224855,8 +225685,8 @@ var init_dist7 = __esm({
|
|
|
224855
225685
|
* short-circuits and returns the body. Most long-running endpoints (image,
|
|
224856
225686
|
* video, music, voice) return 202 with a poll_url.
|
|
224857
225687
|
*/
|
|
224858
|
-
async poll(
|
|
224859
|
-
const submitUrl = this.buildUrl(
|
|
225688
|
+
async poll(path5, body, options) {
|
|
225689
|
+
const submitUrl = this.buildUrl(path5);
|
|
224860
225690
|
const budgetMs = options?.budgetMs ?? DEFAULT_POLL_BUDGET_MS;
|
|
224861
225691
|
const intervalMs = options?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
224862
225692
|
const resp402 = await this.fetchWithTimeout(submitUrl, {
|
|
@@ -224955,8 +225785,8 @@ var init_dist7 = __esm({
|
|
|
224955
225785
|
* process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
|
|
224956
225786
|
* }
|
|
224957
225787
|
*/
|
|
224958
|
-
async *stream(
|
|
224959
|
-
const url2 = this.buildUrl(
|
|
225788
|
+
async *stream(path5, body) {
|
|
225789
|
+
const url2 = this.buildUrl(path5);
|
|
224960
225790
|
const requestBody = JSON.stringify(body ?? {});
|
|
224961
225791
|
const resp402 = await this.fetchWithTimeout(url2, {
|
|
224962
225792
|
method: "POST",
|
|
@@ -225022,8 +225852,8 @@ var init_dist7 = __esm({
|
|
|
225022
225852
|
// --------------------------------------------------------------------
|
|
225023
225853
|
// Internal: shared infrastructure
|
|
225024
225854
|
// --------------------------------------------------------------------
|
|
225025
|
-
buildUrl(
|
|
225026
|
-
let normalized =
|
|
225855
|
+
buildUrl(path5, params) {
|
|
225856
|
+
let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
|
|
225027
225857
|
if (normalized.startsWith("/api/")) {
|
|
225028
225858
|
normalized = normalized.slice(4);
|
|
225029
225859
|
}
|
|
@@ -225171,10 +226001,10 @@ var init_dist7 = __esm({
|
|
|
225171
226001
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
225172
226002
|
}
|
|
225173
226003
|
};
|
|
225174
|
-
|
|
225175
|
-
WALLET_FILE3 = path22.join(
|
|
225176
|
-
WALLET_DIR22 =
|
|
225177
|
-
SOLANA_WALLET_FILE =
|
|
226004
|
+
WALLET_DIR3 = path22.join(os22.homedir(), ".blockrun");
|
|
226005
|
+
WALLET_FILE3 = path22.join(WALLET_DIR3, ".session");
|
|
226006
|
+
WALLET_DIR22 = path32.join(os3.homedir(), ".blockrun");
|
|
226007
|
+
SOLANA_WALLET_FILE = path32.join(WALLET_DIR22, ".solana-session");
|
|
225178
226008
|
CACHE_DIR = path4.join(os4.homedir(), ".blockrun", "cache");
|
|
225179
226009
|
DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
|
|
225180
226010
|
COST_LOG_FILE2 = path4.join(os4.homedir(), ".blockrun", "cost_log.jsonl");
|
|
@@ -225670,261 +226500,6 @@ var init_mcp_config = __esm({
|
|
|
225670
226500
|
}
|
|
225671
226501
|
});
|
|
225672
226502
|
|
|
225673
|
-
// src/spend-control.ts
|
|
225674
|
-
import * as fs3 from "fs";
|
|
225675
|
-
import * as path5 from "path";
|
|
225676
|
-
import { homedir as homedir12 } from "os";
|
|
225677
|
-
function formatDuration(seconds) {
|
|
225678
|
-
if (seconds < 60) {
|
|
225679
|
-
return `${seconds}s`;
|
|
225680
|
-
} else if (seconds < 3600) {
|
|
225681
|
-
const mins = Math.ceil(seconds / 60);
|
|
225682
|
-
return `${mins} min`;
|
|
225683
|
-
} else {
|
|
225684
|
-
const hours = Math.floor(seconds / 3600);
|
|
225685
|
-
const mins = Math.ceil(seconds % 3600 / 60);
|
|
225686
|
-
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
225687
|
-
}
|
|
225688
|
-
}
|
|
225689
|
-
var WALLET_DIR3, HOUR_MS, DAY_MS, FileSpendControlStorage, InMemorySpendControlStorage, SpendControl;
|
|
225690
|
-
var init_spend_control = __esm({
|
|
225691
|
-
"src/spend-control.ts"() {
|
|
225692
|
-
"use strict";
|
|
225693
|
-
init_fs_read();
|
|
225694
|
-
WALLET_DIR3 = path5.join(homedir12(), ".openclaw", "blockrun");
|
|
225695
|
-
HOUR_MS = 60 * 60 * 1e3;
|
|
225696
|
-
DAY_MS = 24 * HOUR_MS;
|
|
225697
|
-
FileSpendControlStorage = class {
|
|
225698
|
-
spendingFile;
|
|
225699
|
-
constructor() {
|
|
225700
|
-
this.spendingFile = path5.join(WALLET_DIR3, "spending.json");
|
|
225701
|
-
}
|
|
225702
|
-
load() {
|
|
225703
|
-
try {
|
|
225704
|
-
if (fs3.existsSync(this.spendingFile)) {
|
|
225705
|
-
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
225706
|
-
const rawLimits = data.limits ?? {};
|
|
225707
|
-
const rawHistory = data.history ?? [];
|
|
225708
|
-
const limits = {};
|
|
225709
|
-
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
225710
|
-
const val = rawLimits[key2];
|
|
225711
|
-
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
225712
|
-
limits[key2] = val;
|
|
225713
|
-
}
|
|
225714
|
-
}
|
|
225715
|
-
const history = [];
|
|
225716
|
-
if (Array.isArray(rawHistory)) {
|
|
225717
|
-
for (const r2 of rawHistory) {
|
|
225718
|
-
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
225719
|
-
history.push({
|
|
225720
|
-
timestamp: r2.timestamp,
|
|
225721
|
-
amount: r2.amount,
|
|
225722
|
-
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
225723
|
-
action: typeof r2.action === "string" ? r2.action : void 0
|
|
225724
|
-
});
|
|
225725
|
-
}
|
|
225726
|
-
}
|
|
225727
|
-
}
|
|
225728
|
-
return { limits, history };
|
|
225729
|
-
}
|
|
225730
|
-
} catch (err) {
|
|
225731
|
-
console.error(`[ClawRouter] Failed to load spending data, starting fresh: ${err}`);
|
|
225732
|
-
}
|
|
225733
|
-
return null;
|
|
225734
|
-
}
|
|
225735
|
-
save(data) {
|
|
225736
|
-
try {
|
|
225737
|
-
if (!fs3.existsSync(WALLET_DIR3)) {
|
|
225738
|
-
fs3.mkdirSync(WALLET_DIR3, { recursive: true, mode: 448 });
|
|
225739
|
-
}
|
|
225740
|
-
fs3.writeFileSync(this.spendingFile, JSON.stringify(data, null, 2), {
|
|
225741
|
-
mode: 384
|
|
225742
|
-
});
|
|
225743
|
-
} catch (err) {
|
|
225744
|
-
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
225745
|
-
}
|
|
225746
|
-
}
|
|
225747
|
-
};
|
|
225748
|
-
InMemorySpendControlStorage = class {
|
|
225749
|
-
data = null;
|
|
225750
|
-
load() {
|
|
225751
|
-
return this.data ? {
|
|
225752
|
-
limits: { ...this.data.limits },
|
|
225753
|
-
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
225754
|
-
} : null;
|
|
225755
|
-
}
|
|
225756
|
-
save(data) {
|
|
225757
|
-
this.data = {
|
|
225758
|
-
limits: { ...data.limits },
|
|
225759
|
-
history: data.history.map((r2) => ({ ...r2 }))
|
|
225760
|
-
};
|
|
225761
|
-
}
|
|
225762
|
-
};
|
|
225763
|
-
SpendControl = class {
|
|
225764
|
-
limits = {};
|
|
225765
|
-
history = [];
|
|
225766
|
-
sessionSpent = 0;
|
|
225767
|
-
sessionCalls = 0;
|
|
225768
|
-
storage;
|
|
225769
|
-
now;
|
|
225770
|
-
constructor(options) {
|
|
225771
|
-
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
225772
|
-
this.now = options?.now ?? (() => Date.now());
|
|
225773
|
-
this.load();
|
|
225774
|
-
}
|
|
225775
|
-
setLimit(window2, amount) {
|
|
225776
|
-
if (!Number.isFinite(amount) || amount <= 0) {
|
|
225777
|
-
throw new Error("Limit must be a finite positive number");
|
|
225778
|
-
}
|
|
225779
|
-
this.limits[window2] = amount;
|
|
225780
|
-
this.save();
|
|
225781
|
-
}
|
|
225782
|
-
clearLimit(window2) {
|
|
225783
|
-
delete this.limits[window2];
|
|
225784
|
-
this.save();
|
|
225785
|
-
}
|
|
225786
|
-
getLimits() {
|
|
225787
|
-
return { ...this.limits };
|
|
225788
|
-
}
|
|
225789
|
-
check(estimatedCost2) {
|
|
225790
|
-
const now2 = this.now();
|
|
225791
|
-
if (this.limits.perRequest !== void 0) {
|
|
225792
|
-
if (estimatedCost2 > this.limits.perRequest) {
|
|
225793
|
-
return {
|
|
225794
|
-
allowed: false,
|
|
225795
|
-
blockedBy: "perRequest",
|
|
225796
|
-
remaining: this.limits.perRequest,
|
|
225797
|
-
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
225798
|
-
};
|
|
225799
|
-
}
|
|
225800
|
-
}
|
|
225801
|
-
if (this.limits.hourly !== void 0) {
|
|
225802
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225803
|
-
const remaining = this.limits.hourly - hourlySpent;
|
|
225804
|
-
if (estimatedCost2 > remaining) {
|
|
225805
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
225806
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
225807
|
-
return {
|
|
225808
|
-
allowed: false,
|
|
225809
|
-
blockedBy: "hourly",
|
|
225810
|
-
remaining,
|
|
225811
|
-
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
225812
|
-
resetIn
|
|
225813
|
-
};
|
|
225814
|
-
}
|
|
225815
|
-
}
|
|
225816
|
-
if (this.limits.daily !== void 0) {
|
|
225817
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225818
|
-
const remaining = this.limits.daily - dailySpent;
|
|
225819
|
-
if (estimatedCost2 > remaining) {
|
|
225820
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
225821
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
225822
|
-
return {
|
|
225823
|
-
allowed: false,
|
|
225824
|
-
blockedBy: "daily",
|
|
225825
|
-
remaining,
|
|
225826
|
-
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
225827
|
-
resetIn
|
|
225828
|
-
};
|
|
225829
|
-
}
|
|
225830
|
-
}
|
|
225831
|
-
if (this.limits.session !== void 0) {
|
|
225832
|
-
const remaining = this.limits.session - this.sessionSpent;
|
|
225833
|
-
if (estimatedCost2 > remaining) {
|
|
225834
|
-
return {
|
|
225835
|
-
allowed: false,
|
|
225836
|
-
blockedBy: "session",
|
|
225837
|
-
remaining,
|
|
225838
|
-
reason: `Session limit exceeded: $${(this.sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
225839
|
-
};
|
|
225840
|
-
}
|
|
225841
|
-
}
|
|
225842
|
-
return { allowed: true };
|
|
225843
|
-
}
|
|
225844
|
-
record(amount, metadata) {
|
|
225845
|
-
if (!Number.isFinite(amount) || amount < 0) {
|
|
225846
|
-
throw new Error("Record amount must be a non-negative finite number");
|
|
225847
|
-
}
|
|
225848
|
-
const record = {
|
|
225849
|
-
timestamp: this.now(),
|
|
225850
|
-
amount,
|
|
225851
|
-
model: metadata?.model,
|
|
225852
|
-
action: metadata?.action
|
|
225853
|
-
};
|
|
225854
|
-
this.history.push(record);
|
|
225855
|
-
this.sessionSpent += amount;
|
|
225856
|
-
this.sessionCalls += 1;
|
|
225857
|
-
this.cleanup();
|
|
225858
|
-
this.save();
|
|
225859
|
-
}
|
|
225860
|
-
getSpendingInWindow(from15, to) {
|
|
225861
|
-
return this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
225862
|
-
}
|
|
225863
|
-
getSpending(window2) {
|
|
225864
|
-
const now2 = this.now();
|
|
225865
|
-
switch (window2) {
|
|
225866
|
-
case "hourly":
|
|
225867
|
-
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225868
|
-
case "daily":
|
|
225869
|
-
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225870
|
-
case "session":
|
|
225871
|
-
return this.sessionSpent;
|
|
225872
|
-
}
|
|
225873
|
-
}
|
|
225874
|
-
getRemaining(window2) {
|
|
225875
|
-
const limit = this.limits[window2];
|
|
225876
|
-
if (limit === void 0) return null;
|
|
225877
|
-
return Math.max(0, limit - this.getSpending(window2));
|
|
225878
|
-
}
|
|
225879
|
-
getStatus() {
|
|
225880
|
-
const now2 = this.now();
|
|
225881
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225882
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225883
|
-
return {
|
|
225884
|
-
limits: { ...this.limits },
|
|
225885
|
-
spending: {
|
|
225886
|
-
hourly: hourlySpent,
|
|
225887
|
-
daily: dailySpent,
|
|
225888
|
-
session: this.sessionSpent
|
|
225889
|
-
},
|
|
225890
|
-
remaining: {
|
|
225891
|
-
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
225892
|
-
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
225893
|
-
session: this.limits.session !== void 0 ? this.limits.session - this.sessionSpent : null
|
|
225894
|
-
},
|
|
225895
|
-
calls: this.sessionCalls
|
|
225896
|
-
};
|
|
225897
|
-
}
|
|
225898
|
-
getHistory(limit) {
|
|
225899
|
-
const records = [...this.history].reverse();
|
|
225900
|
-
return limit ? records.slice(0, limit) : records;
|
|
225901
|
-
}
|
|
225902
|
-
resetSession() {
|
|
225903
|
-
this.sessionSpent = 0;
|
|
225904
|
-
this.sessionCalls = 0;
|
|
225905
|
-
}
|
|
225906
|
-
cleanup() {
|
|
225907
|
-
const cutoff = this.now() - DAY_MS;
|
|
225908
|
-
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
225909
|
-
}
|
|
225910
|
-
save() {
|
|
225911
|
-
this.storage.save({
|
|
225912
|
-
limits: { ...this.limits },
|
|
225913
|
-
history: [...this.history]
|
|
225914
|
-
});
|
|
225915
|
-
}
|
|
225916
|
-
load() {
|
|
225917
|
-
const data = this.storage.load();
|
|
225918
|
-
if (data) {
|
|
225919
|
-
this.limits = data.limits;
|
|
225920
|
-
this.history = data.history;
|
|
225921
|
-
this.cleanup();
|
|
225922
|
-
}
|
|
225923
|
-
}
|
|
225924
|
-
};
|
|
225925
|
-
}
|
|
225926
|
-
});
|
|
225927
|
-
|
|
225928
226503
|
// src/retry.ts
|
|
225929
226504
|
function sleep3(ms) {
|
|
225930
226505
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -225993,6 +226568,8 @@ __export(index_exports, {
|
|
|
225993
226568
|
BALANCE_THRESHOLDS: () => BALANCE_THRESHOLDS,
|
|
225994
226569
|
BLOCKRUN_MODELS: () => BLOCKRUN_MODELS,
|
|
225995
226570
|
BalanceMonitor: () => BalanceMonitor,
|
|
226571
|
+
CAIP2_BASE: () => CAIP2_BASE,
|
|
226572
|
+
CAIP2_SOLANA_MAINNET: () => CAIP2_SOLANA_MAINNET,
|
|
225996
226573
|
DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
|
|
225997
226574
|
DEFAULT_ROUTING_CONFIG: () => DEFAULT_ROUTING_CONFIG,
|
|
225998
226575
|
DEFAULT_SESSION_CONFIG: () => DEFAULT_SESSION_CONFIG,
|
|
@@ -226001,6 +226578,7 @@ __export(index_exports, {
|
|
|
226001
226578
|
InMemorySpendControlStorage: () => InMemorySpendControlStorage,
|
|
226002
226579
|
InsufficientFundsError: () => InsufficientFundsError2,
|
|
226003
226580
|
MODEL_ALIASES: () => MODEL_ALIASES,
|
|
226581
|
+
MalformedSpendPolicyError: () => MalformedSpendPolicyError,
|
|
226004
226582
|
OPENCLAW_MODELS: () => OPENCLAW_MODELS,
|
|
226005
226583
|
PARTNER_SERVICES: () => PARTNER_SERVICES,
|
|
226006
226584
|
RequestDeduplicator: () => RequestDeduplicator,
|
|
@@ -226009,6 +226587,7 @@ __export(index_exports, {
|
|
|
226009
226587
|
SessionStore: () => SessionStore,
|
|
226010
226588
|
SolanaBalanceMonitor: () => SolanaBalanceMonitor,
|
|
226011
226589
|
SpendControl: () => SpendControl,
|
|
226590
|
+
SpendPolicyError: () => SpendPolicyError,
|
|
226012
226591
|
VISIBLE_OPENCLAW_MODELS: () => VISIBLE_OPENCLAW_MODELS,
|
|
226013
226592
|
blockrunProvider: () => blockrunProvider,
|
|
226014
226593
|
buildImageGenerationProvider: () => buildImageGenerationProvider,
|
|
@@ -226048,6 +226627,7 @@ __export(index_exports, {
|
|
|
226048
226627
|
loadPaymentChain: () => loadPaymentChain,
|
|
226049
226628
|
logUsage: () => logUsage,
|
|
226050
226629
|
parseCallArgs: () => parseCallArgs,
|
|
226630
|
+
registerSpendPolicyHook: () => registerSpendPolicyHook,
|
|
226051
226631
|
resolveModelAlias: () => resolveModelAlias,
|
|
226052
226632
|
resolvePaymentChain: () => resolvePaymentChain,
|
|
226053
226633
|
route: () => route,
|
|
@@ -226062,7 +226642,7 @@ import {
|
|
|
226062
226642
|
readdirSync,
|
|
226063
226643
|
mkdirSync as mkdirSync3,
|
|
226064
226644
|
copyFileSync,
|
|
226065
|
-
renameSync
|
|
226645
|
+
renameSync as renameSync2
|
|
226066
226646
|
} from "fs";
|
|
226067
226647
|
import { readFile as readFileAsync } from "fs/promises";
|
|
226068
226648
|
import { homedir as homedir13 } from "os";
|
|
@@ -226340,7 +226920,7 @@ function injectModelsConfig(logger48, options = {}) {
|
|
|
226340
226920
|
try {
|
|
226341
226921
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
226342
226922
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
226343
|
-
|
|
226923
|
+
renameSync2(tmpPath, configPath);
|
|
226344
226924
|
logger48.info("Smart routing enabled (blockrun/auto)");
|
|
226345
226925
|
} catch (err) {
|
|
226346
226926
|
logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -226376,7 +226956,7 @@ function syncAgentModelCache(logger48, options = {}) {
|
|
|
226376
226956
|
entry.models = VISIBLE_OPENCLAW_MODELS;
|
|
226377
226957
|
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
226378
226958
|
writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
|
|
226379
|
-
|
|
226959
|
+
renameSync2(tmpPath, cachePath);
|
|
226380
226960
|
logger48.info(
|
|
226381
226961
|
`Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
|
|
226382
226962
|
);
|
|
@@ -227740,7 +228320,7 @@ ${errText}`
|
|
|
227740
228320
|
}
|
|
227741
228321
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
227742
228322
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
227743
|
-
|
|
228323
|
+
renameSync2(tmpPath, configPath);
|
|
227744
228324
|
api.logger.info("ClawRouter config cleaned up");
|
|
227745
228325
|
}
|
|
227746
228326
|
} catch (err) {
|
|
@@ -227835,7 +228415,7 @@ init_stats();
|
|
|
227835
228415
|
init_proxy();
|
|
227836
228416
|
init_version4();
|
|
227837
228417
|
import { platform, arch, freemem, totalmem } from "os";
|
|
227838
|
-
import { existsSync as
|
|
228418
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
227839
228419
|
function formatBytes(bytes) {
|
|
227840
228420
|
const gb = bytes / (1024 * 1024 * 1024);
|
|
227841
228421
|
return `${gb.toFixed(1)}GB`;
|
|
@@ -228124,7 +228704,7 @@ async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
|
|
|
228124
228704
|
const paymentChain = diagnostics.wallet.paymentChain;
|
|
228125
228705
|
if (paymentChain === "solana") {
|
|
228126
228706
|
try {
|
|
228127
|
-
if (!
|
|
228707
|
+
if (!existsSync3(MNEMONIC_FILE)) {
|
|
228128
228708
|
throw new Error(`mnemonic file missing at ${MNEMONIC_FILE}`);
|
|
228129
228709
|
}
|
|
228130
228710
|
const mnemonic = readFileSync3(MNEMONIC_FILE, "utf8").trim();
|
|
@@ -228287,8 +228867,8 @@ Environment Variables:
|
|
|
228287
228867
|
For more info: https://blockrun.ai/clawrouter.md
|
|
228288
228868
|
`);
|
|
228289
228869
|
}
|
|
228290
|
-
async function queryProxy(
|
|
228291
|
-
const res = await fetch(`http://127.0.0.1:${port}${
|
|
228870
|
+
async function queryProxy(path5, port) {
|
|
228871
|
+
const res = await fetch(`http://127.0.0.1:${port}${path5}`);
|
|
228292
228872
|
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
|
|
228293
228873
|
return res.json();
|
|
228294
228874
|
}
|
|
@@ -228368,8 +228948,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
|
|
|
228368
228948
|
const { join: pjoin } = await import("path");
|
|
228369
228949
|
const paths = [];
|
|
228370
228950
|
for (const p of VALID_PRESETS) {
|
|
228371
|
-
const
|
|
228372
|
-
const result = await queryProxy(
|
|
228951
|
+
const path5 = idOrLast === "last" ? `/share/last?as=${p}` : `/share/${idOrLast}/render?as=${p}`;
|
|
228952
|
+
const result = await queryProxy(path5, port);
|
|
228373
228953
|
const file = pjoin(tmpdir(), `claw-share-${result.id}-${p}.txt`);
|
|
228374
228954
|
await writeFile3(file, result.rendered, "utf8");
|
|
228375
228955
|
paths.push(file);
|
|
@@ -228390,8 +228970,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
|
|
|
228390
228970
|
process.exit(1);
|
|
228391
228971
|
}
|
|
228392
228972
|
try {
|
|
228393
|
-
const
|
|
228394
|
-
const result = await queryProxy(
|
|
228973
|
+
const path5 = idOrLast === "last" ? `/share/last?as=${chosenPreset}` : `/share/${idOrLast}/render?as=${chosenPreset}`;
|
|
228974
|
+
const result = await queryProxy(path5, port);
|
|
228395
228975
|
process.stdout.write(result.rendered);
|
|
228396
228976
|
if (!result.rendered.endsWith("\n")) process.stdout.write("\n");
|
|
228397
228977
|
const clipErr = await copyToClipboard(result.rendered);
|
|
@@ -228511,8 +229091,8 @@ Usage Stats (last ${days} days)
|
|
|
228511
229091
|
}
|
|
228512
229092
|
async function cmdPhone(port, subcommand, numbersAction, arg, areaCode) {
|
|
228513
229093
|
const base3 = `http://127.0.0.1:${port}`;
|
|
228514
|
-
async function postJson(
|
|
228515
|
-
const resp = await fetch(`${base3}${
|
|
229094
|
+
async function postJson(path5, body) {
|
|
229095
|
+
const resp = await fetch(`${base3}${path5}`, {
|
|
228516
229096
|
method: "POST",
|
|
228517
229097
|
headers: { "content-type": "application/json" },
|
|
228518
229098
|
body: JSON.stringify(body)
|
|
@@ -228614,12 +229194,12 @@ Releasing ${arg}...
|
|
|
228614
229194
|
console.error(`\u2717 Usage: clawrouter phone ${subcommand} <+E.164-number>`);
|
|
228615
229195
|
process.exit(1);
|
|
228616
229196
|
}
|
|
228617
|
-
const
|
|
229197
|
+
const path5 = subcommand === "fraud" ? "/v1/phone/lookup/fraud" : "/v1/phone/lookup";
|
|
228618
229198
|
const price = subcommand === "fraud" ? "$0.05" : "$0.01";
|
|
228619
229199
|
console.log(`
|
|
228620
229200
|
Looking up ${arg}... (${price})
|
|
228621
229201
|
`);
|
|
228622
|
-
const result = await postJson(
|
|
229202
|
+
const result = await postJson(path5, { phoneNumber: arg });
|
|
228623
229203
|
console.log(JSON.stringify(result, null, 2));
|
|
228624
229204
|
console.log();
|
|
228625
229205
|
}
|