@ai-sdk/black-forest-labs 2.0.20 → 2.0.21
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/CHANGELOG.md +8 -0
- package/README.md +16 -2
- package/dist/index.d.ts +27 -4
- package/dist/index.js +745 -80
- package/dist/index.js.map +1 -1
- package/docs/12-black-forest-labs.mdx +250 -3
- package/package.json +2 -2
- package/src/black-forest-labs-api.ts +58 -0
- package/src/black-forest-labs-image-model.ts +4 -51
- package/src/black-forest-labs-provider.ts +29 -2
- package/src/black-forest-labs-video-model-options.ts +92 -0
- package/src/black-forest-labs-video-model.ts +778 -0
- package/src/black-forest-labs-video-settings.ts +22 -0
- package/src/index.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -12,12 +12,10 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
combineHeaders,
|
|
14
14
|
createBinaryResponseHandler,
|
|
15
|
-
createJsonErrorResponseHandler,
|
|
16
15
|
createJsonResponseHandler,
|
|
17
16
|
createStatusCodeErrorResponseHandler,
|
|
18
17
|
delay,
|
|
19
18
|
getFromApi,
|
|
20
|
-
isSameOrigin,
|
|
21
19
|
parseProviderOptions,
|
|
22
20
|
postJsonToApi,
|
|
23
21
|
resolve,
|
|
@@ -25,51 +23,93 @@ import {
|
|
|
25
23
|
WORKFLOW_SERIALIZE,
|
|
26
24
|
WORKFLOW_DESERIALIZE
|
|
27
25
|
} from "@ai-sdk/provider-utils";
|
|
28
|
-
import { z as
|
|
26
|
+
import { z as z3 } from "zod/v4";
|
|
27
|
+
|
|
28
|
+
// src/black-forest-labs-api.ts
|
|
29
|
+
import {
|
|
30
|
+
createJsonErrorResponseHandler,
|
|
31
|
+
isSameOrigin
|
|
32
|
+
} from "@ai-sdk/provider-utils";
|
|
33
|
+
import { z } from "zod/v4";
|
|
34
|
+
var bflErrorSchema = z.object({
|
|
35
|
+
message: z.string().optional(),
|
|
36
|
+
detail: z.any().optional()
|
|
37
|
+
});
|
|
38
|
+
function bflErrorToMessage(error) {
|
|
39
|
+
const parsed = bflErrorSchema.safeParse(error);
|
|
40
|
+
if (!parsed.success) return void 0;
|
|
41
|
+
const { message, detail } = parsed.data;
|
|
42
|
+
if (typeof detail === "string") return detail;
|
|
43
|
+
if (detail != null) {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.stringify(detail);
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return message;
|
|
50
|
+
}
|
|
51
|
+
var bflFailedResponseHandler = createJsonErrorResponseHandler({
|
|
52
|
+
errorSchema: bflErrorSchema,
|
|
53
|
+
errorToMessage: (error) => {
|
|
54
|
+
var _a;
|
|
55
|
+
return (_a = bflErrorToMessage(error)) != null ? _a : "Unknown Black Forest Labs error";
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
function isTrustedUrl(url, baseUrl) {
|
|
59
|
+
if (isSameOrigin(url, baseUrl)) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const { protocol, hostname } = new URL(url);
|
|
64
|
+
return protocol === "https:" && (hostname === "bfl.ai" || hostname.endsWith(".bfl.ai"));
|
|
65
|
+
} catch (e) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
29
69
|
|
|
30
70
|
// src/black-forest-labs-image-model-options.ts
|
|
31
71
|
import {
|
|
32
72
|
lazySchema,
|
|
33
73
|
zodSchema
|
|
34
74
|
} from "@ai-sdk/provider-utils";
|
|
35
|
-
import { z } from "zod/v4";
|
|
75
|
+
import { z as z2 } from "zod/v4";
|
|
36
76
|
var blackForestLabsImageModelOptionsSchema = lazySchema(
|
|
37
77
|
() => zodSchema(
|
|
38
|
-
|
|
39
|
-
imagePrompt:
|
|
40
|
-
imagePromptStrength:
|
|
78
|
+
z2.object({
|
|
79
|
+
imagePrompt: z2.string().optional(),
|
|
80
|
+
imagePromptStrength: z2.number().min(0).max(1).optional(),
|
|
41
81
|
/** @deprecated use prompt.images instead */
|
|
42
|
-
inputImage:
|
|
82
|
+
inputImage: z2.string().optional(),
|
|
43
83
|
/** @deprecated use prompt.images instead */
|
|
44
|
-
inputImage2:
|
|
84
|
+
inputImage2: z2.string().optional(),
|
|
45
85
|
/** @deprecated use prompt.images instead */
|
|
46
|
-
inputImage3:
|
|
86
|
+
inputImage3: z2.string().optional(),
|
|
47
87
|
/** @deprecated use prompt.images instead */
|
|
48
|
-
inputImage4:
|
|
88
|
+
inputImage4: z2.string().optional(),
|
|
49
89
|
/** @deprecated use prompt.images instead */
|
|
50
|
-
inputImage5:
|
|
90
|
+
inputImage5: z2.string().optional(),
|
|
51
91
|
/** @deprecated use prompt.images instead */
|
|
52
|
-
inputImage6:
|
|
92
|
+
inputImage6: z2.string().optional(),
|
|
53
93
|
/** @deprecated use prompt.images instead */
|
|
54
|
-
inputImage7:
|
|
94
|
+
inputImage7: z2.string().optional(),
|
|
55
95
|
/** @deprecated use prompt.images instead */
|
|
56
|
-
inputImage8:
|
|
96
|
+
inputImage8: z2.string().optional(),
|
|
57
97
|
/** @deprecated use prompt.images instead */
|
|
58
|
-
inputImage9:
|
|
98
|
+
inputImage9: z2.string().optional(),
|
|
59
99
|
/** @deprecated use prompt.images instead */
|
|
60
|
-
inputImage10:
|
|
61
|
-
steps:
|
|
62
|
-
guidance:
|
|
63
|
-
width:
|
|
64
|
-
height:
|
|
65
|
-
outputFormat:
|
|
66
|
-
promptUpsampling:
|
|
67
|
-
raw:
|
|
68
|
-
safetyTolerance:
|
|
69
|
-
webhookSecret:
|
|
70
|
-
webhookUrl:
|
|
71
|
-
pollIntervalMillis:
|
|
72
|
-
pollTimeoutMillis:
|
|
100
|
+
inputImage10: z2.string().optional(),
|
|
101
|
+
steps: z2.number().int().positive().optional(),
|
|
102
|
+
guidance: z2.number().min(0).optional(),
|
|
103
|
+
width: z2.number().int().min(256).max(1920).optional(),
|
|
104
|
+
height: z2.number().int().min(256).max(1920).optional(),
|
|
105
|
+
outputFormat: z2.enum(["jpeg", "png"]).optional(),
|
|
106
|
+
promptUpsampling: z2.boolean().optional(),
|
|
107
|
+
raw: z2.boolean().optional(),
|
|
108
|
+
safetyTolerance: z2.number().int().min(0).max(6).optional(),
|
|
109
|
+
webhookSecret: z2.string().optional(),
|
|
110
|
+
webhookUrl: z2.url().optional(),
|
|
111
|
+
pollIntervalMillis: z2.number().int().positive().optional(),
|
|
112
|
+
pollTimeoutMillis: z2.number().int().positive().optional()
|
|
73
113
|
})
|
|
74
114
|
)
|
|
75
115
|
);
|
|
@@ -329,17 +369,6 @@ var BlackForestLabsImageModel = class _BlackForestLabsImageModel {
|
|
|
329
369
|
throw new Error("Black Forest Labs generation timed out.");
|
|
330
370
|
}
|
|
331
371
|
};
|
|
332
|
-
function isTrustedUrl(url, baseUrl) {
|
|
333
|
-
if (isSameOrigin(url, baseUrl)) {
|
|
334
|
-
return true;
|
|
335
|
-
}
|
|
336
|
-
try {
|
|
337
|
-
const { protocol, hostname } = new URL(url);
|
|
338
|
-
return protocol === "https:" && (hostname === "bfl.ai" || hostname.endsWith(".bfl.ai"));
|
|
339
|
-
} catch (e) {
|
|
340
|
-
return false;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
372
|
function convertSizeToAspectRatio(size) {
|
|
344
373
|
const [wStr, hStr] = size.split("x");
|
|
345
374
|
const width = Number(wStr);
|
|
@@ -360,30 +389,30 @@ function gcd(a, b) {
|
|
|
360
389
|
}
|
|
361
390
|
return x;
|
|
362
391
|
}
|
|
363
|
-
var bflSubmitSchema =
|
|
364
|
-
id:
|
|
365
|
-
polling_url:
|
|
366
|
-
cost:
|
|
367
|
-
input_mp:
|
|
368
|
-
output_mp:
|
|
392
|
+
var bflSubmitSchema = z3.object({
|
|
393
|
+
id: z3.string(),
|
|
394
|
+
polling_url: z3.url(),
|
|
395
|
+
cost: z3.number().nullish(),
|
|
396
|
+
input_mp: z3.number().nullish(),
|
|
397
|
+
output_mp: z3.number().nullish()
|
|
369
398
|
});
|
|
370
|
-
var bflStatus =
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
399
|
+
var bflStatus = z3.union([
|
|
400
|
+
z3.literal("Pending"),
|
|
401
|
+
z3.literal("Ready"),
|
|
402
|
+
z3.literal("Error"),
|
|
403
|
+
z3.literal("Failed"),
|
|
404
|
+
z3.literal("Request Moderated")
|
|
376
405
|
]);
|
|
377
|
-
var bflPollSchema =
|
|
406
|
+
var bflPollSchema = z3.object({
|
|
378
407
|
status: bflStatus.optional(),
|
|
379
408
|
state: bflStatus.optional(),
|
|
380
|
-
details:
|
|
381
|
-
result:
|
|
382
|
-
sample:
|
|
383
|
-
seed:
|
|
384
|
-
start_time:
|
|
385
|
-
end_time:
|
|
386
|
-
duration:
|
|
409
|
+
details: z3.unknown().optional(),
|
|
410
|
+
result: z3.object({
|
|
411
|
+
sample: z3.url(),
|
|
412
|
+
seed: z3.number().optional(),
|
|
413
|
+
start_time: z3.number().optional(),
|
|
414
|
+
end_time: z3.number().optional(),
|
|
415
|
+
duration: z3.number().optional()
|
|
387
416
|
}).nullish()
|
|
388
417
|
}).refine((v) => v.status != null || v.state != null, {
|
|
389
418
|
message: "Missing status in Black Forest Labs poll response"
|
|
@@ -394,33 +423,659 @@ var bflPollSchema = z2.object({
|
|
|
394
423
|
result: v.result
|
|
395
424
|
};
|
|
396
425
|
});
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
426
|
+
|
|
427
|
+
// src/black-forest-labs-video-model.ts
|
|
428
|
+
import {
|
|
429
|
+
AISDKError,
|
|
430
|
+
InvalidArgumentError
|
|
431
|
+
} from "@ai-sdk/provider";
|
|
432
|
+
import {
|
|
433
|
+
combineHeaders as combineHeaders2,
|
|
434
|
+
createJsonResponseHandler as createJsonResponseHandler2,
|
|
435
|
+
delay as delay2,
|
|
436
|
+
getFromApi as getFromApi2,
|
|
437
|
+
getTopLevelMediaType,
|
|
438
|
+
parseProviderOptions as parseProviderOptions2,
|
|
439
|
+
postJsonToApi as postJsonToApi2,
|
|
440
|
+
resolve as resolve2,
|
|
441
|
+
serializeModelOptions as serializeModelOptions2,
|
|
442
|
+
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE2,
|
|
443
|
+
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE2
|
|
444
|
+
} from "@ai-sdk/provider-utils";
|
|
445
|
+
import { z as z5 } from "zod/v4";
|
|
446
|
+
|
|
447
|
+
// src/black-forest-labs-video-model-options.ts
|
|
448
|
+
import {
|
|
449
|
+
lazySchema as lazySchema2,
|
|
450
|
+
zodSchema as zodSchema2
|
|
451
|
+
} from "@ai-sdk/provider-utils";
|
|
452
|
+
import { z as z4 } from "zod/v4";
|
|
453
|
+
|
|
454
|
+
// src/black-forest-labs-video-settings.ts
|
|
455
|
+
var blackForestLabsVideoAspectRatios = [
|
|
456
|
+
"21:9",
|
|
457
|
+
"2:1",
|
|
458
|
+
"16:9",
|
|
459
|
+
"4:3",
|
|
460
|
+
"1:1",
|
|
461
|
+
"3:4",
|
|
462
|
+
"9:16",
|
|
463
|
+
"auto"
|
|
464
|
+
];
|
|
465
|
+
var blackForestLabsVideoResolutions = ["hd", "fhd"];
|
|
466
|
+
|
|
467
|
+
// src/black-forest-labs-video-model-options.ts
|
|
468
|
+
var blackForestLabsTimedVideoKeyframeSchema = z4.tuple([
|
|
469
|
+
z4.number().min(0).max(20),
|
|
470
|
+
z4.string()
|
|
471
|
+
]);
|
|
472
|
+
var blackForestLabsVideoKeyframesSchema = z4.union([
|
|
473
|
+
z4.array(z4.string()).min(1).max(10),
|
|
474
|
+
z4.array(blackForestLabsTimedVideoKeyframeSchema).min(1).max(10).refine(
|
|
475
|
+
(keyframes) => keyframes.every(
|
|
476
|
+
(keyframe, index) => index === 0 || keyframe[0] > keyframes[index - 1][0]
|
|
477
|
+
),
|
|
478
|
+
{ message: "Timed keyframes must be in chronological order." }
|
|
479
|
+
)
|
|
480
|
+
]);
|
|
481
|
+
var blackForestLabsVideoProviderOptions = z4.object({
|
|
482
|
+
/**
|
|
483
|
+
* Output resolution tier. Takes precedence over the top-level `resolution`,
|
|
484
|
+
* which is expressed as `{width}x{height}` and has to be mapped onto a tier.
|
|
485
|
+
*/
|
|
486
|
+
resolution: z4.enum(blackForestLabsVideoResolutions).optional(),
|
|
487
|
+
/**
|
|
488
|
+
* Aspect ratio of the generated video. Takes precedence over the top-level
|
|
489
|
+
* `aspectRatio`, and unlike it can be set to `auto`.
|
|
490
|
+
*/
|
|
491
|
+
aspectRatio: z4.enum(blackForestLabsVideoAspectRatios).optional(),
|
|
492
|
+
/**
|
|
493
|
+
* Keyframes for image-to-video generation, for the shapes the top-level
|
|
494
|
+
* `image` and `frameImages` options cannot express: more than two images, or
|
|
495
|
+
* images pinned to a specific second. Takes precedence over both.
|
|
496
|
+
*
|
|
497
|
+
* One image opens the clip, two open and close it, and with more the extras
|
|
498
|
+
* are spaced evenly in between. Three or more plain images require an
|
|
499
|
+
* explicit `duration`.
|
|
500
|
+
*/
|
|
501
|
+
keyframes: blackForestLabsVideoKeyframesSchema.optional(),
|
|
502
|
+
/**
|
|
503
|
+
* Moderation strictness from 0 (strictest) to 4. Defaults to 2. Sexual
|
|
504
|
+
* content is capped at 3 and hate content at 2 regardless of the request,
|
|
505
|
+
* and any request carrying conditioning media is capped at 2.
|
|
506
|
+
*/
|
|
507
|
+
safetyTolerance: z4.number().int().min(0).max(4).optional(),
|
|
508
|
+
/**
|
|
509
|
+
* Render a fast, lower-quality preview instead of the finished video.
|
|
510
|
+
* Defaults to `false`.
|
|
511
|
+
*/
|
|
512
|
+
draft: z4.boolean().optional(),
|
|
513
|
+
/**
|
|
514
|
+
* Encrypted draft-cache bundle from a prior `draft` generation, which
|
|
515
|
+
* switches the request to draft-enhance mode: the bundle is replayed at full
|
|
516
|
+
* quality.
|
|
517
|
+
*
|
|
518
|
+
* Either the base64-encoded `.bin` downloaded from the draft's `draftCache`
|
|
519
|
+
* URL, or that URL itself while it is still in its expiry window.
|
|
520
|
+
*/
|
|
521
|
+
draftCache: z4.string().optional(),
|
|
522
|
+
/**
|
|
523
|
+
* Model version to pin. Only `latest` is available today.
|
|
524
|
+
*/
|
|
525
|
+
version: z4.literal("latest").optional()
|
|
400
526
|
});
|
|
401
|
-
var
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
527
|
+
var blackForestLabsVideoModelOptionsSchema = lazySchema2(
|
|
528
|
+
() => zodSchema2(blackForestLabsVideoProviderOptions)
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
// src/black-forest-labs-video-model.ts
|
|
532
|
+
var DEFAULT_POLL_INTERVAL_MILLIS2 = 2e3;
|
|
533
|
+
var DEFAULT_POLL_TIMEOUT_MILLIS2 = 6e5;
|
|
534
|
+
var MIN_DURATION_SECONDS = 5;
|
|
535
|
+
var MAX_DURATION_SECONDS = 20;
|
|
536
|
+
var UNTIMED_KEYFRAMES_NEEDING_DURATION = 3;
|
|
537
|
+
var allowedAspectRatios = new Set(blackForestLabsVideoAspectRatios);
|
|
538
|
+
var allowedResolutions = new Set(blackForestLabsVideoResolutions);
|
|
539
|
+
var TERMINAL_FAILURE_STATUSES = /* @__PURE__ */ new Set([
|
|
540
|
+
"Error",
|
|
541
|
+
"Failed",
|
|
542
|
+
"Request Moderated",
|
|
543
|
+
"Content Moderated",
|
|
544
|
+
"Task not found"
|
|
545
|
+
]);
|
|
546
|
+
function resolveTopLevelResolution(resolution) {
|
|
547
|
+
const named = resolution.toLowerCase();
|
|
548
|
+
if (allowedResolutions.has(named)) {
|
|
549
|
+
return { tier: named, derived: false };
|
|
406
550
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
551
|
+
const match = resolution.match(/^(\d+)x(\d+)$/);
|
|
552
|
+
if (match == null) {
|
|
553
|
+
return void 0;
|
|
554
|
+
}
|
|
555
|
+
const shorterSide = Math.min(Number(match[1]), Number(match[2]));
|
|
556
|
+
return {
|
|
557
|
+
tier: shorterSide <= 720 ? "hd" : "fhd",
|
|
558
|
+
derived: shorterSide !== 720 && shorterSide !== 1080
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
function nonImageFrameMediaType(file) {
|
|
562
|
+
if (file.mediaType == null) {
|
|
563
|
+
return void 0;
|
|
564
|
+
}
|
|
565
|
+
const topLevelMediaType = getTopLevelMediaType(file.mediaType);
|
|
566
|
+
return topLevelMediaType === "image" ? void 0 : topLevelMediaType;
|
|
567
|
+
}
|
|
568
|
+
function getDraftEnhanceArgs(options, bflOptions) {
|
|
569
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
570
|
+
const warnings = [];
|
|
571
|
+
const pinnedByBundle = [
|
|
572
|
+
["prompt", ((_b = (_a = options.prompt) == null ? void 0 : _a.trim().length) != null ? _b : 0) > 0],
|
|
573
|
+
[
|
|
574
|
+
"aspectRatio",
|
|
575
|
+
options.aspectRatio != null || bflOptions.aspectRatio != null
|
|
576
|
+
],
|
|
577
|
+
["resolution", options.resolution != null || bflOptions.resolution != null],
|
|
578
|
+
["duration", options.duration != null],
|
|
579
|
+
["fps", options.fps != null],
|
|
580
|
+
["seed", options.seed != null],
|
|
581
|
+
["generateAudio", options.generateAudio != null],
|
|
582
|
+
["image", options.image != null],
|
|
583
|
+
["frameImages", ((_d = (_c = options.frameImages) == null ? void 0 : _c.length) != null ? _d : 0) > 0],
|
|
584
|
+
["inputReferences", ((_f = (_e = options.inputReferences) == null ? void 0 : _e.length) != null ? _f : 0) > 0],
|
|
585
|
+
["keyframes", ((_h = (_g = bflOptions.keyframes) == null ? void 0 : _g.length) != null ? _h : 0) > 0],
|
|
586
|
+
["version", bflOptions.version != null]
|
|
587
|
+
];
|
|
588
|
+
for (const [feature, isSet] of pinnedByBundle) {
|
|
589
|
+
if (isSet) {
|
|
590
|
+
warnings.push({
|
|
591
|
+
type: "unsupported",
|
|
592
|
+
feature,
|
|
593
|
+
details: `FLUX 3 draft enhance replays the draft bundle as it was generated, so "${feature}" was ignored. Set it on the original draft request instead.`
|
|
594
|
+
});
|
|
417
595
|
}
|
|
418
596
|
}
|
|
419
|
-
|
|
597
|
+
if (bflOptions.draft != null) {
|
|
598
|
+
warnings.push({
|
|
599
|
+
type: "unsupported",
|
|
600
|
+
feature: "draft",
|
|
601
|
+
details: "FLUX 3 draft enhance always renders at full quality. The draft option was ignored."
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
if (options.n != null && options.n > 1) {
|
|
605
|
+
warnings.push({
|
|
606
|
+
type: "unsupported",
|
|
607
|
+
feature: "n",
|
|
608
|
+
details: "FLUX 3 video generates a single video per call. Only 1 video will be generated."
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
return {
|
|
612
|
+
body: {
|
|
613
|
+
mode: "draft_enhance",
|
|
614
|
+
draft_cache: bflOptions.draftCache,
|
|
615
|
+
safety_tolerance: bflOptions.safetyTolerance
|
|
616
|
+
},
|
|
617
|
+
warnings
|
|
618
|
+
};
|
|
420
619
|
}
|
|
620
|
+
function describePollDetails(details) {
|
|
621
|
+
if (details == null) {
|
|
622
|
+
return void 0;
|
|
623
|
+
}
|
|
624
|
+
if (typeof details === "string") {
|
|
625
|
+
return details;
|
|
626
|
+
}
|
|
627
|
+
try {
|
|
628
|
+
return JSON.stringify(details);
|
|
629
|
+
} catch (e) {
|
|
630
|
+
return void 0;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
function toBlackForestLabsFile(file) {
|
|
634
|
+
if (file.type === "url") {
|
|
635
|
+
return file.url;
|
|
636
|
+
}
|
|
637
|
+
if (typeof file.data === "string") {
|
|
638
|
+
return file.data;
|
|
639
|
+
}
|
|
640
|
+
return Buffer.from(file.data).toString("base64");
|
|
641
|
+
}
|
|
642
|
+
var BlackForestLabsVideoModel = class _BlackForestLabsVideoModel {
|
|
643
|
+
constructor(modelId, config) {
|
|
644
|
+
this.modelId = modelId;
|
|
645
|
+
this.config = config;
|
|
646
|
+
this.specificationVersion = "v4";
|
|
647
|
+
this.maxVideosPerCall = 1;
|
|
648
|
+
}
|
|
649
|
+
get provider() {
|
|
650
|
+
return this.config.provider;
|
|
651
|
+
}
|
|
652
|
+
static [WORKFLOW_SERIALIZE2](model) {
|
|
653
|
+
return serializeModelOptions2({
|
|
654
|
+
modelId: model.modelId,
|
|
655
|
+
config: model.config
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
static [WORKFLOW_DESERIALIZE2](options) {
|
|
659
|
+
return new _BlackForestLabsVideoModel(options.modelId, options.config);
|
|
660
|
+
}
|
|
661
|
+
async getArgs(options) {
|
|
662
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
663
|
+
const warnings = [];
|
|
664
|
+
const bflOptions = await parseProviderOptions2({
|
|
665
|
+
provider: "blackForestLabs",
|
|
666
|
+
providerOptions: options.providerOptions,
|
|
667
|
+
schema: blackForestLabsVideoModelOptionsSchema
|
|
668
|
+
});
|
|
669
|
+
if ((bflOptions == null ? void 0 : bflOptions.draftCache) != null) {
|
|
670
|
+
return getDraftEnhanceArgs(options, bflOptions);
|
|
671
|
+
}
|
|
672
|
+
if (options.fps != null) {
|
|
673
|
+
warnings.push({
|
|
674
|
+
type: "unsupported",
|
|
675
|
+
feature: "fps",
|
|
676
|
+
details: "FLUX 3 video does not support a custom frame rate."
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
if (options.seed != null) {
|
|
680
|
+
warnings.push({
|
|
681
|
+
type: "unsupported",
|
|
682
|
+
feature: "seed",
|
|
683
|
+
details: "FLUX 3 video does not accept a seed."
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (options.n != null && options.n > 1) {
|
|
687
|
+
warnings.push({
|
|
688
|
+
type: "unsupported",
|
|
689
|
+
feature: "n",
|
|
690
|
+
details: "FLUX 3 video generates a single video per call. Only 1 video will be generated."
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
let resolution = bflOptions == null ? void 0 : bflOptions.resolution;
|
|
694
|
+
if (options.resolution != null) {
|
|
695
|
+
const resolved = resolveTopLevelResolution(options.resolution);
|
|
696
|
+
if (resolution != null) {
|
|
697
|
+
if (resolved == null) {
|
|
698
|
+
warnings.push({
|
|
699
|
+
type: "unsupported",
|
|
700
|
+
feature: "resolution",
|
|
701
|
+
details: `Unrecognized resolution "${options.resolution}". FLUX 3 video supports "hd" and "fhd", so providerOptions.blackForestLabs.resolution ("${resolution}") was used instead.`
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
} else if (resolved == null) {
|
|
705
|
+
warnings.push({
|
|
706
|
+
type: "unsupported",
|
|
707
|
+
feature: "resolution",
|
|
708
|
+
details: `Unrecognized resolution "${options.resolution}". FLUX 3 video supports "hd" and "fhd", or a {width}x{height} value to map onto one.`
|
|
709
|
+
});
|
|
710
|
+
} else {
|
|
711
|
+
resolution = resolved.tier;
|
|
712
|
+
if (resolved.derived) {
|
|
713
|
+
warnings.push({
|
|
714
|
+
type: "compatibility",
|
|
715
|
+
feature: "resolution",
|
|
716
|
+
details: `FLUX 3 video renders at "hd" or "fhd"; the requested resolution "${options.resolution}" was mapped to "${resolved.tier}".`
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
let aspectRatio = bflOptions == null ? void 0 : bflOptions.aspectRatio;
|
|
722
|
+
if (aspectRatio == null && options.aspectRatio != null) {
|
|
723
|
+
if (allowedAspectRatios.has(options.aspectRatio)) {
|
|
724
|
+
aspectRatio = options.aspectRatio;
|
|
725
|
+
} else {
|
|
726
|
+
warnings.push({
|
|
727
|
+
type: "unsupported",
|
|
728
|
+
feature: "aspectRatio",
|
|
729
|
+
details: `FLUX 3 video does not support the aspect ratio "${options.aspectRatio}". Using the provider default (auto).`
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
const firstFrameImage = (_b = (_a = options.frameImages) == null ? void 0 : _a.find(
|
|
734
|
+
(frame) => frame.frameType === "first_frame"
|
|
735
|
+
)) == null ? void 0 : _b.image;
|
|
736
|
+
let firstFrame = firstFrameImage != null ? firstFrameImage : options.image;
|
|
737
|
+
let lastFrame = (_d = (_c = options.frameImages) == null ? void 0 : _c.find(
|
|
738
|
+
(frame) => frame.frameType === "last_frame"
|
|
739
|
+
)) == null ? void 0 : _d.image;
|
|
740
|
+
const firstFrameMediaType = firstFrame != null ? nonImageFrameMediaType(firstFrame) : void 0;
|
|
741
|
+
if (firstFrame != null && firstFrameMediaType != null) {
|
|
742
|
+
warnings.push({
|
|
743
|
+
type: "unsupported",
|
|
744
|
+
feature: firstFrameImage != null ? "frameImages" : "image",
|
|
745
|
+
details: firstFrameMediaType === "video" ? "FLUX 3 video does not accept a video as a keyframe. Pass it as an inputReference to continue from it instead." : `FLUX 3 video only accepts an image as a keyframe; the "${firstFrame.mediaType}" file was ignored.`
|
|
746
|
+
});
|
|
747
|
+
firstFrame = void 0;
|
|
748
|
+
}
|
|
749
|
+
if (lastFrame != null) {
|
|
750
|
+
if (firstFrame == null) {
|
|
751
|
+
warnings.push({
|
|
752
|
+
type: "unsupported",
|
|
753
|
+
feature: "frameImages",
|
|
754
|
+
details: "FLUX 3 video requires a first_frame when a last_frame is provided. The last_frame was ignored."
|
|
755
|
+
});
|
|
756
|
+
lastFrame = void 0;
|
|
757
|
+
} else {
|
|
758
|
+
const lastFrameMediaType = nonImageFrameMediaType(lastFrame);
|
|
759
|
+
if (lastFrameMediaType != null) {
|
|
760
|
+
warnings.push({
|
|
761
|
+
type: "unsupported",
|
|
762
|
+
feature: "frameImages",
|
|
763
|
+
details: lastFrameMediaType === "video" ? "FLUX 3 video does not accept a video as a keyframe. The last_frame video was ignored." : `FLUX 3 video only accepts an image as a keyframe; the "${lastFrame.mediaType}" last_frame was ignored.`
|
|
764
|
+
});
|
|
765
|
+
lastFrame = void 0;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
let keyframes = (bflOptions == null ? void 0 : bflOptions.keyframes) != null && bflOptions.keyframes.length > 0 ? [...bflOptions.keyframes] : void 0;
|
|
770
|
+
if (keyframes != null) {
|
|
771
|
+
if (firstFrame != null || lastFrame != null) {
|
|
772
|
+
warnings.push({
|
|
773
|
+
type: "unsupported",
|
|
774
|
+
feature: options.frameImages != null ? "frameImages" : "image",
|
|
775
|
+
details: "FLUX 3 video takes a single keyframe list. providerOptions.blackForestLabs.keyframes was used and the top-level frame images were ignored."
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
} else if (firstFrame != null) {
|
|
779
|
+
keyframes = [toBlackForestLabsFile(firstFrame)];
|
|
780
|
+
if (lastFrame != null) {
|
|
781
|
+
keyframes.push(toBlackForestLabsFile(lastFrame));
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
let startVideo;
|
|
785
|
+
const referenceFiles = (_e = options.inputReferences) != null ? _e : [];
|
|
786
|
+
const referenceVideos = [];
|
|
787
|
+
for (const file of referenceFiles) {
|
|
788
|
+
const topLevelMediaType = file.mediaType != null ? getTopLevelMediaType(file.mediaType) : void 0;
|
|
789
|
+
if (topLevelMediaType === "video") {
|
|
790
|
+
referenceVideos.push(file);
|
|
791
|
+
} else if (topLevelMediaType == null) {
|
|
792
|
+
warnings.push({
|
|
793
|
+
type: "compatibility",
|
|
794
|
+
feature: "inputReferences",
|
|
795
|
+
details: 'FLUX 3 video only accepts a video reference, so the reference with no mediaType was treated as the video to continue from. Pass { url, mediaType: "video/mp4" } to be explicit.'
|
|
796
|
+
});
|
|
797
|
+
referenceVideos.push(file);
|
|
798
|
+
} else if (topLevelMediaType === "image") {
|
|
799
|
+
warnings.push({
|
|
800
|
+
type: "unsupported",
|
|
801
|
+
feature: "inputReferences",
|
|
802
|
+
details: "FLUX 3 video has no reference-image input. Pass images as `image`, `frameImages`, or providerOptions.blackForestLabs.keyframes instead. The reference was ignored."
|
|
803
|
+
});
|
|
804
|
+
} else {
|
|
805
|
+
warnings.push({
|
|
806
|
+
type: "unsupported",
|
|
807
|
+
feature: "inputReferences",
|
|
808
|
+
details: `FLUX 3 video only accepts a video reference; the "${file.mediaType}" reference was ignored.`
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
if (referenceVideos.length > 0) {
|
|
813
|
+
if (keyframes != null) {
|
|
814
|
+
warnings.push({
|
|
815
|
+
type: "unsupported",
|
|
816
|
+
feature: "inputReferences",
|
|
817
|
+
details: "FLUX 3 video cannot combine keyframes with a video to continue from. The video reference was ignored."
|
|
818
|
+
});
|
|
819
|
+
} else {
|
|
820
|
+
startVideo = toBlackForestLabsFile(referenceVideos[0]);
|
|
821
|
+
if (referenceVideos.length > 1) {
|
|
822
|
+
warnings.push({
|
|
823
|
+
type: "unsupported",
|
|
824
|
+
feature: "inputReferences",
|
|
825
|
+
details: "FLUX 3 video continues from a single video. Only the first video reference was used."
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
let duration = options.duration;
|
|
831
|
+
if (duration != null) {
|
|
832
|
+
if (!Number.isInteger(duration)) {
|
|
833
|
+
const rounded = Math.round(duration);
|
|
834
|
+
warnings.push({
|
|
835
|
+
type: "unsupported",
|
|
836
|
+
feature: "duration",
|
|
837
|
+
details: `FLUX 3 video requires a whole number of seconds. The requested duration of ${duration} was rounded to ${rounded}.`
|
|
838
|
+
});
|
|
839
|
+
duration = rounded;
|
|
840
|
+
}
|
|
841
|
+
if (duration > MAX_DURATION_SECONDS) {
|
|
842
|
+
warnings.push({
|
|
843
|
+
type: "unsupported",
|
|
844
|
+
feature: "duration",
|
|
845
|
+
details: `FLUX 3 video supports at most ${MAX_DURATION_SECONDS} seconds. The requested duration of ${options.duration} was clamped to ${MAX_DURATION_SECONDS}.`
|
|
846
|
+
});
|
|
847
|
+
duration = MAX_DURATION_SECONDS;
|
|
848
|
+
} else if (duration < MIN_DURATION_SECONDS) {
|
|
849
|
+
warnings.push({
|
|
850
|
+
type: "unsupported",
|
|
851
|
+
feature: "duration",
|
|
852
|
+
details: `FLUX 3 video requires at least ${MIN_DURATION_SECONDS} seconds. The requested duration of ${options.duration} was clamped to ${MIN_DURATION_SECONDS}.`
|
|
853
|
+
});
|
|
854
|
+
duration = MIN_DURATION_SECONDS;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
const untimedKeyframeCount = (_f = keyframes == null ? void 0 : keyframes.filter((keyframe) => typeof keyframe === "string").length) != null ? _f : 0;
|
|
858
|
+
if (duration == null && untimedKeyframeCount >= UNTIMED_KEYFRAMES_NEEDING_DURATION) {
|
|
859
|
+
throw new InvalidArgumentError({
|
|
860
|
+
argument: "duration",
|
|
861
|
+
message: `FLUX 3 video requires an explicit duration when ${UNTIMED_KEYFRAMES_NEEDING_DURATION} or more keyframes are sent without a timestamp.`
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
const mode = keyframes != null ? "i2v" : startVideo != null ? "v2v" : "t2v";
|
|
865
|
+
const body = {
|
|
866
|
+
mode,
|
|
867
|
+
prompt: (_g = options.prompt) != null ? _g : "",
|
|
868
|
+
aspect_ratio: aspectRatio,
|
|
869
|
+
duration,
|
|
870
|
+
resolution,
|
|
871
|
+
version: bflOptions == null ? void 0 : bflOptions.version,
|
|
872
|
+
generate_audio: options.generateAudio,
|
|
873
|
+
safety_tolerance: bflOptions == null ? void 0 : bflOptions.safetyTolerance,
|
|
874
|
+
draft: bflOptions == null ? void 0 : bflOptions.draft,
|
|
875
|
+
...mode === "i2v" && { keyframes },
|
|
876
|
+
...mode === "v2v" && { start_video: startVideo }
|
|
877
|
+
};
|
|
878
|
+
return { body, warnings };
|
|
879
|
+
}
|
|
880
|
+
async doStart(options) {
|
|
881
|
+
var _a, _b, _c;
|
|
882
|
+
const { body, warnings } = await this.getArgs(options);
|
|
883
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
884
|
+
const combinedHeaders = combineHeaders2(
|
|
885
|
+
await resolve2(this.config.headers),
|
|
886
|
+
options.headers
|
|
887
|
+
);
|
|
888
|
+
const { value: submit, responseHeaders } = await postJsonToApi2({
|
|
889
|
+
url: `${this.config.baseURL}/${this.modelId}`,
|
|
890
|
+
headers: combinedHeaders,
|
|
891
|
+
body,
|
|
892
|
+
failedResponseHandler: bflFailedResponseHandler,
|
|
893
|
+
successfulResponseHandler: createJsonResponseHandler2(bflVideoSubmitSchema),
|
|
894
|
+
abortSignal: options.abortSignal,
|
|
895
|
+
fetch: this.config.fetch
|
|
896
|
+
});
|
|
897
|
+
return {
|
|
898
|
+
operation: {
|
|
899
|
+
requestId: submit.id,
|
|
900
|
+
pollingUrl: submit.polling_url,
|
|
901
|
+
...submit.cost != null && { cost: submit.cost },
|
|
902
|
+
...submit.input_mp != null && {
|
|
903
|
+
inputMegapixels: submit.input_mp
|
|
904
|
+
},
|
|
905
|
+
...submit.output_mp != null && {
|
|
906
|
+
outputMegapixels: submit.output_mp
|
|
907
|
+
}
|
|
908
|
+
},
|
|
909
|
+
warnings,
|
|
910
|
+
response: {
|
|
911
|
+
modelId: this.modelId,
|
|
912
|
+
timestamp: currentDate,
|
|
913
|
+
headers: responseHeaders
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
async doStatus(options) {
|
|
918
|
+
var _a, _b, _c;
|
|
919
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
920
|
+
const operation = options.operation;
|
|
921
|
+
const url = new URL(operation.pollingUrl);
|
|
922
|
+
if (!url.searchParams.has("id")) {
|
|
923
|
+
url.searchParams.set("id", operation.requestId);
|
|
924
|
+
}
|
|
925
|
+
const combinedHeaders = combineHeaders2(
|
|
926
|
+
await resolve2(this.config.headers),
|
|
927
|
+
options.headers
|
|
928
|
+
);
|
|
929
|
+
const { value, responseHeaders } = await getFromApi2({
|
|
930
|
+
url: url.toString(),
|
|
931
|
+
// The polling URL comes from the provider response; validate it.
|
|
932
|
+
validateUrl: true,
|
|
933
|
+
trustedOrigin: this.config.baseURL,
|
|
934
|
+
// Only send credentials when it stays on a trusted provider host.
|
|
935
|
+
headers: isTrustedUrl(url.toString(), this.config.baseURL) ? combinedHeaders : void 0,
|
|
936
|
+
failedResponseHandler: bflFailedResponseHandler,
|
|
937
|
+
successfulResponseHandler: createJsonResponseHandler2(bflVideoPollSchema),
|
|
938
|
+
abortSignal: options.abortSignal,
|
|
939
|
+
fetch: this.config.fetch
|
|
940
|
+
});
|
|
941
|
+
const response = {
|
|
942
|
+
modelId: this.modelId,
|
|
943
|
+
timestamp: currentDate,
|
|
944
|
+
headers: responseHeaders
|
|
945
|
+
};
|
|
946
|
+
const { status, result } = value;
|
|
947
|
+
if (status === "Ready") {
|
|
948
|
+
const parsed = bflVideoResultSchema.safeParse(result);
|
|
949
|
+
if (!parsed.success) {
|
|
950
|
+
throw new AISDKError({
|
|
951
|
+
name: "BLACK_FOREST_LABS_VIDEO_GENERATION_ERROR",
|
|
952
|
+
message: `Black Forest Labs reported the video as Ready but returned no result.sample URL. Request id: ${operation.requestId}`
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
return {
|
|
956
|
+
status: "completed",
|
|
957
|
+
videos: [
|
|
958
|
+
{
|
|
959
|
+
type: "url",
|
|
960
|
+
url: parsed.data.sample,
|
|
961
|
+
mediaType: "video/mp4"
|
|
962
|
+
}
|
|
963
|
+
],
|
|
964
|
+
warnings: [],
|
|
965
|
+
providerMetadata: {
|
|
966
|
+
blackForestLabs: {
|
|
967
|
+
videos: [
|
|
968
|
+
{
|
|
969
|
+
id: operation.requestId,
|
|
970
|
+
videoUrl: parsed.data.sample,
|
|
971
|
+
...parsed.data.seed != null && { seed: parsed.data.seed },
|
|
972
|
+
...parsed.data.start_time != null && {
|
|
973
|
+
start_time: parsed.data.start_time
|
|
974
|
+
},
|
|
975
|
+
...parsed.data.end_time != null && {
|
|
976
|
+
end_time: parsed.data.end_time
|
|
977
|
+
},
|
|
978
|
+
...parsed.data.duration != null && {
|
|
979
|
+
duration: parsed.data.duration
|
|
980
|
+
},
|
|
981
|
+
...parsed.data.draft_cache != null && {
|
|
982
|
+
draftCache: parsed.data.draft_cache
|
|
983
|
+
},
|
|
984
|
+
...operation.cost != null && { cost: operation.cost },
|
|
985
|
+
...operation.inputMegapixels != null && {
|
|
986
|
+
inputMegapixels: operation.inputMegapixels
|
|
987
|
+
},
|
|
988
|
+
...operation.outputMegapixels != null && {
|
|
989
|
+
outputMegapixels: operation.outputMegapixels
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
]
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
response
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
if (TERMINAL_FAILURE_STATUSES.has(status)) {
|
|
999
|
+
const detail = describePollDetails(value.details);
|
|
1000
|
+
return {
|
|
1001
|
+
status: "error",
|
|
1002
|
+
error: `Black Forest Labs video generation failed with status "${status}"${detail != null ? `: ${detail}` : ""}. Request id: ${operation.requestId}`,
|
|
1003
|
+
response
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
return { status: "pending", response };
|
|
1007
|
+
}
|
|
1008
|
+
async doGenerate(options) {
|
|
1009
|
+
var _a, _b;
|
|
1010
|
+
const startResult = await this.doStart(options);
|
|
1011
|
+
const operation = startResult.operation;
|
|
1012
|
+
const pollIntervalMillis = (_a = this.config.pollIntervalMillis) != null ? _a : DEFAULT_POLL_INTERVAL_MILLIS2;
|
|
1013
|
+
const pollTimeoutMillis = (_b = this.config.pollTimeoutMillis) != null ? _b : DEFAULT_POLL_TIMEOUT_MILLIS2;
|
|
1014
|
+
const startTime = Date.now();
|
|
1015
|
+
while (true) {
|
|
1016
|
+
await delay2(pollIntervalMillis, { abortSignal: options.abortSignal });
|
|
1017
|
+
if (Date.now() - startTime > pollTimeoutMillis) {
|
|
1018
|
+
throw new AISDKError({
|
|
1019
|
+
name: "BLACK_FOREST_LABS_VIDEO_GENERATION_TIMEOUT",
|
|
1020
|
+
message: `Black Forest Labs video generation timed out after ${pollTimeoutMillis}ms. Request id: ${operation.requestId}`
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
const statusResult = await this.doStatus({
|
|
1024
|
+
operation,
|
|
1025
|
+
headers: options.headers,
|
|
1026
|
+
abortSignal: options.abortSignal
|
|
1027
|
+
});
|
|
1028
|
+
if (statusResult.status === "pending") {
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (statusResult.status === "error") {
|
|
1032
|
+
throw new AISDKError({
|
|
1033
|
+
name: "BLACK_FOREST_LABS_VIDEO_GENERATION_FAILED",
|
|
1034
|
+
message: statusResult.error
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
return {
|
|
1038
|
+
videos: statusResult.videos,
|
|
1039
|
+
warnings: [...startResult.warnings, ...statusResult.warnings],
|
|
1040
|
+
providerMetadata: statusResult.providerMetadata,
|
|
1041
|
+
response: statusResult.response
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
var bflVideoSubmitSchema = z5.object({
|
|
1047
|
+
id: z5.string(),
|
|
1048
|
+
polling_url: z5.url(),
|
|
1049
|
+
cost: z5.number().nullish(),
|
|
1050
|
+
input_mp: z5.number().nullish(),
|
|
1051
|
+
output_mp: z5.number().nullish()
|
|
1052
|
+
});
|
|
1053
|
+
var bflVideoResultSchema = z5.object({
|
|
1054
|
+
sample: z5.url(),
|
|
1055
|
+
seed: z5.number().nullish(),
|
|
1056
|
+
start_time: z5.number().nullish(),
|
|
1057
|
+
end_time: z5.number().nullish(),
|
|
1058
|
+
duration: z5.number().nullish(),
|
|
1059
|
+
draft_cache: z5.string().nullish()
|
|
1060
|
+
});
|
|
1061
|
+
var bflVideoPollSchema = z5.object({
|
|
1062
|
+
status: z5.string().optional(),
|
|
1063
|
+
state: z5.string().optional(),
|
|
1064
|
+
details: z5.unknown().optional(),
|
|
1065
|
+
result: z5.unknown().optional()
|
|
1066
|
+
}).refine((v) => v.status != null || v.state != null, {
|
|
1067
|
+
message: "Missing status in Black Forest Labs poll response"
|
|
1068
|
+
}).transform((v) => {
|
|
1069
|
+
var _a;
|
|
1070
|
+
return {
|
|
1071
|
+
status: (_a = v.status) != null ? _a : v.state,
|
|
1072
|
+
details: v.details,
|
|
1073
|
+
result: v.result
|
|
1074
|
+
};
|
|
1075
|
+
});
|
|
421
1076
|
|
|
422
1077
|
// src/version.ts
|
|
423
|
-
var VERSION = true ? "2.0.
|
|
1078
|
+
var VERSION = true ? "2.0.21" : "0.0.0-test";
|
|
424
1079
|
|
|
425
1080
|
// src/black-forest-labs-provider.ts
|
|
426
1081
|
var defaultBaseURL = "https://api.bfl.ai/v1";
|
|
@@ -446,6 +1101,14 @@ function createBlackForestLabs(options = {}) {
|
|
|
446
1101
|
pollIntervalMillis: options.pollIntervalMillis,
|
|
447
1102
|
pollTimeoutMillis: options.pollTimeoutMillis
|
|
448
1103
|
});
|
|
1104
|
+
const createVideoModel = (modelId) => new BlackForestLabsVideoModel(modelId, {
|
|
1105
|
+
provider: "black-forest-labs.video",
|
|
1106
|
+
baseURL: baseURL != null ? baseURL : defaultBaseURL,
|
|
1107
|
+
headers: getHeaders,
|
|
1108
|
+
fetch: options.fetch,
|
|
1109
|
+
pollIntervalMillis: options.pollIntervalMillis,
|
|
1110
|
+
pollTimeoutMillis: options.pollTimeoutMillis
|
|
1111
|
+
});
|
|
449
1112
|
const embeddingModel = (modelId) => {
|
|
450
1113
|
throw new NoSuchModelError({
|
|
451
1114
|
modelId,
|
|
@@ -456,6 +1119,8 @@ function createBlackForestLabs(options = {}) {
|
|
|
456
1119
|
specificationVersion: "v4",
|
|
457
1120
|
imageModel: createImageModel,
|
|
458
1121
|
image: createImageModel,
|
|
1122
|
+
videoModel: createVideoModel,
|
|
1123
|
+
video: createVideoModel,
|
|
459
1124
|
languageModel: (modelId) => {
|
|
460
1125
|
throw new NoSuchModelError({
|
|
461
1126
|
modelId,
|