@blockrun/llm 3.24.4 → 3.24.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ### Cut your LLM bill by <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->%. One line of TypeScript.
6
6
 
7
- The smart-routing SDK for <!-- br:models.chatVisible -->88<!-- /br:models.chatVisible --> models — every request goes to the cheapest model that can handle it,
7
+ The smart-routing SDK for <!-- br:models.chatVisible -->90<!-- /br:models.chatVisible --> models — every request goes to the cheapest model that can handle it,
8
8
  paid with an API key or per-request USDC on Solana, Base or Arc. No vendor lock-in.
9
9
 
10
10
  [![npm](https://img.shields.io/npm/v/@blockrun/llm.svg?style=flat-square)](https://www.npmjs.com/package/@blockrun/llm)
@@ -56,7 +56,7 @@ console.log(r.response); // the proof
56
56
  | | OpenAI SDK | OpenRouter | LiteLLM | **@blockrun/llm** |
57
57
  | ------------------ | -------------- | ----------------- | ---------------- | ----------------------------------------------------------------------- |
58
58
  | **Cost routing** | ✗ one vendor | Manual selection | Manual selection | **Automatic — <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->% cheaper** |
59
- | **Models** | GPT only | 200+ | 100+ (BYO keys) | **<!-- br:models.chatVisible -->88<!-- /br:models.chatVisible -->, one credential** |
59
+ | **Models** | GPT only | 200+ | 100+ (BYO keys) | **<!-- br:models.chatVisible -->90<!-- /br:models.chatVisible -->, one credential** |
60
60
  | **Free tier** | ✗ | Rate-limited | ✗ | **<!-- br:models.free -->7<!-- /br:models.free --> models, no signup** |
61
61
  | **Auth** | API key | Account + API key | Your API keys | **API key *or* wallet signature** |
62
62
  | **Payment** | Card + invoice | Credit card | BYO keys | **Account credit or USDC per-request** |
@@ -1811,7 +1811,7 @@ to pick up security fixes.
1811
1811
  ## Frequently Asked Questions
1812
1812
 
1813
1813
  ### What is @blockrun/llm?
1814
- A TypeScript SDK that cuts LLM costs by <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->% on a realistic workload with built-in smart routing: every request goes to the cheapest of <!-- br:models.chatVisible -->88<!-- /br:models.chatVisible --> models (OpenAI, Anthropic, Google, xAI, DeepSeek, Moonshot, and more) that can handle it, paid with an account API key or per-request USDC via x402 on Solana, Base or Arc.
1814
+ A TypeScript SDK that cuts LLM costs by <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->% on a realistic workload with built-in smart routing: every request goes to the cheapest of <!-- br:models.chatVisible -->90<!-- /br:models.chatVisible --> models (OpenAI, Anthropic, Google, xAI, DeepSeek, Moonshot, and more) that can handle it, paid with an account API key or per-request USDC via x402 on Solana, Base or Arc.
1815
1815
 
1816
1816
  ### What is smart routing?
1817
1817
  Router Core V3, bundled into the SDK: the same deterministic engine that powers ClawRouter. It analyzes each request across <!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions --> dimensions locally, in under 1ms, and picks the cheapest capable model. Use `smartChat()`, `smartChatCompletion()`, or the `blockrun/auto` model alias. See [Smart Routing](#smart-routing-router-core-v3).
package/dist/index.cjs CHANGED
@@ -571,7 +571,7 @@ function withCost(body, response, bookedUsd, scheme) {
571
571
  // src/client.ts
572
572
  var import_accounts2 = require("viem/accounts");
573
573
 
574
- // node_modules/.pnpm/@blockrun+router-core@https+++codeload.github.com+BlockRunAI+router-core+tar.gz+8773a9954b091_rjdkm4uoakz3dfyojiwn3sv45i/node_modules/@blockrun/router-core/dist/index.js
574
+ // node_modules/.pnpm/@blockrun+router-core@https+++codeload.github.com+BlockRunAI+router-core+tar.gz+fd6d03d035ff6_meidvh7c7i3y7wjjl6r2ymc4py/node_modules/@blockrun/router-core/dist/index.js
575
575
  var UNSEGMENTED_SCRIPT = /[؀-ۿ -ヿ㐀-䶿一-鿿가-힯豈-﫿＀-￯]/;
576
576
  var WORD_CHAR = /[\p{L}\p{N}]/u;
577
577
  var ASCII_PHRASE = /^[a-z0-9' -]+$/;
@@ -2903,10 +2903,10 @@ function isEligible(modelId, features, maxOutputTokens, options) {
2903
2903
  return model.contextWindow >= (features.estimatedInputTokens + maxOutputTokens) * 1.1;
2904
2904
  }
2905
2905
  function estimatedCost(modelId, options, inputTokens, outputTokens) {
2906
- const price = options.modelPricing.get(modelId);
2907
- if (!price) return Number.POSITIVE_INFINITY;
2908
- if (price.flatPrice !== void 0) return price.flatPrice;
2909
- return (inputTokens * price.inputPrice + outputTokens * price.outputPrice) / 1e6;
2906
+ const price2 = options.modelPricing.get(modelId);
2907
+ if (!price2) return Number.POSITIVE_INFINITY;
2908
+ if (price2.flatPrice !== void 0) return price2.flatPrice;
2909
+ return (inputTokens * price2.inputPrice + outputTokens * price2.outputPrice) / 1e6;
2910
2910
  }
2911
2911
  function profileScore(modelId, options, now) {
2912
2912
  const profile = options.modelPerformance?.[modelId] ?? LIVE_MODEL_PROFILES[modelId] ?? HISTORICAL_MODEL_PROFILES[modelId];
@@ -5089,7 +5089,7 @@ function getCostSummary() {
5089
5089
  }
5090
5090
 
5091
5091
  // src/version.ts
5092
- var SDK_VERSION = "3.24.4";
5092
+ var SDK_VERSION = "3.24.6";
5093
5093
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
5094
5094
 
5095
5095
  // src/client.ts
@@ -5157,8 +5157,15 @@ var LLMClient = class _LLMClient {
5157
5157
  modelPricingCache = null;
5158
5158
  modelPricingPromise = null;
5159
5159
  // Pre-auth cache: avoids the 402 round-trip on repeat requests to the same model.
5160
- // Key = "endpoint:model", value = cached payment header + timestamp.
5160
+ // Key = "endpoint:model", value = cached payment header + timestamp + the
5161
+ // length of the request body it was quoted for.
5161
5162
  // TTL: 1 hour — pre-auth quotes are stable server-side on that horizon.
5163
+ //
5164
+ // A quote prices ONE request (input size + max_tokens), and exact settles
5165
+ // the whole signed amount, so reusing it for a smaller request overpaid and
5166
+ // for a larger one underpaid. The gateway refuses both with a 402 (an
5167
+ // over-signed payment since blockrun#874), so a reuse is only attempted for
5168
+ // a body the same size as the one that was quoted.
5162
5169
  preAuthCache = /* @__PURE__ */ new Map();
5163
5170
  static PRE_AUTH_TTL_MS = 36e5;
5164
5171
  /**
@@ -5765,9 +5772,10 @@ var LLMClient = class _LLMClient {
5765
5772
  if (options?.responseFormat !== void 0) body.response_format = options.responseFormat;
5766
5773
  if (options?.stop !== void 0) body.stop = options.stop;
5767
5774
  const cacheKey2 = `/v1/chat/completions:${requestModel}`;
5775
+ const requestBody = JSON.stringify(body);
5768
5776
  const cached = this.preAuthCache.get(cacheKey2);
5769
5777
  const now = Date.now();
5770
- if (cached && now - cached.cachedAt < _LLMClient.PRE_AUTH_TTL_MS) {
5778
+ if (cached && now - cached.cachedAt < _LLMClient.PRE_AUTH_TTL_MS && cached.bodyLength === requestBody.length) {
5771
5779
  let signed;
5772
5780
  try {
5773
5781
  signed = await this.signPayment(cached.paymentHeader);
@@ -5836,7 +5844,7 @@ var LLMClient = class _LLMClient {
5836
5844
  }
5837
5845
  }
5838
5846
  if (!paymentHeader) throw new PaymentError("402 response but no payment requirements found");
5839
- this.preAuthCache.set(cacheKey2, { paymentHeader, cachedAt: now });
5847
+ this.preAuthCache.set(cacheKey2, { paymentHeader, cachedAt: now, bodyLength: requestBody.length });
5840
5848
  const { paymentPayload, costUsd } = await this.signPayment(paymentHeader);
5841
5849
  const streamResp = await this.fetchWithTimeout(url, {
5842
5850
  method: "POST",
package/dist/index.js CHANGED
@@ -440,7 +440,7 @@ function withCost(body, response, bookedUsd, scheme) {
440
440
  // src/client.ts
441
441
  import { privateKeyToAccount } from "viem/accounts";
442
442
 
443
- // node_modules/.pnpm/@blockrun+router-core@https+++codeload.github.com+BlockRunAI+router-core+tar.gz+8773a9954b091_rjdkm4uoakz3dfyojiwn3sv45i/node_modules/@blockrun/router-core/dist/index.js
443
+ // node_modules/.pnpm/@blockrun+router-core@https+++codeload.github.com+BlockRunAI+router-core+tar.gz+fd6d03d035ff6_meidvh7c7i3y7wjjl6r2ymc4py/node_modules/@blockrun/router-core/dist/index.js
444
444
  var UNSEGMENTED_SCRIPT = /[؀-ۿ -ヿ㐀-䶿一-鿿가-힯豈-﫿＀-￯]/;
445
445
  var WORD_CHAR = /[\p{L}\p{N}]/u;
446
446
  var ASCII_PHRASE = /^[a-z0-9' -]+$/;
@@ -2772,10 +2772,10 @@ function isEligible(modelId, features, maxOutputTokens, options) {
2772
2772
  return model.contextWindow >= (features.estimatedInputTokens + maxOutputTokens) * 1.1;
2773
2773
  }
2774
2774
  function estimatedCost(modelId, options, inputTokens, outputTokens) {
2775
- const price = options.modelPricing.get(modelId);
2776
- if (!price) return Number.POSITIVE_INFINITY;
2777
- if (price.flatPrice !== void 0) return price.flatPrice;
2778
- return (inputTokens * price.inputPrice + outputTokens * price.outputPrice) / 1e6;
2775
+ const price2 = options.modelPricing.get(modelId);
2776
+ if (!price2) return Number.POSITIVE_INFINITY;
2777
+ if (price2.flatPrice !== void 0) return price2.flatPrice;
2778
+ return (inputTokens * price2.inputPrice + outputTokens * price2.outputPrice) / 1e6;
2779
2779
  }
2780
2780
  function profileScore(modelId, options, now) {
2781
2781
  const profile = options.modelPerformance?.[modelId] ?? LIVE_MODEL_PROFILES[modelId] ?? HISTORICAL_MODEL_PROFILES[modelId];
@@ -4958,7 +4958,7 @@ function getCostSummary() {
4958
4958
  }
4959
4959
 
4960
4960
  // src/version.ts
4961
- var SDK_VERSION = "3.24.4";
4961
+ var SDK_VERSION = "3.24.6";
4962
4962
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4963
4963
 
4964
4964
  // src/client.ts
@@ -5026,8 +5026,15 @@ var LLMClient = class _LLMClient {
5026
5026
  modelPricingCache = null;
5027
5027
  modelPricingPromise = null;
5028
5028
  // Pre-auth cache: avoids the 402 round-trip on repeat requests to the same model.
5029
- // Key = "endpoint:model", value = cached payment header + timestamp.
5029
+ // Key = "endpoint:model", value = cached payment header + timestamp + the
5030
+ // length of the request body it was quoted for.
5030
5031
  // TTL: 1 hour — pre-auth quotes are stable server-side on that horizon.
5032
+ //
5033
+ // A quote prices ONE request (input size + max_tokens), and exact settles
5034
+ // the whole signed amount, so reusing it for a smaller request overpaid and
5035
+ // for a larger one underpaid. The gateway refuses both with a 402 (an
5036
+ // over-signed payment since blockrun#874), so a reuse is only attempted for
5037
+ // a body the same size as the one that was quoted.
5031
5038
  preAuthCache = /* @__PURE__ */ new Map();
5032
5039
  static PRE_AUTH_TTL_MS = 36e5;
5033
5040
  /**
@@ -5634,9 +5641,10 @@ var LLMClient = class _LLMClient {
5634
5641
  if (options?.responseFormat !== void 0) body.response_format = options.responseFormat;
5635
5642
  if (options?.stop !== void 0) body.stop = options.stop;
5636
5643
  const cacheKey2 = `/v1/chat/completions:${requestModel}`;
5644
+ const requestBody = JSON.stringify(body);
5637
5645
  const cached = this.preAuthCache.get(cacheKey2);
5638
5646
  const now = Date.now();
5639
- if (cached && now - cached.cachedAt < _LLMClient.PRE_AUTH_TTL_MS) {
5647
+ if (cached && now - cached.cachedAt < _LLMClient.PRE_AUTH_TTL_MS && cached.bodyLength === requestBody.length) {
5640
5648
  let signed;
5641
5649
  try {
5642
5650
  signed = await this.signPayment(cached.paymentHeader);
@@ -5705,7 +5713,7 @@ var LLMClient = class _LLMClient {
5705
5713
  }
5706
5714
  }
5707
5715
  if (!paymentHeader) throw new PaymentError("402 response but no payment requirements found");
5708
- this.preAuthCache.set(cacheKey2, { paymentHeader, cachedAt: now });
5716
+ this.preAuthCache.set(cacheKey2, { paymentHeader, cachedAt: now, bodyLength: requestBody.length });
5709
5717
  const { paymentPayload, costUsd } = await this.signPayment(paymentHeader);
5710
5718
  const streamResp = await this.fetchWithTimeout(url, {
5711
5719
  method: "POST",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.24.4",
3
+ "version": "3.24.6",
4
4
  "type": "module",
5
5
  "description": "TypeScript SDK for BlockRun - every frontier model behind one OpenAI-compatible client. Pay with a BlockRun API key or per-call in USDC. Smart routing picks the cheapest capable model. No rate limits.",
6
6
  "main": "dist/index.cjs",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "devDependencies": {
60
60
  "@blockrun/core": "^0.1.0",
61
- "@blockrun/router-core": "https://codeload.github.com/BlockRunAI/router-core/tar.gz/8773a9954b091bd0090acdfec67c75a006c0e156",
61
+ "@blockrun/router-core": "https://codeload.github.com/BlockRunAI/router-core/tar.gz/fd6d03d035ff676642ba1683c333d929939f8a00",
62
62
  "@eslint/js": "^10.0.1",
63
63
  "@solana/kit": "^5.5.1",
64
64
  "@types/node": "^26.4.1",