@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 +75 -15
- package/dist/index.cjs +60 -8
- package/dist/index.d.cts +66 -10
- package/dist/index.d.ts +66 -10
- package/dist/index.js +60 -8
- package/package.json +1 -1
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 -->
|
|
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
|
[](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 -->
|
|
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-
|
|
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.
|
|
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
|
-
###
|
|
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
|
-
//
|
|
809
|
-
//
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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 -->
|
|
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.
|
|
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
|
-
|
|
6962
|
-
|
|
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 =
|
|
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
|
|
6988
|
-
*
|
|
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`
|
|
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
|
-
* (
|
|
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
|
|
823
|
-
*
|
|
824
|
-
* in the prompt. Mutually exclusive with
|
|
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
|
-
/**
|
|
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
|
|
1873
|
-
*
|
|
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`
|
|
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
|
-
* (
|
|
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
|
|
823
|
-
*
|
|
824
|
-
* in the prompt. Mutually exclusive with
|
|
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
|
-
/**
|
|
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
|
|
1873
|
-
*
|
|
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`
|
|
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.
|
|
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
|
-
|
|
6841
|
-
|
|
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 =
|
|
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
|
|
6867
|
-
*
|
|
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`
|
|
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.
|
|
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",
|