@blockrun/llm 3.9.0 → 3.11.0
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 +128 -36
- package/dist/index.cjs +108 -31
- package/dist/index.d.cts +236 -32
- package/dist/index.d.ts +236 -32
- package/dist/index.js +107 -31
- package/package.json +15 -7
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @blockrun/llm (TypeScript SDK)
|
|
2
2
|
|
|
3
|
-
> **@blockrun/llm** is a TypeScript/Node.js SDK for accessing <!-- br:models.chatVisible -->
|
|
3
|
+
> **@blockrun/llm** is a TypeScript/Node.js SDK for accessing <!-- br:models.chatVisible -->71<!-- /br:models.chatVisible --> large language models (GPT-5, Claude, Gemini, Grok, DeepSeek, Kimi, and more) with automatic pay-per-request USDC micropayments via the x402 protocol. No API keys required — your wallet signature is your authentication. Supports **streaming**, smart routing, Base and Solana chains.
|
|
4
4
|
>
|
|
5
5
|
> 🆓 **Includes 7 fully-free NVIDIA-hosted models** (5 visible in `/v1/models`, 2 hidden but directly callable) — DeepSeek V4 Flash (1M context), Nemotron Nano Omni (vision), Qwen3 Coder, Llama 4, Mistral, plus the gpt-oss pair. Zero USDC, no rate-limit gimmicks. Use `routingProfile: 'free'` or call any `nvidia/*` model directly.
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
## Installation
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
# Base
|
|
24
|
+
# Base / EVM payments — nothing else needed
|
|
25
25
|
npm install @blockrun/llm
|
|
26
26
|
# or
|
|
27
27
|
pnpm add @blockrun/llm
|
|
@@ -29,6 +29,21 @@ pnpm add @blockrun/llm
|
|
|
29
29
|
yarn add @blockrun/llm
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
**Solana payments** need two more packages. They are optional peer dependencies,
|
|
33
|
+
so npm will not install them for you:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @blockrun/llm @solana/web3.js @solana/spl-token
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Why they are not automatic: `@solana/spl-token` pulls in `bigint-buffer`, whose
|
|
40
|
+
native `toBigIntLE()` has an unpatched buffer overflow
|
|
41
|
+
([GHSA-3gc7-fjrx-p6mg](https://github.com/advisories/GHSA-3gc7-fjrx-p6mg)) with no
|
|
42
|
+
fixed release anywhere. As an optional *dependency* it landed in the lockfile of
|
|
43
|
+
every consumer, including projects that only ever pay on Base. As an optional
|
|
44
|
+
*peer* it reaches only the projects that ask for Solana. Calling a Solana path
|
|
45
|
+
without them throws an error naming the exact install command.
|
|
46
|
+
|
|
32
47
|
## Quick Start (Base - Default)
|
|
33
48
|
|
|
34
49
|
```typescript
|
|
@@ -221,7 +236,24 @@ Every paid request is a real on-chain USDC transfer — look up your wallet addr
|
|
|
221
236
|
|
|
222
237
|
## Smart Routing (ClawRouter)
|
|
223
238
|
|
|
224
|
-
Let the SDK automatically pick the cheapest capable model for each request:
|
|
239
|
+
Let the SDK automatically pick the cheapest capable model for each request — **<!-- br:savings.autoVsBaselinePct -->88<!-- /br:savings.autoVsBaselinePct -->% cheaper than pinning Claude Opus 5** for the same traffic on `auto`, **<!-- br:savings.ecoVsBaselinePct -->98<!-- /br:savings.ecoVsBaselinePct -->%** on `eco`.
|
|
240
|
+
|
|
241
|
+
Not an "up to" figure. The baseline, the workload mix and the token ratio are
|
|
242
|
+
published in [`savings-mix.json`](https://github.com/BlockRunAI/blockrun/blob/main/src/brand/savings-mix.json),
|
|
243
|
+
priced against the live catalog, so anyone can recompute the claim and get the
|
|
244
|
+
same answer.
|
|
245
|
+
|
|
246
|
+
Smart routing is powered by [ClawRouter](https://github.com/BlockRunAI/ClawRouter) —
|
|
247
|
+
the open-source, agent-first LLM router: wallet signatures instead of API keys,
|
|
248
|
+
USDC micropayments instead of credit cards, and <1ms fully-local routing with
|
|
249
|
+
zero external calls. In this SDK it is an **optional peer dependency** —
|
|
250
|
+
install it alongside the SDK:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm install @blockrun/clawrouter
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Only `smartChat()` needs it: every other API works without it, and the package is loaded lazily, so a missing or broken router can never break `import '@blockrun/llm'`. Calling `smartChat()` without it throws an error naming the package instead of a cryptic module-load failure.
|
|
225
257
|
|
|
226
258
|
```typescript
|
|
227
259
|
import { LLMClient } from '@blockrun/llm';
|
|
@@ -232,23 +264,28 @@ const client = new LLMClient();
|
|
|
232
264
|
const result = await client.smartChat('What is 2+2?');
|
|
233
265
|
console.log(result.response); // '4'
|
|
234
266
|
console.log(result.model); // 'moonshot/kimi-k2.5' (cheap, fast)
|
|
235
|
-
console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved
|
|
267
|
+
console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 88%'
|
|
236
268
|
|
|
237
269
|
// Complex reasoning task -> routes to reasoning model
|
|
238
270
|
const complex = await client.smartChat('Prove the Riemann hypothesis step by step');
|
|
239
271
|
console.log(complex.model); // 'xai/grok-4-1-fast-reasoning'
|
|
240
272
|
|
|
273
|
+
// Inspect how the request was classified and ranked (Router v3.4 portfolio).
|
|
274
|
+
console.log(complex.routing.method); // 'portfolio'
|
|
275
|
+
console.log(complex.routing.taskType); // 'reasoning'
|
|
276
|
+
console.log(complex.routing.candidates); // ranked, capability-eligible models
|
|
277
|
+
|
|
241
278
|
// Inspect the fallback chain SmartChat will walk on transient errors.
|
|
242
279
|
console.log(complex.routing.fallbacks); // ['anthropic/claude-opus-4.7', ...]
|
|
243
280
|
```
|
|
244
281
|
|
|
245
282
|
### Automatic Fallback on Transient Errors
|
|
246
283
|
|
|
247
|
-
`smartChat()` populates a
|
|
248
|
-
`chatCompletion()` walk it automatically when the primary model
|
|
249
|
-
transient error — timeouts, network failures,
|
|
250
|
-
522/524). 4xx errors and `PaymentError`
|
|
251
|
-
auth issues surface fast.
|
|
284
|
+
`smartChat()` populates a fallback chain from the portfolio ranking and
|
|
285
|
+
`chat()` / `chatCompletion()` walk it automatically when the primary model
|
|
286
|
+
returns a transient error — timeouts, network failures, 429 rate limits, or
|
|
287
|
+
5xx responses (502/503/504/522/524). Other 4xx errors and `PaymentError`
|
|
288
|
+
propagate immediately so wallet / auth issues surface fast.
|
|
252
289
|
|
|
253
290
|
```typescript
|
|
254
291
|
// Manually pass a fallback chain to chat() / chatCompletion()
|
|
@@ -261,12 +298,12 @@ const reply = await client.chat('nvidia/deepseek-v4-flash', 'hello', {
|
|
|
261
298
|
|
|
262
299
|
### Routing Profiles
|
|
263
300
|
|
|
264
|
-
| Profile |
|
|
265
|
-
|
|
266
|
-
| `free` | NVIDIA free tier — smart-routes across <!-- br:models.free -->
|
|
267
|
-
| `eco` | Cheapest
|
|
268
|
-
| `auto` | Best balance of cost/quality (default) | General use |
|
|
269
|
-
| `premium` | Top-tier models (OpenAI, Anthropic) | Quality-critical tasks |
|
|
301
|
+
| Profile | Strategy | Savings vs Opus 5 | Best For |
|
|
302
|
+
|---------|----------|-------------------|----------|
|
|
303
|
+
| `free` | NVIDIA free tier — smart-routes across <!-- br:models.free -->6<!-- /br:models.free --> models (DeepSeek V4 Flash, Nemotron Nano Omni, Qwen3, Llama 4, Mistral, plus 2 hidden gpt-oss) | **100%** | Zero-cost testing, dev, prod |
|
|
304
|
+
| `eco` | Cheapest capable model per tier | **<!-- br:savings.ecoVsBaselinePct -->98<!-- /br:savings.ecoVsBaselinePct -->%** | Cost-sensitive production |
|
|
305
|
+
| `auto` | Best balance of cost/quality (default) | **<!-- br:savings.autoVsBaselinePct -->88<!-- /br:savings.autoVsBaselinePct -->%** | General use |
|
|
306
|
+
| `premium` | Top-tier models (OpenAI, Anthropic) | 0% | Quality-critical tasks |
|
|
270
307
|
|
|
271
308
|
```typescript
|
|
272
309
|
// Use premium models for complex tasks
|
|
@@ -279,23 +316,78 @@ console.log(result.model); // 'anthropic/claude-opus-4.7'
|
|
|
279
316
|
|
|
280
317
|
### How ClawRouter Works
|
|
281
318
|
|
|
282
|
-
ClawRouter
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
|
298
|
-
|
|
319
|
+
Since ClawRouter v0.12.242, Auto uses the deterministic **Router v3.4 portfolio
|
|
320
|
+
strategy**: it classifies the task shape locally across
|
|
321
|
+
<!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions --> dimensions
|
|
322
|
+
(token count, code presence, reasoning markers, technical/creative terms,
|
|
323
|
+
agentic patterns, …), enforces tool / vision / structured-output / context
|
|
324
|
+
constraints as **hard filters**, then ranks an ordered candidate portfolio.
|
|
325
|
+
The winner becomes `routing.model`; the rest surface as `routing.candidates`
|
|
326
|
+
and feed SmartChat's transient-error fallback chain. Routing stays 100% local
|
|
327
|
+
and deterministic — <1ms, no extra model call, no network hop.
|
|
328
|
+
|
|
329
|
+
Classification still maps to one of four tiers (`routing.tier`). Each
|
|
330
|
+
tier × profile has a designated primary (what the rules strategy —
|
|
331
|
+
`routing.method: 'rules'`, the rollback lever — routes to directly, and what
|
|
332
|
+
anchors the portfolio's candidate pool):
|
|
333
|
+
|
|
334
|
+
| Tier | Example Tasks | ECO | AUTO | PREMIUM |
|
|
335
|
+
|------|---------------|-----|------|---------|
|
|
336
|
+
| SIMPLE | "What is 2+2?", definitions | free/gpt-oss-120b † (**FREE**) | gemini-2.5-flash ($0.30/$2.50) | kimi-k2.7 † ($0.95/$4.00) |
|
|
337
|
+
| MEDIUM | Code snippets, explanations | gemini-3.1-flash-lite ($0.25/$1.50) | kimi-k2.7 ($0.95/$4.00) | gpt-5.3-codex ($1.75/$14.00) |
|
|
338
|
+
| COMPLEX | Architecture, long documents | gemini-3.1-flash-lite ($0.25/$1.50) | gemini-3.1-pro ($2/$12) | claude-fable-5 ($10/$50) |
|
|
339
|
+
| REASONING | Proofs, multi-step reasoning | grok-4-1-fast-reasoning † ($0.20/$0.50) | grok-4-1-fast-reasoning † ($0.20/$0.50) | claude-sonnet-4.6 ($3/$15) |
|
|
340
|
+
|
|
341
|
+
† Withheld from `/v1/models` — the router still calls it by direct ID, but you
|
|
342
|
+
will not find it on the public pricing page. The published savings claim is
|
|
343
|
+
priced on visible models only.
|
|
344
|
+
|
|
345
|
+
This table mirrors ClawRouter's tier configs at the version this SDK pins;
|
|
346
|
+
the [ClawRouter README](https://github.com/BlockRunAI/ClawRouter#how-it-works)
|
|
347
|
+
is the live source of truth as models and prices move.
|
|
348
|
+
|
|
349
|
+
### Routing Metadata Reference
|
|
350
|
+
|
|
351
|
+
Every `smartChat()` result carries the full decision on `result.routing`
|
|
352
|
+
(type `RoutingDecision`) — enough to log, audit, or replay why a model was
|
|
353
|
+
picked:
|
|
354
|
+
|
|
355
|
+
| Field | Description |
|
|
356
|
+
|-------|-------------|
|
|
357
|
+
| `model` | Selected model id (same as `result.model`) |
|
|
358
|
+
| `method` | `'portfolio'` (the Auto default), `'rules'` (rollback strategy), or `'llm'` |
|
|
359
|
+
| `tier` | Task tier: `'SIMPLE'`, `'MEDIUM'`, `'COMPLEX'`, or `'REASONING'` |
|
|
360
|
+
| `taskType` | Portfolio task classification: `'chat'`, `'extraction'`, `'code_edit'`, `'code_agent'`, `'tool_agent'`, `'debug'`, `'reasoning'`, `'reasoning_math'`, `'long_context'`, `'vision'`, … |
|
|
361
|
+
| `candidates` | Ordered, capability-eligible models ranked by the portfolio router; the first entry is `model` |
|
|
362
|
+
| `candidateScores` | Per-candidate score breakdown (`quality` / `cost` / `speed` / `reliability`), ordered with `candidates` |
|
|
363
|
+
| `fallbacks` | The chain `chat()` walks on transient errors (timeout / network / 429 / 5xx) — `candidates` minus the primary, with ClawRouter's proxy-namespace `free/*` ids mapped to their `nvidia/*` gateway ids (SDK-computed) |
|
|
364
|
+
| `savings` | 0–1 fraction saved vs the premium baseline |
|
|
365
|
+
| `costEstimate` / `baselineCost` | Estimated cost of the pick vs that baseline, in USD |
|
|
366
|
+
| `confidence` | Sigmoid-calibrated classifier confidence, 0–1 |
|
|
367
|
+
| `routerVersion` | `'v3-portfolio'` or `'v2-rules'` |
|
|
368
|
+
| `profile` | Routing profile applied: `'auto'`, `'eco'`, `'premium'`, or `'agentic'` |
|
|
369
|
+
| `reasoning` | Human-readable explanation of the decision |
|
|
370
|
+
| `tierConfigs` | The tier → primary/fallback map the decision was made against |
|
|
371
|
+
|
|
372
|
+
### TypeScript Types
|
|
373
|
+
|
|
374
|
+
`RoutingDecision`, `RoutingProfile`, `RoutingTier`, `RoutingTaskType`, and
|
|
375
|
+
`RoutingTierConfig` are exported from `@blockrun/llm`. They are derived from
|
|
376
|
+
[`@blockrun/router-core`](https://github.com/BlockRunAI/router-core) — the
|
|
377
|
+
routing engine ClawRouter bundles — pinned to the exact commit ClawRouter's
|
|
378
|
+
published build inlines, and shipped **inlined in this SDK's declaration
|
|
379
|
+
files**. You do not need to install `@blockrun/clawrouter` (or router-core,
|
|
380
|
+
which is not on npm) for your project to typecheck against these types; the
|
|
381
|
+
runtime package is only needed to actually call `smartChat()`.
|
|
382
|
+
|
|
383
|
+
### Going Deeper
|
|
384
|
+
|
|
385
|
+
- [ClawRouter](https://github.com/BlockRunAI/ClawRouter) — the router itself: OpenClaw plugin, standalone proxy for Cursor / continue.dev / any OpenAI-compatible client, Telegram integration
|
|
386
|
+
- [Routing profiles in depth](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/routing-profiles.md) — ECO / AUTO / PREMIUM details
|
|
387
|
+
- [How the routing engine works](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/smart-llm-router-14-dimension-classifier.md) — the classifier, dimension by dimension
|
|
388
|
+
- [Router benchmark](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/llm-router-benchmark-46-models-sub-1ms-routing.md) — sub-1ms routing across the catalog
|
|
389
|
+
- [ClawRouter vs OpenRouter](https://github.com/BlockRunAI/ClawRouter/blob/main/docs/clawrouter-vs-openrouter-llm-routing-comparison.md) — head-to-head comparison
|
|
390
|
+
- [`@blockrun/router-core`](https://github.com/BlockRunAI/router-core) — the deterministic routing engine both share
|
|
299
391
|
|
|
300
392
|
## Available Models
|
|
301
393
|
|
|
@@ -858,7 +950,7 @@ const response2 = await client.chat('anthropic/claude-sonnet-4', 'Write a haiku'
|
|
|
858
950
|
|
|
859
951
|
### Smart Routing (ClawRouter)
|
|
860
952
|
|
|
861
|
-
Save up to <!-- br:savings.autoVsBaselinePct -->
|
|
953
|
+
Save up to <!-- br:savings.autoVsBaselinePct -->88<!-- /br:savings.autoVsBaselinePct -->% on inference costs with intelligent model routing. ClawRouter's deterministic portfolio router (v3.4, default since ClawRouter v0.12.242) classifies each request across <!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions --> dimensions, applies hard capability filters, and ranks the cheapest capable models (<1ms, 100% local). Requires the optional peer dependency: `npm install @blockrun/clawrouter`.
|
|
862
954
|
|
|
863
955
|
```typescript
|
|
864
956
|
import { LLMClient } from '@blockrun/llm';
|
|
@@ -870,7 +962,7 @@ const result = await client.smartChat('What is 2+2?');
|
|
|
870
962
|
console.log(result.response); // '4'
|
|
871
963
|
console.log(result.model); // 'google/gemini-2.5-flash'
|
|
872
964
|
console.log(result.routing.tier); // 'SIMPLE'
|
|
873
|
-
console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved
|
|
965
|
+
console.log(`Saved ${(result.routing.savings * 100).toFixed(0)}%`); // 'Saved 88%'
|
|
874
966
|
|
|
875
967
|
// Routing profiles
|
|
876
968
|
const free = await client.smartChat('Hello!', { routingProfile: 'free' }); // Zero cost
|
|
@@ -883,7 +975,7 @@ const premium = await client.smartChat('Write a legal brief', { routingProfile:
|
|
|
883
975
|
|
|
884
976
|
| Profile | Description | Best For |
|
|
885
977
|
|---------|-------------|----------|
|
|
886
|
-
| `free` | NVIDIA free tier (<!-- br:models.free -->
|
|
978
|
+
| `free` | NVIDIA free tier (<!-- br:models.free -->6<!-- /br:models.free --> models, smart-routed) | Zero-cost testing, dev, prod |
|
|
887
979
|
| `eco` | Budget-optimized | Cost-sensitive workloads |
|
|
888
980
|
| `auto` | Intelligent routing (default) | General use |
|
|
889
981
|
| `premium` | Best quality models | Critical tasks |
|
|
@@ -1427,7 +1519,7 @@ The `AnthropicClient` wraps the official `@anthropic-ai/sdk` with a custom fetch
|
|
|
1427
1519
|
When you make an API call, the SDK automatically handles x402 payment. It signs a USDC transaction locally using your wallet private key (which never leaves your machine), and includes the payment proof in the request header. Settlement is non-custodial and instant on Base or Solana.
|
|
1428
1520
|
|
|
1429
1521
|
### What is smart routing / ClawRouter?
|
|
1430
|
-
ClawRouter is
|
|
1522
|
+
ClawRouter is the SDK's smart routing engine, shipped as the optional `@blockrun/clawrouter` peer dependency (`npm install @blockrun/clawrouter` — only `smartChat()` needs it). It analyzes your request across <!-- br:clawrouter.dimensions -->15<!-- /br:clawrouter.dimensions --> dimensions and automatically picks the cheapest model capable of handling it. Routing happens locally in under 1ms. It can save up to <!-- br:savings.autoVsBaselinePct -->88<!-- /br:savings.autoVsBaselinePct -->% on LLM costs compared to using premium models for every request.
|
|
1431
1523
|
|
|
1432
1524
|
### Does it support streaming?
|
|
1433
1525
|
Yes — as of v1.6.1. Use `client.chatCompletionStream()` for native streaming or `stream: true` in the OpenAI-compatible client. Payment is handled automatically: the SDK signs USDC payment before streaming begins, and caches payment requirements per model so subsequent calls skip the 402 round-trip (~200ms faster).
|
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
PortraitClient: () => PortraitClient,
|
|
49
49
|
PriceClient: () => PriceClient,
|
|
50
50
|
RPC_PRICE_USD: () => RPC_PRICE_USD,
|
|
51
|
+
RetiredEndpointError: () => RetiredEndpointError,
|
|
51
52
|
RpcClient: () => RpcClient,
|
|
52
53
|
SOLANA_NETWORK: () => SOLANA_NETWORK,
|
|
53
54
|
SOLANA_WALLET_FILE_PATH: () => SOLANA_WALLET_FILE,
|
|
@@ -121,6 +122,12 @@ var BlockrunError = class extends Error {
|
|
|
121
122
|
this.name = "BlockrunError";
|
|
122
123
|
}
|
|
123
124
|
};
|
|
125
|
+
var RetiredEndpointError = class extends BlockrunError {
|
|
126
|
+
constructor(message) {
|
|
127
|
+
super(message);
|
|
128
|
+
this.name = "RetiredEndpointError";
|
|
129
|
+
}
|
|
130
|
+
};
|
|
124
131
|
var PaymentError = class extends BlockrunError {
|
|
125
132
|
constructor(message) {
|
|
126
133
|
super(message);
|
|
@@ -140,6 +147,35 @@ var APIError = class extends BlockrunError {
|
|
|
140
147
|
|
|
141
148
|
// src/x402.ts
|
|
142
149
|
var import_accounts = require("viem/accounts");
|
|
150
|
+
|
|
151
|
+
// src/solana-deps.ts
|
|
152
|
+
var INSTALL_HINT = "npm install @solana/web3.js @solana/spl-token (or pnpm add / yarn add)";
|
|
153
|
+
function missing(pkg, what, cause) {
|
|
154
|
+
return new Error(
|
|
155
|
+
`@blockrun/llm: ${what} requires the optional peer dependency "${pkg}", which is not installed.
|
|
156
|
+
|
|
157
|
+
${INSTALL_HINT}
|
|
158
|
+
|
|
159
|
+
Solana packages are optional peers so that consumers who only use Base/EVM payments do not inherit them. If you only make Base payments, you should not be reaching this code path \u2014 check which chain you passed.
|
|
160
|
+
Original error: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
async function loadSolanaWeb3(what) {
|
|
164
|
+
try {
|
|
165
|
+
return await import("@solana/web3.js");
|
|
166
|
+
} catch (err) {
|
|
167
|
+
throw missing("@solana/web3.js", what, err);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function loadSplToken(what) {
|
|
171
|
+
try {
|
|
172
|
+
return await import("@solana/spl-token");
|
|
173
|
+
} catch (err) {
|
|
174
|
+
throw missing("@solana/spl-token", what, err);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/x402.ts
|
|
143
179
|
var BASE_CHAIN_ID = 8453;
|
|
144
180
|
var USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
145
181
|
var SOLANA_NETWORK = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
@@ -268,9 +304,17 @@ async function createPaymentPayload(privateKey, fromAddress, recipient, amount,
|
|
|
268
304
|
return btoa(JSON.stringify(paymentData));
|
|
269
305
|
}
|
|
270
306
|
async function createSolanaPaymentPayload(secretKey, fromAddress, recipient, amount, feePayer, options = {}) {
|
|
271
|
-
const {
|
|
272
|
-
|
|
273
|
-
|
|
307
|
+
const {
|
|
308
|
+
Connection,
|
|
309
|
+
PublicKey,
|
|
310
|
+
TransactionMessage,
|
|
311
|
+
VersionedTransaction,
|
|
312
|
+
ComputeBudgetProgram,
|
|
313
|
+
Keypair
|
|
314
|
+
} = await loadSolanaWeb3("createSolanaPaymentPayload()");
|
|
315
|
+
const { getAssociatedTokenAddress, createTransferCheckedInstruction } = await loadSplToken(
|
|
316
|
+
"createSolanaPaymentPayload()"
|
|
317
|
+
);
|
|
274
318
|
const rpcUrl = options.rpcUrl || "https://sol.blockrun.ai/api/v1/solana/rpc";
|
|
275
319
|
const connection = options.rpcHeaders ? new Connection(rpcUrl, { httpHeaders: options.rpcHeaders }) : new Connection(rpcUrl);
|
|
276
320
|
const keypair = Keypair.fromSecretKey(secretKey);
|
|
@@ -564,14 +608,14 @@ function getCostSummary() {
|
|
|
564
608
|
}
|
|
565
609
|
|
|
566
610
|
// src/version.ts
|
|
567
|
-
var SDK_VERSION = "3.
|
|
611
|
+
var SDK_VERSION = "3.11.0";
|
|
568
612
|
var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
|
|
569
613
|
|
|
570
614
|
// src/client.ts
|
|
571
615
|
function isTransientError(err) {
|
|
572
616
|
if (err instanceof PaymentError) return false;
|
|
573
617
|
if (err instanceof APIError) {
|
|
574
|
-
return [502, 503, 504, 522, 524].includes(err.statusCode);
|
|
618
|
+
return [429, 502, 503, 504, 522, 524].includes(err.statusCode);
|
|
575
619
|
}
|
|
576
620
|
if (err instanceof Error) {
|
|
577
621
|
if (err.name === "AbortError") return true;
|
|
@@ -698,8 +742,11 @@ var LLMClient = class _LLMClient {
|
|
|
698
742
|
/**
|
|
699
743
|
* Smart chat with automatic model routing.
|
|
700
744
|
*
|
|
701
|
-
* Uses ClawRouter's
|
|
702
|
-
*
|
|
745
|
+
* Uses ClawRouter's deterministic portfolio router (Router v3.4, the Auto
|
|
746
|
+
* default since v0.12.242): it classifies the task shape locally (<1ms, no
|
|
747
|
+
* extra model call), enforces capability constraints as hard filters, and
|
|
748
|
+
* ranks an ordered candidate portfolio — the cheapest model that can handle
|
|
749
|
+
* the request wins, and the rest become the transient-error fallback chain.
|
|
703
750
|
*
|
|
704
751
|
* @param prompt - User message
|
|
705
752
|
* @param options - Optional chat and routing parameters
|
|
@@ -709,7 +756,8 @@ var LLMClient = class _LLMClient {
|
|
|
709
756
|
* ```ts
|
|
710
757
|
* const result = await client.smartChat('What is 2+2?');
|
|
711
758
|
* console.log(result.response); // '4'
|
|
712
|
-
* console.log(result.model); // 'google/gemini-
|
|
759
|
+
* console.log(result.model); // 'google/gemini-3.5-flash'
|
|
760
|
+
* console.log(result.routing.method); // 'portfolio'
|
|
713
761
|
* console.log(result.routing.savings); // 0.78 (78% savings)
|
|
714
762
|
* ```
|
|
715
763
|
*
|
|
@@ -741,11 +789,15 @@ var LLMClient = class _LLMClient {
|
|
|
741
789
|
routingProfile: options?.routingProfile
|
|
742
790
|
});
|
|
743
791
|
const tierConfigs = decision.tierConfigs ?? DEFAULT_ROUTING_CONFIG.tiers;
|
|
744
|
-
const
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
792
|
+
const ranked = decision.candidates?.length ? decision.candidates : [decision.model, ...getFallbackChain(decision.tier, tierConfigs)];
|
|
793
|
+
const callable = [];
|
|
794
|
+
for (const id of ranked) {
|
|
795
|
+
const resolved = !id.startsWith("free/") ? id : modelPricing.has(`nvidia/${id.slice(5)}`) ? `nvidia/${id.slice(5)}` : null;
|
|
796
|
+
if (resolved && !callable.includes(resolved)) callable.push(resolved);
|
|
797
|
+
}
|
|
798
|
+
const primary = callable[0] ?? decision.model;
|
|
799
|
+
const fallbacks = callable.slice(1);
|
|
800
|
+
const response = await this.chat(primary, prompt, {
|
|
749
801
|
system: options?.system,
|
|
750
802
|
maxTokens: options?.maxTokens,
|
|
751
803
|
temperature: options?.temperature,
|
|
@@ -758,8 +810,8 @@ var LLMClient = class _LLMClient {
|
|
|
758
810
|
});
|
|
759
811
|
return {
|
|
760
812
|
response,
|
|
761
|
-
model:
|
|
762
|
-
routing: { ...decision, fallbacks }
|
|
813
|
+
model: primary,
|
|
814
|
+
routing: { ...decision, model: primary, fallbacks }
|
|
763
815
|
};
|
|
764
816
|
}
|
|
765
817
|
/**
|
|
@@ -1783,20 +1835,38 @@ var LLMClient = class _LLMClient {
|
|
|
1783
1835
|
}
|
|
1784
1836
|
// ── PM convenience helpers (Predexon v2) ─────────────────────────────────
|
|
1785
1837
|
// Thin wrappers over pm() / pmQuery() for the most common v2 endpoints.
|
|
1786
|
-
/**
|
|
1787
|
-
*
|
|
1788
|
-
|
|
1789
|
-
|
|
1838
|
+
/** RETIRED — `/v1/pm/markets` no longer exists.
|
|
1839
|
+
*
|
|
1840
|
+
* Predexon sunset market matching on 2026-07-20 and the whole canonical layer
|
|
1841
|
+
* went with it, so this path returns 410 upstream. Use
|
|
1842
|
+
* `pm("markets/search", { q })` for cross-venue lookups.
|
|
1843
|
+
*
|
|
1844
|
+
* Kept as a throwing stub rather than deleted so upgrading does not break
|
|
1845
|
+
* property access; it throws before any network I/O.
|
|
1846
|
+
*
|
|
1847
|
+
* @throws {RetiredEndpointError} always. */
|
|
1848
|
+
async pmMarkets(_params) {
|
|
1849
|
+
throw new RetiredEndpointError(
|
|
1850
|
+
'/v1/pm/markets was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
|
|
1851
|
+
);
|
|
1790
1852
|
}
|
|
1791
|
-
/**
|
|
1792
|
-
*
|
|
1793
|
-
|
|
1794
|
-
|
|
1853
|
+
/** RETIRED — `/v1/pm/markets/listings` no longer exists (410, sunset
|
|
1854
|
+
* 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
|
|
1855
|
+
*
|
|
1856
|
+
* @throws {RetiredEndpointError} always. */
|
|
1857
|
+
async pmListings(_params) {
|
|
1858
|
+
throw new RetiredEndpointError(
|
|
1859
|
+
'/v1/pm/markets/listings was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
|
|
1860
|
+
);
|
|
1795
1861
|
}
|
|
1796
|
-
/**
|
|
1797
|
-
*
|
|
1798
|
-
|
|
1799
|
-
|
|
1862
|
+
/** RETIRED — `/v1/pm/outcomes/{predexonId}` no longer exists (410, sunset
|
|
1863
|
+
* 2026-07-20 with market matching). Use `pm("markets/search", { q })`.
|
|
1864
|
+
*
|
|
1865
|
+
* @throws {RetiredEndpointError} always. */
|
|
1866
|
+
async pmOutcome(_predexonId) {
|
|
1867
|
+
throw new RetiredEndpointError(
|
|
1868
|
+
'/v1/pm/outcomes/{predexon_id} was sunset by Predexon on 2026-07-20 (upstream 410). Use pm("markets/search", { q }) for cross-venue lookups.'
|
|
1869
|
+
);
|
|
1800
1870
|
}
|
|
1801
1871
|
/** Polymarket markets with cursor-based keyset pagination (use pagination_key).
|
|
1802
1872
|
* Tier 1 ($0.001/call). */
|
|
@@ -1808,12 +1878,18 @@ var LLMClient = class _LLMClient {
|
|
|
1808
1878
|
async pmPolymarketEventsKeyset(params) {
|
|
1809
1879
|
return this.pm("polymarket/events/keyset", params);
|
|
1810
1880
|
}
|
|
1811
|
-
/** List available sports categories. Tier 1 ($0.001/call).
|
|
1881
|
+
/** List available sports categories. Tier 1 ($0.001/call).
|
|
1882
|
+
*
|
|
1883
|
+
* NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04.
|
|
1884
|
+
* The route still resolves, so this works again the moment Predexon restores
|
|
1885
|
+
* it, but do not build on it yet. */
|
|
1812
1886
|
async pmSportsCategories() {
|
|
1813
1887
|
return this.pm("sports/categories");
|
|
1814
1888
|
}
|
|
1815
1889
|
/** List sports markets grouped by game. Filter with league, sport_type,
|
|
1816
|
-
* status, venue. Tier 1 ($0.001/call).
|
|
1890
|
+
* status, venue. Tier 1 ($0.001/call).
|
|
1891
|
+
*
|
|
1892
|
+
* NOTE: upstream returns 500 for every `sports/*` path as of 2026-08-04. */
|
|
1817
1893
|
async pmSportsMarkets(params) {
|
|
1818
1894
|
return this.pm("sports/markets", params);
|
|
1819
1895
|
}
|
|
@@ -4894,7 +4970,7 @@ var os3 = __toESM(require("os"), 1);
|
|
|
4894
4970
|
var WALLET_DIR2 = path3.join(os3.homedir(), ".blockrun");
|
|
4895
4971
|
var SOLANA_WALLET_FILE = path3.join(WALLET_DIR2, ".solana-session");
|
|
4896
4972
|
async function createSolanaWallet() {
|
|
4897
|
-
const { Keypair } = await
|
|
4973
|
+
const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
|
|
4898
4974
|
const bs58 = await import("bs58");
|
|
4899
4975
|
const keypair = Keypair.generate();
|
|
4900
4976
|
return {
|
|
@@ -4951,7 +5027,7 @@ async function solanaKeyToBytes(privateKey) {
|
|
|
4951
5027
|
}
|
|
4952
5028
|
}
|
|
4953
5029
|
async function solanaPublicKey(privateKey) {
|
|
4954
|
-
const { Keypair } = await
|
|
5030
|
+
const { Keypair } = await loadSolanaWeb3("Solana wallet operations");
|
|
4955
5031
|
const bytes = await solanaKeyToBytes(privateKey);
|
|
4956
5032
|
return Keypair.fromSecretKey(bytes).publicKey.toBase58();
|
|
4957
5033
|
}
|
|
@@ -6245,6 +6321,7 @@ var AnthropicClient = class {
|
|
|
6245
6321
|
PortraitClient,
|
|
6246
6322
|
PriceClient,
|
|
6247
6323
|
RPC_PRICE_USD,
|
|
6324
|
+
RetiredEndpointError,
|
|
6248
6325
|
RpcClient,
|
|
6249
6326
|
SOLANA_NETWORK,
|
|
6250
6327
|
SOLANA_WALLET_FILE_PATH,
|