@blockrun/clawrouter 0.12.285 → 0.12.287

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/dist/index.d.ts CHANGED
@@ -359,9 +359,128 @@ type OpenClawPluginDefinition = {
359
359
  };
360
360
  };
361
361
 
362
+ /**
363
+ * BlockRun Model Definitions for OpenClaw
364
+ *
365
+ * Maps BlockRun's model catalog to OpenClaw's ModelDefinitionConfig format.
366
+ * All models use the "openai-completions" API since BlockRun is OpenAI-compatible.
367
+ *
368
+ * Pricing is in USD per 1M tokens. Operators pay these rates via x402;
369
+ * they set their own markup when reselling to end users (Phase 2).
370
+ */
371
+
372
+ /**
373
+ * Model aliases for convenient shorthand access.
374
+ * Users can type `/model claude` instead of `/model blockrun/anthropic/claude-sonnet-4-6`.
375
+ */
376
+ declare const MODEL_ALIASES: Record<string, string>;
377
+ /**
378
+ * Resolve a model alias to its full model ID.
379
+ * Also strips "blockrun/" prefix for direct model paths.
380
+ * Examples:
381
+ * - "claude" -> "anthropic/claude-sonnet-4-6" (alias)
382
+ * - "blockrun/claude" -> "anthropic/claude-sonnet-4-6" (alias with prefix)
383
+ * - "blockrun/anthropic/claude-sonnet-4-6" -> "anthropic/claude-sonnet-4-6" (prefix stripped)
384
+ * - "openai/gpt-4o" -> "openai/gpt-4o" (unchanged)
385
+ */
386
+ declare function resolveModelAlias(model: string): string;
387
+ type BlockRunModel = {
388
+ id: string;
389
+ name: string;
390
+ /** Model version (e.g., "4.6", "3.1", "5.2") for tracking updates */
391
+ version?: string;
392
+ inputPrice: number;
393
+ outputPrice: number;
394
+ contextWindow: number;
395
+ maxOutput: number;
396
+ reasoning?: boolean;
397
+ vision?: boolean;
398
+ /** Models optimized for agentic workflows (multi-step autonomous tasks) */
399
+ agentic?: boolean;
400
+ /**
401
+ * Model supports OpenAI-compatible structured function/tool calling.
402
+ * Models without this flag output tool invocations as plain text JSON,
403
+ * which leaks raw {"command":"..."} into visible chat messages.
404
+ * Default: false (must opt-in to prevent silent regressions on new models).
405
+ */
406
+ toolCalling?: boolean;
407
+ /** Model is deprecated — will be routed to fallbackModel if set */
408
+ deprecated?: boolean;
409
+ /** Model ID to route to when this model is deprecated */
410
+ fallbackModel?: string;
411
+ /** Time-limited promotional pricing — auto-expires after endDate */
412
+ promo?: {
413
+ /** Flat price per request in USD (replaces token-based pricing) */
414
+ flatPrice: number;
415
+ /** ISO date, promo starts (inclusive). e.g. "2026-04-01" */
416
+ startDate: string;
417
+ /** ISO date, promo ends (exclusive). e.g. "2026-04-15" */
418
+ endDate: string;
419
+ };
420
+ /**
421
+ * Permanent flat per-request price in USD (backend billingMode: "flat").
422
+ * Unlike promo, this never expires. Takes precedence over promo.
423
+ */
424
+ flatPrice?: number;
425
+ };
426
+ declare const BLOCKRUN_MODELS: BlockRunModel[];
427
+ /**
428
+ * All BlockRun models in OpenClaw format (including aliases).
429
+ * Used for proxy-side resolution (alias → target ID), tool routing, etc.
430
+ *
431
+ * Catalog entries shadowed by an identically-keyed alias are excluded:
432
+ * resolveModelAlias checks MODEL_ALIASES first, so those catalog entries are
433
+ * unreachable and their metadata (name/pricing) would misadvertise what
434
+ * callers actually get. The alias-derived entry carries the redirect
435
+ * target's real metadata instead.
436
+ */
437
+ declare const OPENCLAW_MODELS: ModelDefinitionConfig[];
438
+ declare const VISIBLE_OPENCLAW_MODELS: ModelDefinitionConfig[];
439
+ /**
440
+ * Build a ModelProviderConfig for BlockRun.
441
+ *
442
+ * Returns only the TOP_MODELS-listed subset so the OpenClaw picker stays
443
+ * focused. Hidden models are still resolvable through the proxy.
444
+ *
445
+ * @param baseUrl - The proxy's local base URL (e.g., "http://127.0.0.1:12345")
446
+ */
447
+ declare function buildProviderModels(baseUrl: string): ModelProviderConfig;
448
+ /**
449
+ * Check if a model is optimized for agentic workflows.
450
+ * Agentic models continue autonomously with multi-step tasks
451
+ * instead of stopping and waiting for user input.
452
+ */
453
+ declare function isAgenticModel(modelId: string): boolean;
454
+ /**
455
+ * Get all agentic-capable models.
456
+ */
457
+ declare function getAgenticModels(): string[];
458
+ /**
459
+ * Get context window size for a model.
460
+ * Returns undefined if model not found.
461
+ */
462
+ declare function getModelContextWindow(modelId: string): number | undefined;
463
+
362
464
  /** OpenClaw's bundled router owns `clawrouter`; BlockRun must never claim it. */
363
465
  declare const BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
364
466
 
467
+ /** Model metadata only. This client has no wallet or payment-signing capability. */
468
+
469
+ type ModelCatalogView = {
470
+ models: BlockRunModel[];
471
+ openclaw: ModelDefinitionConfig[];
472
+ visible: ModelDefinitionConfig[];
473
+ /**
474
+ * Models ClawRouter treats as free: its own `free/*` products, and only
475
+ * those. This set gates the strict cost cap, the balance preflight and the
476
+ * budget filters, so it never takes a gateway listing's word for it: a
477
+ * model the listing calls free but whose 402 quotes a price would otherwise
478
+ * be signed with no cap check. A gateway-free model is still priced at 0
479
+ * here, so its estimates are 0 and the signing hooks check its real quote.
480
+ */
481
+ freeIds: ReadonlySet<string>;
482
+ };
483
+
365
484
  /**
366
485
  * Response Cache for LLM Completions
367
486
  *
@@ -1067,26 +1186,44 @@ declare function getSessionId(headers: Record<string, string | string[] | undefi
1067
1186
  declare function hashRequestContent(lastUserContent: string, toolCallNames?: string[]): string;
1068
1187
 
1069
1188
  /**
1070
- * Local x402 Proxy Server
1071
- *
1072
- * Sits between OpenClaw's pi-ai (which makes standard OpenAI-format requests)
1073
- * and BlockRun's API (which requires x402 micropayments).
1189
+ * Solana batch-settlement, paid by @blockrun/llm's SolanaBatchPayer.
1074
1190
  *
1075
- * Flow:
1076
- * pi-ai → http://localhost:{port}/v1/chat/completions
1077
- * → proxy forwards to https://blockrun.ai/api/v1/chat/completions
1078
- * → gets 402 → @x402/fetch signs payment → retries
1079
- * → streams response back to pi-ai
1191
+ * `exact` signs one SPL transfer per call at the call's ceiling (the quote for
1192
+ * `max_tokens`). `batch-settlement` opens a deposit-backed channel once; each
1193
+ * call then carries a signed authorization for its ceiling, and the gateway
1194
+ * charges what the call actually cost. ClawRouter does not implement the
1195
+ * protocol: it uses the same payer `SolanaLLMClient` ships, so both clients
1196
+ * share one hardened path (in-doubt payments are never replaced, the channel
1197
+ * file is locked across processes, 429s cool the wallet down, a refused
1198
+ * deposit parks the wallet on exact).
1080
1199
  *
1081
- * Optimizations (v0.3.0):
1082
- * - SSE heartbeat: for streaming requests, sends headers + heartbeat immediately
1083
- * before the x402 flow, preventing OpenClaw's 10-15s timeout from firing.
1084
- * - Response dedup: hashes request bodies and caches responses for 30s,
1085
- * preventing double-charging when OpenClaw retries after timeout.
1086
- * - Smart routing: when model is "blockrun/auto", classify query and pick cheapest model.
1087
- * - Usage logging: log every request as JSON line to ~/.openclaw/blockrun/logs/
1200
+ * The channel's voucher signer is BlockRun's operator key, pinned here as the
1201
+ * only trusted operator. The deposit is escrow under that key, bounded by
1202
+ * `maxDeposit`; spend is the per-call charge. ClawRouter's own spend rules
1203
+ * (SpendControl, the strict session cap) see each batch payment at its
1204
+ * per-call ceiling through `configureClient`, exactly as they see `exact`
1205
+ * payments, and only when the user configured them.
1088
1206
  */
1089
1207
 
1208
+ interface SolanaBatchSettings {
1209
+ /** Escrow cap per channel, e.g. "$5". Unset: @x402/svm's default ("$1"). */
1210
+ maxDeposit?: string | number;
1211
+ /**
1212
+ * Operator keys trusted to sign vouchers. Default: BlockRun's
1213
+ * (`BLOCKRUN_SOL_OPERATOR`). Only for a key rotation, when both keys are
1214
+ * valid for a while. Never trust the operator a 402 names.
1215
+ */
1216
+ operators?: string[];
1217
+ /**
1218
+ * Where open-channel state is kept: a file path, or `false` for memory only.
1219
+ * Default: @blockrun/llm's `~/.blockrun/solana-batch/<address>.json`, locked
1220
+ * to one process at a time.
1221
+ */
1222
+ channelStore?: string | false;
1223
+ /** @internal Replay budget for a payment in doubt, in ms (tests shorten it). */
1224
+ inDoubtMaxWaitMs?: number;
1225
+ }
1226
+
1090
1227
  /** Union type for chain- and auth-agnostic balance monitoring */
1091
1228
  type AnyBalanceMonitor = BalanceMonitor | SolanaBalanceMonitor | ApiKeyBalanceMonitor;
1092
1229
 
@@ -1201,6 +1338,7 @@ type ProxyOptions = {
1201
1338
  * Loaded from ~/.openclaw/blockrun/exclude-models.json
1202
1339
  */
1203
1340
  excludeModels?: Set<string>;
1341
+ onCatalogUpdated?: (models: ModelCatalogView["visible"]) => void;
1204
1342
  onReady?: (port: number) => void;
1205
1343
  onError?: (error: Error) => void;
1206
1344
  onPayment?: (info: {
@@ -1227,6 +1365,16 @@ type ProxyOptions = {
1227
1365
  * ~/.openclaw/blockrun/spending.json. Inject in tests.
1228
1366
  */
1229
1367
  spendControl?: SpendControl;
1368
+ /**
1369
+ * Solana batch-settlement for chat calls on the Solana rail: one deposit
1370
+ * opens a payment channel with BlockRun, then each call is charged what it
1371
+ * actually cost instead of its ceiling. `true` turns it on with the default
1372
+ * escrow cap; an object sets `maxDeposit`. Default: off, unless
1373
+ * CLAWROUTER_SOLANA_BATCH is set.
1374
+ */
1375
+ solanaBatch?: boolean | SolanaBatchSettings;
1376
+ /** @internal Set by startProxy when Solana batch-settlement is active. */
1377
+ _solanaBatchActive?: boolean;
1230
1378
  /**
1231
1379
  * Upstream proxy URL for all outgoing requests.
1232
1380
  * Supports http://, https://, and socks5:// schemes.
@@ -1236,6 +1384,8 @@ type ProxyOptions = {
1236
1384
  upstreamProxy?: string;
1237
1385
  };
1238
1386
  type ProxyHandle = {
1387
+ /** Current proxy-owned picker view; credentials are never exposed here. */
1388
+ getCatalogModels?: () => ModelCatalogView["visible"];
1239
1389
  port: number;
1240
1390
  baseUrl: string;
1241
1391
  /** The x402 signer's address, or "" in API-key mode (there is no wallet). */
@@ -1324,108 +1474,6 @@ declare function resolvePaymentChain(): Promise<"base" | "solana">;
1324
1474
  */
1325
1475
  declare const blockrunProvider: ProviderPlugin;
1326
1476
 
1327
- /**
1328
- * BlockRun Model Definitions for OpenClaw
1329
- *
1330
- * Maps BlockRun's model catalog to OpenClaw's ModelDefinitionConfig format.
1331
- * All models use the "openai-completions" API since BlockRun is OpenAI-compatible.
1332
- *
1333
- * Pricing is in USD per 1M tokens. Operators pay these rates via x402;
1334
- * they set their own markup when reselling to end users (Phase 2).
1335
- */
1336
-
1337
- /**
1338
- * Model aliases for convenient shorthand access.
1339
- * Users can type `/model claude` instead of `/model blockrun/anthropic/claude-sonnet-4-6`.
1340
- */
1341
- declare const MODEL_ALIASES: Record<string, string>;
1342
- /**
1343
- * Resolve a model alias to its full model ID.
1344
- * Also strips "blockrun/" prefix for direct model paths.
1345
- * Examples:
1346
- * - "claude" -> "anthropic/claude-sonnet-4-6" (alias)
1347
- * - "blockrun/claude" -> "anthropic/claude-sonnet-4-6" (alias with prefix)
1348
- * - "blockrun/anthropic/claude-sonnet-4-6" -> "anthropic/claude-sonnet-4-6" (prefix stripped)
1349
- * - "openai/gpt-4o" -> "openai/gpt-4o" (unchanged)
1350
- */
1351
- declare function resolveModelAlias(model: string): string;
1352
- type BlockRunModel = {
1353
- id: string;
1354
- name: string;
1355
- /** Model version (e.g., "4.6", "3.1", "5.2") for tracking updates */
1356
- version?: string;
1357
- inputPrice: number;
1358
- outputPrice: number;
1359
- contextWindow: number;
1360
- maxOutput: number;
1361
- reasoning?: boolean;
1362
- vision?: boolean;
1363
- /** Models optimized for agentic workflows (multi-step autonomous tasks) */
1364
- agentic?: boolean;
1365
- /**
1366
- * Model supports OpenAI-compatible structured function/tool calling.
1367
- * Models without this flag output tool invocations as plain text JSON,
1368
- * which leaks raw {"command":"..."} into visible chat messages.
1369
- * Default: false (must opt-in to prevent silent regressions on new models).
1370
- */
1371
- toolCalling?: boolean;
1372
- /** Model is deprecated — will be routed to fallbackModel if set */
1373
- deprecated?: boolean;
1374
- /** Model ID to route to when this model is deprecated */
1375
- fallbackModel?: string;
1376
- /** Time-limited promotional pricing — auto-expires after endDate */
1377
- promo?: {
1378
- /** Flat price per request in USD (replaces token-based pricing) */
1379
- flatPrice: number;
1380
- /** ISO date, promo starts (inclusive). e.g. "2026-04-01" */
1381
- startDate: string;
1382
- /** ISO date, promo ends (exclusive). e.g. "2026-04-15" */
1383
- endDate: string;
1384
- };
1385
- /**
1386
- * Permanent flat per-request price in USD (backend billingMode: "flat").
1387
- * Unlike promo, this never expires. Takes precedence over promo.
1388
- */
1389
- flatPrice?: number;
1390
- };
1391
- declare const BLOCKRUN_MODELS: BlockRunModel[];
1392
- /**
1393
- * All BlockRun models in OpenClaw format (including aliases).
1394
- * Used for proxy-side resolution (alias → target ID), tool routing, etc.
1395
- *
1396
- * Catalog entries shadowed by an identically-keyed alias are excluded:
1397
- * resolveModelAlias checks MODEL_ALIASES first, so those catalog entries are
1398
- * unreachable and their metadata (name/pricing) would misadvertise what
1399
- * callers actually get. The alias-derived entry carries the redirect
1400
- * target's real metadata instead.
1401
- */
1402
- declare const OPENCLAW_MODELS: ModelDefinitionConfig[];
1403
- declare const VISIBLE_OPENCLAW_MODELS: ModelDefinitionConfig[];
1404
- /**
1405
- * Build a ModelProviderConfig for BlockRun.
1406
- *
1407
- * Returns only the TOP_MODELS-listed subset so the OpenClaw picker stays
1408
- * focused. Hidden models are still resolvable through the proxy.
1409
- *
1410
- * @param baseUrl - The proxy's local base URL (e.g., "http://127.0.0.1:12345")
1411
- */
1412
- declare function buildProviderModels(baseUrl: string): ModelProviderConfig;
1413
- /**
1414
- * Check if a model is optimized for agentic workflows.
1415
- * Agentic models continue autonomously with multi-step tasks
1416
- * instead of stopping and waiting for user input.
1417
- */
1418
- declare function isAgenticModel(modelId: string): boolean;
1419
- /**
1420
- * Get all agentic-capable models.
1421
- */
1422
- declare function getAgenticModels(): string[];
1423
- /**
1424
- * Get context window size for a model.
1425
- * Returns undefined if model not found.
1426
- */
1427
- declare function getModelContextWindow(modelId: string): number | undefined;
1428
-
1429
1477
  /**
1430
1478
  * Usage Logger
1431
1479
  *
@@ -1819,6 +1867,7 @@ declare function injectModelsConfig(logger: {
1819
1867
  info: (msg: string) => void;
1820
1868
  }, options?: {
1821
1869
  forceWrite?: boolean;
1870
+ catalogModels?: typeof VISIBLE_OPENCLAW_MODELS;
1822
1871
  }): void;
1823
1872
  /**
1824
1873
  * Repair the per-agent model cache OpenClaw keeps at
@@ -1845,6 +1894,7 @@ declare function syncAgentModelCache(logger: {
1845
1894
  info: (msg: string) => void;
1846
1895
  }, options?: {
1847
1896
  forceWrite?: boolean;
1897
+ catalogModels?: typeof VISIBLE_OPENCLAW_MODELS;
1848
1898
  }): void;
1849
1899
  /**
1850
1900
  * Inject dummy auth profile for BlockRun into agent auth stores.