@blockrun/llm 3.17.1 → 3.18.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 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 -->79<!-- /br:models.chatVisible --> models — every request goes to the cheapest model that can handle it,
7
+ The smart-routing SDK for <!-- br:models.chatVisible -->82<!-- /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 or Base. 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 -->79<!-- /br:models.chatVisible -->, one credential** |
59
+ | **Models** | GPT only | 200+ | 100+ (BYO keys) | **<!-- br:models.chatVisible -->82<!-- /br:models.chatVisible -->, one credential** |
60
60
  | **Free tier** | ✗ | Rate-limited | ✗ | **<!-- br:models.free -->6<!-- /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** |
@@ -210,7 +210,6 @@ longer NVIDIA-only**, so pin these by full model id rather than by an
210
210
  | `nvidia/nemotron-3.5-lightning` | 1M | Thinking-mode reasoning at 1M context |
211
211
  | `nvidia/nemotron-3-ultra-550b` | 1M | Largest free model — 550B |
212
212
  | `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning` | 256K | Multimodal reasoning — text + images |
213
- | `nvidia/nemotron-3-nano-30b` | 128K | Compact + fast, good for high-volume light tasks |
214
213
  | `nvidia/llama-3.2-11b-vision` | 128K | Vision-language — accepts images |
215
214
  | `cohere/north-mini-code` | 256K | Compact coding model, sub-second responses |
216
215
  | `poolside/laguna-xs-2.1` | 128K | Coding model |
@@ -303,7 +302,7 @@ step — see [How Payment Works](#phase-2--every-request-pays-itself-automatic-x
303
302
  ```typescript
304
303
  // Manually pass a fallback chain to chat() / chatCompletion()
305
304
  const reply = await client.chat('nvidia/nemotron-3.5-lightning', 'hello', {
306
- fallbackModels: ['nvidia/nemotron-3-nano-30b', 'cohere/north-mini-code'],
305
+ fallbackModels: ['nvidia/nemotron-3-ultra-550b', 'cohere/north-mini-code'],
307
306
  });
308
307
  // If nemotron-3.5-lightning times out, the SDK retries against the next model
309
308
  // and logs each hop to stderr: "[@blockrun/llm] <from> -> <to> (...)".
@@ -589,6 +588,18 @@ README is wrong the day after it lands. See **[blockrun.ai/models](https://block
589
588
  for live rates, or read them from the catalog at runtime — `client.listModels()`
590
589
  and `client.listImageModels()` return exactly what the gateway is charging.
591
590
 
591
+ ### OpenAI GPT-6 Family
592
+
593
+ The GPT-6 generation: Astra is the flagship for long-horizon agentic work and
594
+ computer use, Sol the cost-efficient tier for complex coding, Luna the fast
595
+ low-cost tier.
596
+
597
+ | Model | Context |
598
+ |---|---|
599
+ | `openai/gpt-6-astra` | 1.05M |
600
+ | `openai/gpt-6-sol` | 1.05M |
601
+ | `openai/gpt-6-luna` | 1.05M |
602
+
592
603
  ### OpenAI GPT-5.6 Family
593
604
 
594
605
  Three tiers on one 1.05M-context base — Sol (deepest reasoning), Terra
@@ -604,7 +615,7 @@ longer at the same token price.
604
615
  | `openai/gpt-5.6-luna` | 1.05M |
605
616
  | `openai/gpt-5.6-luna-pro` | 1.05M |
606
617
 
607
- ### OpenAI GPT-5.5 / 5.4 / 5.2 Families
618
+ ### OpenAI GPT-5.5 / 5.4 / 5.2 / 5.1 Families
608
619
 
609
620
  | Model | Context | Notes |
610
621
  |---|---|---|
@@ -617,6 +628,7 @@ longer at the same token price.
617
628
  | `openai/gpt-5.4-nano` | 1.05M | |
618
629
  | `openai/gpt-5.2` | 400K | |
619
630
  | `openai/gpt-5.2-pro` | 400K | |
631
+ | `openai/gpt-5.1` | 400K | Configurable reasoning effort |
620
632
  | `openai/gpt-5.3-codex` | 400K | Coding/agentic SKU |
621
633
  | `openai/gpt-5-mini` | 200K | |
622
634
 
@@ -643,11 +655,14 @@ longer at the same token price.
643
655
 
644
656
  | Model | Context | Notes |
645
657
  |---|---|---|
658
+ | `anthropic/claude-fable-5.1` | 1M | Most capable — successor to Fable 5 at the same tier and price |
646
659
  | `anthropic/claude-fable-5` | 1M | Mythos-class flagship above Opus — always-on thinking, 128K output |
660
+ | `anthropic/claude-opus-5.5` | 1M | Newest Opus — Opus-class reasoning at a lower price than Opus 5 |
647
661
  | `anthropic/claude-opus-5` | 1M | Flagship — the baseline the routing savings claim is measured against |
648
662
  | `anthropic/claude-opus-4.8` | 1M | Agentic coding + adaptive thinking, 128K output |
649
663
  | `anthropic/claude-opus-4.7` | 1M | |
650
664
  | `anthropic/claude-opus-4.5` | 200K | |
665
+ | `anthropic/claude-sonnet-5.5` | 1M | Newest Sonnet — everyday coding and agent work, 128K output |
651
666
  | `anthropic/claude-sonnet-5` | 1M | Best cost/quality balance for long-context agent turns |
652
667
  | `anthropic/claude-sonnet-4.6` | 1M | |
653
668
  | `anthropic/claude-sonnet-4.5` | 200K | |
@@ -658,6 +673,7 @@ longer at the same token price.
658
673
  | Model | Context |
659
674
  |---|---|
660
675
  | `google/gemini-3.1-pro` | 1M |
676
+ | `google/gemini-3.8-flash` | 1M |
661
677
  | `google/gemini-3.6-flash` | 1M |
662
678
  | `google/gemini-3.5-flash` | 1M |
663
679
  | `google/gemini-3-flash-preview` | 1M |
@@ -689,7 +705,9 @@ only ranks what `/v1/models` lists.
689
705
 
690
706
  | Model | Context | Notes |
691
707
  |---|---|---|
692
- | `xai/grok-4.5` | 500K | Flagship — reasoning + vision, native Live Search (`search: true`) |
708
+ | `xai/grok-4.7` | 500K | Flagship — reasoning + vision, selectable effort (low → xhigh), native Live Search (`search: true`) |
709
+ | `xai/grok-4.6` | 500K | Reasoning with selectable effort, native Live Search |
710
+ | `xai/grok-4.5` | 500K | Reasoning + vision, native Live Search |
693
711
  | `xai/grok-4.3` | 1M | Reasoning + vision, tuned for agentic workflows |
694
712
  | `xai/grok-build-0.1` | 256K | Fast agentic coding model |
695
713
 
@@ -711,11 +729,10 @@ only ranks what `/v1/models` lists.
711
729
  | `qwen/qwen3.8-flash` | 1M | |
712
730
  | `qwen/qwen3.7-flash` | 1M | Cheapest paid chat model in the catalog |
713
731
 
714
- ### Tencent, Xiaomi
732
+ ### Xiaomi
715
733
 
716
734
  | Model | Context |
717
735
  |---|---|
718
- | `tencent/hy3` | 256K |
719
736
  | `xiaomi/mimo-v2.5` | 1M |
720
737
  | `xiaomi/mimo-v2.5-pro` | 1M |
721
738
 
@@ -729,7 +746,6 @@ Input and output both $0 — no promo, no rate-limit gimmick. The free tier is
729
746
  |---|---|---|
730
747
  | `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning` | 256K | Multimodal reasoning — text + images |
731
748
  | `nvidia/nemotron-3.5-lightning` | 1M | Thinking-mode reasoning at 1M context |
732
- | `nvidia/nemotron-3-nano-30b` | 128K | Compact and fast, good for high-volume light tasks |
733
749
  | `nvidia/llama-3.2-11b-vision` | 128K | Vision-language — accepts images |
734
750
  | `nvidia/nemotron-3-ultra-550b` | 1M | Largest free model — 550B, 1M context |
735
751
  | `cohere/north-mini-code` | 256K | Compact coding model, sub-second responses |
@@ -740,11 +756,14 @@ Input and output both $0 — no promo, no rate-limit gimmick. The free tier is
740
756
  |---|---|
741
757
  | `openai/gpt-image-1` | Native GPT-4o image generation |
742
758
  | `openai/gpt-image-2` | Reasoning-driven — multilingual text rendering, character consistency |
759
+ | `openai/gpt-image-2.5-flare` | GPT Image 2.5 |
760
+ | `openai/gpt-image-2.5-sunburst` | GPT Image 2.5 |
743
761
  | `google/nano-banana` | Gemini 2.5 Flash image generation — fast and efficient |
744
762
  | `google/nano-banana-2` | Gemini 3.1 Flash — pro-level quality at Flash speed |
745
763
  | `google/nano-banana-pro` | Gemini 3 Pro — highest quality, up to 4K |
746
764
  | `xai/grok-imagine-image` | Fast, 300 RPM |
747
765
  | `xai/grok-imagine-image-pro` | Quality tier, 30 RPM |
766
+ | `xai/grok-imagine-image-2.0` | Grok Imagine 2.0 |
748
767
  | `bytedance/seedream-5-pro` | Flagship generation + editing, up to 4K-class, reference images |
749
768
  | `zai/cogview-4` | Up to 1440x1440 |
750
769
 
@@ -805,11 +824,40 @@ const r4 = await client.generate('the flower blooms in golden morning light', {
805
824
  lastFrameUrl: 'https://example.com/bloom.jpg',
806
825
  });
807
826
 
808
- // Omni / multi-reference (Seedance 2.0 only): up to 9 reference images
809
- // for character/style consistency. Cite them as "image 1", "image 2" in
810
- // the prompt. Mutually exclusive with imageUrl / lastFrameUrl /
811
- // realFaceAssetId.
812
- const r5 = await client.generate(
827
+ // Seedance output controls. Each is model-gated at the gateway: an
828
+ // unsupported one is a 400 before payment, never silently dropped.
829
+ const r5 = await client.generate('a paper boat drifting down a rain gutter', {
830
+ model: 'bytedance/seedance-2.5',
831
+ bitrateMode: 'high', // Seedance 2.x
832
+ outputFormat: 'mov', // Seedance 2.5 only
833
+ returnLastFrame: true,
834
+ });
835
+ console.log(r5.data[0].last_frame_url); // present when the upstream returns it
836
+ // cameraFixed: true is Seedance 1.5-pro only.
837
+ ```
838
+
839
+ #### Reference images, video and audio (account API key only)
840
+
841
+ Seedance reference media is served by `api.blockrun.ai`, so it needs an
842
+ account API key. The wallet gateways (blockrun.ai, sol.blockrun.ai) refuse
843
+ `referenceImageUrls` / `referenceVideos` / `referenceAudios` with a 400 before
844
+ any payment.
845
+
846
+ | Model | Reference images | Reference video / audio |
847
+ |---|---|---|
848
+ | `bytedance/seedance-2.0` / `-fast` / `-mini` | 1–9 | 1–3 clips of each; audio needs an image or video alongside |
849
+ | `bytedance/seedance-2.5` | 1–30 | — |
850
+
851
+ Reference mode is its own mode: it cannot be mixed with `imageUrl`,
852
+ `lastFrameUrl` or `realFaceAssetId`. Cite images as "image 1", "image 2" and
853
+ clips as "video 1" in the prompt. Reference clips add a per-clip surcharge;
854
+ reference audio must be ≤15.2s.
855
+
856
+ ```ts
857
+ const client = new VideoClient({ apiKey: process.env.BLOCKRUN_API_KEY });
858
+
859
+ // Omni / multi-reference: character/style consistency from images
860
+ const r6 = await client.generate(
813
861
  'the character from image 1 walks through the city from image 2',
814
862
  {
815
863
  model: 'bytedance/seedance-2.0',
@@ -819,6 +867,18 @@ const r5 = await client.generate(
819
867
  ],
820
868
  }
821
869
  );
870
+
871
+ // Reference-to-video: image 1 for the character, video 1 for the motion
872
+ const r7 = await client.generate(
873
+ 'use image 1 for the character and video 1 for the motion',
874
+ {
875
+ model: 'bytedance/seedance-2.0-fast',
876
+ durationSeconds: 5,
877
+ referenceImageUrls: ['https://example.com/character.png'],
878
+ referenceVideos: [{ url: 'https://example.com/motion.mp4' }],
879
+ inputType: 'reference', // optional: 400 if the fields say otherwise
880
+ }
881
+ );
822
882
  ```
823
883
 
824
884
  ### Text-to-Speech & Sound Effects
@@ -1774,7 +1834,7 @@ The `AnthropicClient` wraps the official `@anthropic-ai/sdk` with a custom fetch
1774
1834
  ## Frequently Asked Questions
1775
1835
 
1776
1836
  ### What is @blockrun/llm?
1777
- @blockrun/llm is a TypeScript SDK that cuts LLM costs by up to <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->% with built-in smart routing: every request is routed to the cheapest of <!-- br:models.chatVisible -->79<!-- /br:models.chatVisible --> models (OpenAI, Anthropic, Google, xAI, DeepSeek, Moonshot, and more) that can handle it, then paid per-request in USDC via the x402 protocol — with API key account billing or x402 wallet payments on Solana or Base.
1837
+ @blockrun/llm is a TypeScript SDK that cuts LLM costs by up to <!-- br:savings.autoVsBaselinePct -->84<!-- /br:savings.autoVsBaselinePct -->% with built-in smart routing: every request is routed to the cheapest of <!-- br:models.chatVisible -->82<!-- /br:models.chatVisible --> models (OpenAI, Anthropic, Google, xAI, DeepSeek, Moonshot, and more) that can handle it, then paid per-request in USDC via the x402 protocol — with API key account billing or x402 wallet payments on Solana or Base.
1778
1838
 
1779
1839
  ### How does payment work?
1780
1840
  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.
package/dist/index.cjs CHANGED
@@ -4660,7 +4660,7 @@ function getCostSummary() {
4660
4660
  }
4661
4661
 
4662
4662
  // src/version.ts
4663
- var SDK_VERSION = "3.17.1";
4663
+ var SDK_VERSION = "3.18.0";
4664
4664
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4665
4665
 
4666
4666
  // src/client.ts
@@ -6958,8 +6958,36 @@ var VideoClient = class {
6958
6958
  "referenceImageUrls is mutually exclusive with imageUrl, lastFrameUrl, and realFaceAssetId."
6959
6959
  );
6960
6960
  }
6961
- if (options.referenceImageUrls.length > 9) {
6962
- throw new Error("referenceImageUrls accepts at most 9 images.");
6961
+ const imageLimit = options.model?.replace(/^bytedance\//, "") === "seedance-2.5" ? 30 : 9;
6962
+ if (options.referenceImageUrls.length > imageLimit) {
6963
+ throw new Error(`referenceImageUrls accepts at most ${imageLimit} images.`);
6964
+ }
6965
+ }
6966
+ for (const [field, clips] of [
6967
+ ["referenceVideos", options?.referenceVideos],
6968
+ ["referenceAudios", options?.referenceAudios]
6969
+ ]) {
6970
+ if (clips === void 0) continue;
6971
+ if (clips.length < 1 || clips.length > 3) {
6972
+ throw new Error(`${field} accepts 1 to 3 clips.`);
6973
+ }
6974
+ for (const clip of clips) {
6975
+ if (typeof clip?.url !== "string" || !/^https?:\/\//i.test(clip.url)) {
6976
+ throw new Error(`${field} URLs must be http(s).`);
6977
+ }
6978
+ if (clip.role !== void 0 && clip.role !== "reference") {
6979
+ throw new Error(`${field} role must be "reference" (or omitted).`);
6980
+ }
6981
+ }
6982
+ }
6983
+ if (options?.referenceVideos?.length || options?.referenceAudios?.length) {
6984
+ if (options.imageUrl || options.lastFrameUrl || options.realFaceAssetId) {
6985
+ throw new Error(
6986
+ "referenceVideos / referenceAudios are mutually exclusive with imageUrl, lastFrameUrl, and realFaceAssetId; combine them with referenceImageUrls instead."
6987
+ );
6988
+ }
6989
+ if (options.referenceAudios?.length && !options.referenceImageUrls?.length && !options.referenceVideos?.length) {
6990
+ throw new Error("referenceAudios requires referenceImageUrls or referenceVideos.");
6963
6991
  }
6964
6992
  }
6965
6993
  const body = {
@@ -6976,7 +7004,14 @@ var VideoClient = class {
6976
7004
  if (options?.generateAudio !== void 0) body.generate_audio = options.generateAudio;
6977
7005
  if (options?.seed !== void 0) body.seed = options.seed;
6978
7006
  if (options?.watermark !== void 0) body.watermark = options.watermark;
6979
- if (options?.returnLastFrame) body.return_last_frame = true;
7007
+ if (options?.returnLastFrame !== void 0) body.return_last_frame = options.returnLastFrame;
7008
+ if (options?.referenceVideos !== void 0) body.reference_videos = options.referenceVideos;
7009
+ if (options?.referenceAudios !== void 0) body.reference_audios = options.referenceAudios;
7010
+ if (options?.bitrateMode !== void 0) body.bitrate_mode = options.bitrateMode;
7011
+ if (options?.outputFormat !== void 0) body.output_format = options.outputFormat;
7012
+ if (options?.cameraFixed !== void 0) body.camera_fixed = options.cameraFixed;
7013
+ if (options?.safetyIdentifier !== void 0) body.safety_identifier = options.safetyIdentifier;
7014
+ if (options?.inputType !== void 0) body.input_type = options.inputType;
6980
7015
  const budgetMs = options?.budgetMs ?? DEFAULT_GENERATE_BUDGET_MS;
6981
7016
  return this.submitAndPoll(body, budgetMs);
6982
7017
  }
@@ -6984,8 +7019,11 @@ var VideoClient = class {
6984
7019
  * Generate a video from a standard Seedance `content[]` body.
6985
7020
  *
6986
7021
  * Targets the gateway's `POST /v1/videos` endpoint, which accepts the
6987
- * mainstream multimodal `content` array (text + a single reference image)
6988
- * used by other Seedance APIs — so callers already holding a
7022
+ * mainstream multimodal `content` array used by other Seedance APIs. Items
7023
+ * may carry a `role` — `first_frame`, `last_frame`, `reference_image`,
7024
+ * `reference_video`, `reference_audio` — which the gateway maps to the same
7025
+ * validated fields as {@link generate}; a role-less single image keeps its
7026
+ * first-frame meaning — so callers already holding a
6989
7027
  * `content[]`-shaped request can submit it unchanged. The gateway validates
6990
7028
  * unsupported inputs *before* charging, then delegates to the same x402
6991
7029
  * submit+poll pipeline as {@link generate}.
@@ -6999,7 +7037,8 @@ var VideoClient = class {
6999
7037
  * `{ type: "image_url", image_url: { url: "https://..." } }`.
7000
7038
  * @param options - `model`, `budgetMs`, plus the same camelCase render options
7001
7039
  * as {@link generate} (`durationSeconds`, `aspectRatio`, `resolution`,
7002
- * `generateAudio`, `seed`, `watermark`, `returnLastFrame`). These are mapped
7040
+ * `generateAudio`, `seed`, `watermark`, `returnLastFrame`, `bitrateMode`,
7041
+ * `outputFormat`, `cameraFixed`, `safetyIdentifier`, `inputType`). These are mapped
7003
7042
  * to the gateway's snake_case fields for you. Any other keys you pass are
7004
7043
  * forwarded verbatim (use snake_case for those, since the gateway reads
7005
7044
  * snake_case only).
@@ -7018,6 +7057,11 @@ var VideoClient = class {
7018
7057
  seed,
7019
7058
  watermark,
7020
7059
  returnLastFrame,
7060
+ bitrateMode,
7061
+ outputFormat,
7062
+ cameraFixed,
7063
+ safetyIdentifier,
7064
+ inputType,
7021
7065
  ...extra
7022
7066
  } = options ?? {};
7023
7067
  const body = { ...extra, content };
@@ -7029,6 +7073,11 @@ var VideoClient = class {
7029
7073
  if (seed !== void 0) body.seed = seed;
7030
7074
  if (watermark !== void 0) body.watermark = watermark;
7031
7075
  if (returnLastFrame !== void 0) body.return_last_frame = returnLastFrame;
7076
+ if (bitrateMode !== void 0) body.bitrate_mode = bitrateMode;
7077
+ if (outputFormat !== void 0) body.output_format = outputFormat;
7078
+ if (cameraFixed !== void 0) body.camera_fixed = cameraFixed;
7079
+ if (safetyIdentifier !== void 0) body.safety_identifier = safetyIdentifier;
7080
+ if (inputType !== void 0) body.input_type = inputType;
7032
7081
  return this.submitAndPoll(body, budgetMs ?? DEFAULT_GENERATE_BUDGET_MS, "/v1/videos");
7033
7082
  }
7034
7083
  // --------------------------------------------------------------------
@@ -10218,7 +10267,7 @@ var SolanaLLMClient = class {
10218
10267
  * @throws PaymentError when the 402 carries no usable Solana requirements.
10219
10268
  */
10220
10269
  /**
10221
- * Follow a 202 `{ id, poll_url }` to completion, on Solana.
10270
+ * Follow a 202 `{ id, poll_url }` to completion, on Solana **image** routes.
10222
10271
  *
10223
10272
  * Two things differ from Base and both come from the same constraint — a
10224
10273
  * Solana payment is a transaction pinned to a recent blockhash, valid for
@@ -10229,6 +10278,9 @@ var SolanaLLMClient = class {
10229
10278
  * settles optimistically at submit, and this loop only fetches the result.
10230
10279
  * The cost is recorded by the caller at POST, never here — recording it on
10231
10280
  * completion would lose the charge whenever a paid job then fails.
10281
+ * Solana VIDEO is the exception: it settles on the completed poll and a
10282
+ * failed job is not charged. Do not route video through this loop as-is —
10283
+ * it would book spend for jobs that were never charged.
10232
10284
  * 2. **Every poll re-signs.** One authorization cannot be replayed across a
10233
10285
  * long render. The gateway binds the job to the payer address rather than
10234
10286
  * to the signature, so a fresh signature from the same wallet is accepted
package/dist/index.d.cts CHANGED
@@ -770,6 +770,10 @@ interface VideoClip {
770
770
  request_id?: string;
771
771
  /** True when the gateway mirrored the video to its GCS bucket */
772
772
  backed_up?: boolean;
773
+ /** Final frame image when returnLastFrame is requested and the provider returns it. */
774
+ last_frame_url?: string;
775
+ /** Whether the final frame was mirrored to BlockRun storage. */
776
+ last_frame_backed_up?: boolean;
773
777
  }
774
778
  interface VideoResponse {
775
779
  created: number;
@@ -813,18 +817,55 @@ interface VideoGenerateOptions {
813
817
  * First-and-last-frame interpolation: a second image that seeds the FINAL
814
818
  * frame so the model tweens from `imageUrl` → `lastFrameUrl`. Requires
815
819
  * `imageUrl` (the first frame) and a Seedance model
816
- * (bytedance/seedance-1.5-pro, seedance-2.0, or seedance-2.0-fast).
820
+ * (1.5-pro, 2.0 / Fast / Mini, or 2.5).
817
821
  * Priced identically to image-to-video. Mutually exclusive with
818
822
  * `realFaceAssetId`.
819
823
  */
820
824
  lastFrameUrl?: string;
821
825
  /**
822
- * Omni / multi-reference: up to 9 reference image URLs for character/style
823
- * consistency (**Seedance 2.0 only**). Cite them as "image 1", "image 2"
824
- * in the prompt. Mutually exclusive with `imageUrl` / `lastFrameUrl` /
825
- * `realFaceAssetId`.
826
+ * Omni / multi-reference: up to 9 (Seedance 2.0 / Fast / Mini) or 30
827
+ * (Seedance 2.5) reference image URLs for character/style consistency. Cite
828
+ * them as "image 1", "image 2" in the prompt. Mutually exclusive with
829
+ * `imageUrl` / `lastFrameUrl` / `realFaceAssetId`.
830
+ *
831
+ * **Account API key only.** Reference media is served by `api.blockrun.ai`;
832
+ * the wallet gateways (blockrun.ai, sol.blockrun.ai) refuse it with a 400
833
+ * before any payment.
826
834
  */
827
835
  referenceImageUrls?: string[];
836
+ /**
837
+ * Reference-to-video: 1–3 http(s) motion/style video clips (Seedance 2.0 /
838
+ * Fast / Mini). May be combined with `referenceImageUrls`; mutually exclusive
839
+ * with frame seeds. `role` is optional and, when set, must be `"reference"`.
840
+ * Adds a per-clip surcharge. **Account API key only** (see `referenceImageUrls`).
841
+ */
842
+ referenceVideos?: Array<{
843
+ url: string;
844
+ role?: "reference";
845
+ }>;
846
+ /**
847
+ * Reference audio: 1–3 http(s) clips, each ≤15.2s (Seedance 2.0 / Fast /
848
+ * Mini). Requires `referenceImageUrls` or `referenceVideos` alongside it.
849
+ * Adds a per-clip surcharge. **Account API key only** (see `referenceImageUrls`).
850
+ */
851
+ referenceAudios?: Array<{
852
+ url: string;
853
+ role?: "reference";
854
+ }>;
855
+ /** Output bitrate mode. Seedance 2.0 / Fast / Mini / 2.5 only — other models get a 400. */
856
+ bitrateMode?: "standard" | "high";
857
+ /** Output container. Seedance 2.5 only — other models get a 400. */
858
+ outputFormat?: "mp4" | "mov";
859
+ /** Lock the camera. Seedance 1.5-pro only — other models get a 400. */
860
+ cameraFixed?: boolean;
861
+ /** End-user identifier forwarded for upstream abuse monitoring. Seedance only. */
862
+ safetyIdentifier?: string;
863
+ /**
864
+ * Declare the intended mode. The gateway infers it from the media fields
865
+ * anyway; when this is set and disagrees, it answers 400 (with the inferred
866
+ * mode) before payment instead of rendering the wrong thing.
867
+ */
868
+ inputType?: "text" | "image" | "first_last_frame" | "reference";
828
869
  /** Duration to bill for (defaults to model's default duration) */
829
870
  durationSeconds?: number;
830
871
  /** Output aspect ratio. Token360 / Seedance only — silently ignored by xAI Grok. */
@@ -844,7 +885,10 @@ interface VideoGenerateOptions {
844
885
  seed?: number;
845
886
  /** Embed the upstream watermark on the output. Defaults to false at the gateway. */
846
887
  watermark?: boolean;
847
- /** Return the last frame as an image alongside the clip — useful for chaining. */
888
+ /**
889
+ * Return the last frame as an image alongside the clip — useful for chaining.
890
+ * Read it from `data[0].last_frame_url` (absent if the upstream omits it).
891
+ */
848
892
  returnLastFrame?: boolean;
849
893
  }
850
894
  interface SearchOptions {
@@ -1869,8 +1913,11 @@ declare class VideoClient {
1869
1913
  * Generate a video from a standard Seedance `content[]` body.
1870
1914
  *
1871
1915
  * Targets the gateway's `POST /v1/videos` endpoint, which accepts the
1872
- * mainstream multimodal `content` array (text + a single reference image)
1873
- * used by other Seedance APIs — so callers already holding a
1916
+ * mainstream multimodal `content` array used by other Seedance APIs. Items
1917
+ * may carry a `role` — `first_frame`, `last_frame`, `reference_image`,
1918
+ * `reference_video`, `reference_audio` — which the gateway maps to the same
1919
+ * validated fields as {@link generate}; a role-less single image keeps its
1920
+ * first-frame meaning — so callers already holding a
1874
1921
  * `content[]`-shaped request can submit it unchanged. The gateway validates
1875
1922
  * unsupported inputs *before* charging, then delegates to the same x402
1876
1923
  * submit+poll pipeline as {@link generate}.
@@ -1884,7 +1931,8 @@ declare class VideoClient {
1884
1931
  * `{ type: "image_url", image_url: { url: "https://..." } }`.
1885
1932
  * @param options - `model`, `budgetMs`, plus the same camelCase render options
1886
1933
  * as {@link generate} (`durationSeconds`, `aspectRatio`, `resolution`,
1887
- * `generateAudio`, `seed`, `watermark`, `returnLastFrame`). These are mapped
1934
+ * `generateAudio`, `seed`, `watermark`, `returnLastFrame`, `bitrateMode`,
1935
+ * `outputFormat`, `cameraFixed`, `safetyIdentifier`, `inputType`). These are mapped
1888
1936
  * to the gateway's snake_case fields for you. Any other keys you pass are
1889
1937
  * forwarded verbatim (use snake_case for those, since the gateway reads
1890
1938
  * snake_case only).
@@ -1899,6 +1947,11 @@ declare class VideoClient {
1899
1947
  seed?: number;
1900
1948
  watermark?: boolean;
1901
1949
  returnLastFrame?: boolean;
1950
+ bitrateMode?: "standard" | "high";
1951
+ outputFormat?: "mp4" | "mov";
1952
+ cameraFixed?: boolean;
1953
+ safetyIdentifier?: string;
1954
+ inputType?: "text" | "image" | "first_last_frame" | "reference";
1902
1955
  } & Record<string, unknown>): Promise<VideoResponse>;
1903
1956
  private submitAndPoll;
1904
1957
  /**
@@ -2919,7 +2972,7 @@ declare class SolanaLLMClient {
2919
2972
  * @throws PaymentError when the 402 carries no usable Solana requirements.
2920
2973
  */
2921
2974
  /**
2922
- * Follow a 202 `{ id, poll_url }` to completion, on Solana.
2975
+ * Follow a 202 `{ id, poll_url }` to completion, on Solana **image** routes.
2923
2976
  *
2924
2977
  * Two things differ from Base and both come from the same constraint — a
2925
2978
  * Solana payment is a transaction pinned to a recent blockhash, valid for
@@ -2930,6 +2983,9 @@ declare class SolanaLLMClient {
2930
2983
  * settles optimistically at submit, and this loop only fetches the result.
2931
2984
  * The cost is recorded by the caller at POST, never here — recording it on
2932
2985
  * completion would lose the charge whenever a paid job then fails.
2986
+ * Solana VIDEO is the exception: it settles on the completed poll and a
2987
+ * failed job is not charged. Do not route video through this loop as-is —
2988
+ * it would book spend for jobs that were never charged.
2933
2989
  * 2. **Every poll re-signs.** One authorization cannot be replayed across a
2934
2990
  * long render. The gateway binds the job to the payer address rather than
2935
2991
  * to the signature, so a fresh signature from the same wallet is accepted
package/dist/index.d.ts CHANGED
@@ -770,6 +770,10 @@ interface VideoClip {
770
770
  request_id?: string;
771
771
  /** True when the gateway mirrored the video to its GCS bucket */
772
772
  backed_up?: boolean;
773
+ /** Final frame image when returnLastFrame is requested and the provider returns it. */
774
+ last_frame_url?: string;
775
+ /** Whether the final frame was mirrored to BlockRun storage. */
776
+ last_frame_backed_up?: boolean;
773
777
  }
774
778
  interface VideoResponse {
775
779
  created: number;
@@ -813,18 +817,55 @@ interface VideoGenerateOptions {
813
817
  * First-and-last-frame interpolation: a second image that seeds the FINAL
814
818
  * frame so the model tweens from `imageUrl` → `lastFrameUrl`. Requires
815
819
  * `imageUrl` (the first frame) and a Seedance model
816
- * (bytedance/seedance-1.5-pro, seedance-2.0, or seedance-2.0-fast).
820
+ * (1.5-pro, 2.0 / Fast / Mini, or 2.5).
817
821
  * Priced identically to image-to-video. Mutually exclusive with
818
822
  * `realFaceAssetId`.
819
823
  */
820
824
  lastFrameUrl?: string;
821
825
  /**
822
- * Omni / multi-reference: up to 9 reference image URLs for character/style
823
- * consistency (**Seedance 2.0 only**). Cite them as "image 1", "image 2"
824
- * in the prompt. Mutually exclusive with `imageUrl` / `lastFrameUrl` /
825
- * `realFaceAssetId`.
826
+ * Omni / multi-reference: up to 9 (Seedance 2.0 / Fast / Mini) or 30
827
+ * (Seedance 2.5) reference image URLs for character/style consistency. Cite
828
+ * them as "image 1", "image 2" in the prompt. Mutually exclusive with
829
+ * `imageUrl` / `lastFrameUrl` / `realFaceAssetId`.
830
+ *
831
+ * **Account API key only.** Reference media is served by `api.blockrun.ai`;
832
+ * the wallet gateways (blockrun.ai, sol.blockrun.ai) refuse it with a 400
833
+ * before any payment.
826
834
  */
827
835
  referenceImageUrls?: string[];
836
+ /**
837
+ * Reference-to-video: 1–3 http(s) motion/style video clips (Seedance 2.0 /
838
+ * Fast / Mini). May be combined with `referenceImageUrls`; mutually exclusive
839
+ * with frame seeds. `role` is optional and, when set, must be `"reference"`.
840
+ * Adds a per-clip surcharge. **Account API key only** (see `referenceImageUrls`).
841
+ */
842
+ referenceVideos?: Array<{
843
+ url: string;
844
+ role?: "reference";
845
+ }>;
846
+ /**
847
+ * Reference audio: 1–3 http(s) clips, each ≤15.2s (Seedance 2.0 / Fast /
848
+ * Mini). Requires `referenceImageUrls` or `referenceVideos` alongside it.
849
+ * Adds a per-clip surcharge. **Account API key only** (see `referenceImageUrls`).
850
+ */
851
+ referenceAudios?: Array<{
852
+ url: string;
853
+ role?: "reference";
854
+ }>;
855
+ /** Output bitrate mode. Seedance 2.0 / Fast / Mini / 2.5 only — other models get a 400. */
856
+ bitrateMode?: "standard" | "high";
857
+ /** Output container. Seedance 2.5 only — other models get a 400. */
858
+ outputFormat?: "mp4" | "mov";
859
+ /** Lock the camera. Seedance 1.5-pro only — other models get a 400. */
860
+ cameraFixed?: boolean;
861
+ /** End-user identifier forwarded for upstream abuse monitoring. Seedance only. */
862
+ safetyIdentifier?: string;
863
+ /**
864
+ * Declare the intended mode. The gateway infers it from the media fields
865
+ * anyway; when this is set and disagrees, it answers 400 (with the inferred
866
+ * mode) before payment instead of rendering the wrong thing.
867
+ */
868
+ inputType?: "text" | "image" | "first_last_frame" | "reference";
828
869
  /** Duration to bill for (defaults to model's default duration) */
829
870
  durationSeconds?: number;
830
871
  /** Output aspect ratio. Token360 / Seedance only — silently ignored by xAI Grok. */
@@ -844,7 +885,10 @@ interface VideoGenerateOptions {
844
885
  seed?: number;
845
886
  /** Embed the upstream watermark on the output. Defaults to false at the gateway. */
846
887
  watermark?: boolean;
847
- /** Return the last frame as an image alongside the clip — useful for chaining. */
888
+ /**
889
+ * Return the last frame as an image alongside the clip — useful for chaining.
890
+ * Read it from `data[0].last_frame_url` (absent if the upstream omits it).
891
+ */
848
892
  returnLastFrame?: boolean;
849
893
  }
850
894
  interface SearchOptions {
@@ -1869,8 +1913,11 @@ declare class VideoClient {
1869
1913
  * Generate a video from a standard Seedance `content[]` body.
1870
1914
  *
1871
1915
  * Targets the gateway's `POST /v1/videos` endpoint, which accepts the
1872
- * mainstream multimodal `content` array (text + a single reference image)
1873
- * used by other Seedance APIs — so callers already holding a
1916
+ * mainstream multimodal `content` array used by other Seedance APIs. Items
1917
+ * may carry a `role` — `first_frame`, `last_frame`, `reference_image`,
1918
+ * `reference_video`, `reference_audio` — which the gateway maps to the same
1919
+ * validated fields as {@link generate}; a role-less single image keeps its
1920
+ * first-frame meaning — so callers already holding a
1874
1921
  * `content[]`-shaped request can submit it unchanged. The gateway validates
1875
1922
  * unsupported inputs *before* charging, then delegates to the same x402
1876
1923
  * submit+poll pipeline as {@link generate}.
@@ -1884,7 +1931,8 @@ declare class VideoClient {
1884
1931
  * `{ type: "image_url", image_url: { url: "https://..." } }`.
1885
1932
  * @param options - `model`, `budgetMs`, plus the same camelCase render options
1886
1933
  * as {@link generate} (`durationSeconds`, `aspectRatio`, `resolution`,
1887
- * `generateAudio`, `seed`, `watermark`, `returnLastFrame`). These are mapped
1934
+ * `generateAudio`, `seed`, `watermark`, `returnLastFrame`, `bitrateMode`,
1935
+ * `outputFormat`, `cameraFixed`, `safetyIdentifier`, `inputType`). These are mapped
1888
1936
  * to the gateway's snake_case fields for you. Any other keys you pass are
1889
1937
  * forwarded verbatim (use snake_case for those, since the gateway reads
1890
1938
  * snake_case only).
@@ -1899,6 +1947,11 @@ declare class VideoClient {
1899
1947
  seed?: number;
1900
1948
  watermark?: boolean;
1901
1949
  returnLastFrame?: boolean;
1950
+ bitrateMode?: "standard" | "high";
1951
+ outputFormat?: "mp4" | "mov";
1952
+ cameraFixed?: boolean;
1953
+ safetyIdentifier?: string;
1954
+ inputType?: "text" | "image" | "first_last_frame" | "reference";
1902
1955
  } & Record<string, unknown>): Promise<VideoResponse>;
1903
1956
  private submitAndPoll;
1904
1957
  /**
@@ -2919,7 +2972,7 @@ declare class SolanaLLMClient {
2919
2972
  * @throws PaymentError when the 402 carries no usable Solana requirements.
2920
2973
  */
2921
2974
  /**
2922
- * Follow a 202 `{ id, poll_url }` to completion, on Solana.
2975
+ * Follow a 202 `{ id, poll_url }` to completion, on Solana **image** routes.
2923
2976
  *
2924
2977
  * Two things differ from Base and both come from the same constraint — a
2925
2978
  * Solana payment is a transaction pinned to a recent blockhash, valid for
@@ -2930,6 +2983,9 @@ declare class SolanaLLMClient {
2930
2983
  * settles optimistically at submit, and this loop only fetches the result.
2931
2984
  * The cost is recorded by the caller at POST, never here — recording it on
2932
2985
  * completion would lose the charge whenever a paid job then fails.
2986
+ * Solana VIDEO is the exception: it settles on the completed poll and a
2987
+ * failed job is not charged. Do not route video through this loop as-is —
2988
+ * it would book spend for jobs that were never charged.
2933
2989
  * 2. **Every poll re-signs.** One authorization cannot be replayed across a
2934
2990
  * long render. The gateway binds the job to the payer address rather than
2935
2991
  * to the signature, so a fresh signature from the same wallet is accepted
package/dist/index.js CHANGED
@@ -4539,7 +4539,7 @@ function getCostSummary() {
4539
4539
  }
4540
4540
 
4541
4541
  // src/version.ts
4542
- var SDK_VERSION = "3.17.1";
4542
+ var SDK_VERSION = "3.18.0";
4543
4543
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4544
4544
 
4545
4545
  // src/client.ts
@@ -6837,8 +6837,36 @@ var VideoClient = class {
6837
6837
  "referenceImageUrls is mutually exclusive with imageUrl, lastFrameUrl, and realFaceAssetId."
6838
6838
  );
6839
6839
  }
6840
- if (options.referenceImageUrls.length > 9) {
6841
- throw new Error("referenceImageUrls accepts at most 9 images.");
6840
+ const imageLimit = options.model?.replace(/^bytedance\//, "") === "seedance-2.5" ? 30 : 9;
6841
+ if (options.referenceImageUrls.length > imageLimit) {
6842
+ throw new Error(`referenceImageUrls accepts at most ${imageLimit} images.`);
6843
+ }
6844
+ }
6845
+ for (const [field, clips] of [
6846
+ ["referenceVideos", options?.referenceVideos],
6847
+ ["referenceAudios", options?.referenceAudios]
6848
+ ]) {
6849
+ if (clips === void 0) continue;
6850
+ if (clips.length < 1 || clips.length > 3) {
6851
+ throw new Error(`${field} accepts 1 to 3 clips.`);
6852
+ }
6853
+ for (const clip of clips) {
6854
+ if (typeof clip?.url !== "string" || !/^https?:\/\//i.test(clip.url)) {
6855
+ throw new Error(`${field} URLs must be http(s).`);
6856
+ }
6857
+ if (clip.role !== void 0 && clip.role !== "reference") {
6858
+ throw new Error(`${field} role must be "reference" (or omitted).`);
6859
+ }
6860
+ }
6861
+ }
6862
+ if (options?.referenceVideos?.length || options?.referenceAudios?.length) {
6863
+ if (options.imageUrl || options.lastFrameUrl || options.realFaceAssetId) {
6864
+ throw new Error(
6865
+ "referenceVideos / referenceAudios are mutually exclusive with imageUrl, lastFrameUrl, and realFaceAssetId; combine them with referenceImageUrls instead."
6866
+ );
6867
+ }
6868
+ if (options.referenceAudios?.length && !options.referenceImageUrls?.length && !options.referenceVideos?.length) {
6869
+ throw new Error("referenceAudios requires referenceImageUrls or referenceVideos.");
6842
6870
  }
6843
6871
  }
6844
6872
  const body = {
@@ -6855,7 +6883,14 @@ var VideoClient = class {
6855
6883
  if (options?.generateAudio !== void 0) body.generate_audio = options.generateAudio;
6856
6884
  if (options?.seed !== void 0) body.seed = options.seed;
6857
6885
  if (options?.watermark !== void 0) body.watermark = options.watermark;
6858
- if (options?.returnLastFrame) body.return_last_frame = true;
6886
+ if (options?.returnLastFrame !== void 0) body.return_last_frame = options.returnLastFrame;
6887
+ if (options?.referenceVideos !== void 0) body.reference_videos = options.referenceVideos;
6888
+ if (options?.referenceAudios !== void 0) body.reference_audios = options.referenceAudios;
6889
+ if (options?.bitrateMode !== void 0) body.bitrate_mode = options.bitrateMode;
6890
+ if (options?.outputFormat !== void 0) body.output_format = options.outputFormat;
6891
+ if (options?.cameraFixed !== void 0) body.camera_fixed = options.cameraFixed;
6892
+ if (options?.safetyIdentifier !== void 0) body.safety_identifier = options.safetyIdentifier;
6893
+ if (options?.inputType !== void 0) body.input_type = options.inputType;
6859
6894
  const budgetMs = options?.budgetMs ?? DEFAULT_GENERATE_BUDGET_MS;
6860
6895
  return this.submitAndPoll(body, budgetMs);
6861
6896
  }
@@ -6863,8 +6898,11 @@ var VideoClient = class {
6863
6898
  * Generate a video from a standard Seedance `content[]` body.
6864
6899
  *
6865
6900
  * Targets the gateway's `POST /v1/videos` endpoint, which accepts the
6866
- * mainstream multimodal `content` array (text + a single reference image)
6867
- * used by other Seedance APIs — so callers already holding a
6901
+ * mainstream multimodal `content` array used by other Seedance APIs. Items
6902
+ * may carry a `role` — `first_frame`, `last_frame`, `reference_image`,
6903
+ * `reference_video`, `reference_audio` — which the gateway maps to the same
6904
+ * validated fields as {@link generate}; a role-less single image keeps its
6905
+ * first-frame meaning — so callers already holding a
6868
6906
  * `content[]`-shaped request can submit it unchanged. The gateway validates
6869
6907
  * unsupported inputs *before* charging, then delegates to the same x402
6870
6908
  * submit+poll pipeline as {@link generate}.
@@ -6878,7 +6916,8 @@ var VideoClient = class {
6878
6916
  * `{ type: "image_url", image_url: { url: "https://..." } }`.
6879
6917
  * @param options - `model`, `budgetMs`, plus the same camelCase render options
6880
6918
  * as {@link generate} (`durationSeconds`, `aspectRatio`, `resolution`,
6881
- * `generateAudio`, `seed`, `watermark`, `returnLastFrame`). These are mapped
6919
+ * `generateAudio`, `seed`, `watermark`, `returnLastFrame`, `bitrateMode`,
6920
+ * `outputFormat`, `cameraFixed`, `safetyIdentifier`, `inputType`). These are mapped
6882
6921
  * to the gateway's snake_case fields for you. Any other keys you pass are
6883
6922
  * forwarded verbatim (use snake_case for those, since the gateway reads
6884
6923
  * snake_case only).
@@ -6897,6 +6936,11 @@ var VideoClient = class {
6897
6936
  seed,
6898
6937
  watermark,
6899
6938
  returnLastFrame,
6939
+ bitrateMode,
6940
+ outputFormat,
6941
+ cameraFixed,
6942
+ safetyIdentifier,
6943
+ inputType,
6900
6944
  ...extra
6901
6945
  } = options ?? {};
6902
6946
  const body = { ...extra, content };
@@ -6908,6 +6952,11 @@ var VideoClient = class {
6908
6952
  if (seed !== void 0) body.seed = seed;
6909
6953
  if (watermark !== void 0) body.watermark = watermark;
6910
6954
  if (returnLastFrame !== void 0) body.return_last_frame = returnLastFrame;
6955
+ if (bitrateMode !== void 0) body.bitrate_mode = bitrateMode;
6956
+ if (outputFormat !== void 0) body.output_format = outputFormat;
6957
+ if (cameraFixed !== void 0) body.camera_fixed = cameraFixed;
6958
+ if (safetyIdentifier !== void 0) body.safety_identifier = safetyIdentifier;
6959
+ if (inputType !== void 0) body.input_type = inputType;
6911
6960
  return this.submitAndPoll(body, budgetMs ?? DEFAULT_GENERATE_BUDGET_MS, "/v1/videos");
6912
6961
  }
6913
6962
  // --------------------------------------------------------------------
@@ -10097,7 +10146,7 @@ var SolanaLLMClient = class {
10097
10146
  * @throws PaymentError when the 402 carries no usable Solana requirements.
10098
10147
  */
10099
10148
  /**
10100
- * Follow a 202 `{ id, poll_url }` to completion, on Solana.
10149
+ * Follow a 202 `{ id, poll_url }` to completion, on Solana **image** routes.
10101
10150
  *
10102
10151
  * Two things differ from Base and both come from the same constraint — a
10103
10152
  * Solana payment is a transaction pinned to a recent blockhash, valid for
@@ -10108,6 +10157,9 @@ var SolanaLLMClient = class {
10108
10157
  * settles optimistically at submit, and this loop only fetches the result.
10109
10158
  * The cost is recorded by the caller at POST, never here — recording it on
10110
10159
  * completion would lose the charge whenever a paid job then fails.
10160
+ * Solana VIDEO is the exception: it settles on the completed poll and a
10161
+ * failed job is not charged. Do not route video through this loop as-is —
10162
+ * it would book spend for jobs that were never charged.
10111
10163
  * 2. **Every poll re-signs.** One authorization cannot be replayed across a
10112
10164
  * long render. The gateway binds the job to the payer address rather than
10113
10165
  * to the signature, so a fresh signature from the same wallet is accepted
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/llm",
3
- "version": "3.17.1",
3
+ "version": "3.18.0",
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",