@ai-sdk/black-forest-labs 2.0.0-beta.5 → 2.0.0-beta.51

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.
@@ -0,0 +1,51 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ export const blackForestLabsImageModelOptionsSchema = lazySchema(() =>
9
+ zodSchema(
10
+ z.object({
11
+ imagePrompt: z.string().optional(),
12
+ imagePromptStrength: z.number().min(0).max(1).optional(),
13
+ /** @deprecated use prompt.images instead */
14
+ inputImage: z.string().optional(),
15
+ /** @deprecated use prompt.images instead */
16
+ inputImage2: z.string().optional(),
17
+ /** @deprecated use prompt.images instead */
18
+ inputImage3: z.string().optional(),
19
+ /** @deprecated use prompt.images instead */
20
+ inputImage4: z.string().optional(),
21
+ /** @deprecated use prompt.images instead */
22
+ inputImage5: z.string().optional(),
23
+ /** @deprecated use prompt.images instead */
24
+ inputImage6: z.string().optional(),
25
+ /** @deprecated use prompt.images instead */
26
+ inputImage7: z.string().optional(),
27
+ /** @deprecated use prompt.images instead */
28
+ inputImage8: z.string().optional(),
29
+ /** @deprecated use prompt.images instead */
30
+ inputImage9: z.string().optional(),
31
+ /** @deprecated use prompt.images instead */
32
+ inputImage10: z.string().optional(),
33
+ steps: z.number().int().positive().optional(),
34
+ guidance: z.number().min(0).optional(),
35
+ width: z.number().int().min(256).max(1920).optional(),
36
+ height: z.number().int().min(256).max(1920).optional(),
37
+ outputFormat: z.enum(['jpeg', 'png']).optional(),
38
+ promptUpsampling: z.boolean().optional(),
39
+ raw: z.boolean().optional(),
40
+ safetyTolerance: z.number().int().min(0).max(6).optional(),
41
+ webhookSecret: z.string().optional(),
42
+ webhookUrl: z.url().optional(),
43
+ pollIntervalMillis: z.number().int().positive().optional(),
44
+ pollTimeoutMillis: z.number().int().positive().optional(),
45
+ }),
46
+ ),
47
+ );
48
+
49
+ export type BlackForestLabsImageModelOptions = InferSchema<
50
+ typeof blackForestLabsImageModelOptionsSchema
51
+ >;
@@ -1,7 +1,5 @@
1
1
  import type { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';
2
- import type { InferSchema, Resolvable } from '@ai-sdk/provider-utils';
3
2
  import {
4
- FetchFunction,
5
3
  combineHeaders,
6
4
  createBinaryResponseHandler,
7
5
  createJsonErrorResponseHandler,
@@ -9,15 +7,22 @@ import {
9
7
  createStatusCodeErrorResponseHandler,
10
8
  delay,
11
9
  getFromApi,
12
- lazySchema,
10
+ isSameOrigin,
13
11
  parseProviderOptions,
14
12
  postJsonToApi,
15
13
  resolve,
16
- zodSchema,
14
+ serializeModelOptions,
15
+ WORKFLOW_SERIALIZE,
16
+ WORKFLOW_DESERIALIZE,
17
+ type Resolvable,
18
+ type FetchFunction,
17
19
  } from '@ai-sdk/provider-utils';
18
20
  import { z } from 'zod/v4';
19
- import type { BlackForestLabsAspectRatio } from './black-forest-labs-image-settings';
20
- import { BlackForestLabsImageModelId } from './black-forest-labs-image-settings';
21
+ import { blackForestLabsImageModelOptionsSchema } from './black-forest-labs-image-model-options';
22
+ import type {
23
+ BlackForestLabsAspectRatio,
24
+ BlackForestLabsImageModelId,
25
+ } from './black-forest-labs-image-settings';
21
26
 
22
27
  const DEFAULT_POLL_INTERVAL_MILLIS = 500;
23
28
  const DEFAULT_POLL_TIMEOUT_MILLIS = 60000;
@@ -48,6 +53,20 @@ export class BlackForestLabsImageModel implements ImageModelV4 {
48
53
  return this.config.provider;
49
54
  }
50
55
 
56
+ static [WORKFLOW_SERIALIZE](model: BlackForestLabsImageModel) {
57
+ return serializeModelOptions({
58
+ modelId: model.modelId,
59
+ config: model.config,
60
+ });
61
+ }
62
+
63
+ static [WORKFLOW_DESERIALIZE](options: {
64
+ modelId: BlackForestLabsImageModelId;
65
+ config: BlackForestLabsImageModelConfig;
66
+ }) {
67
+ return new BlackForestLabsImageModel(options.modelId, options.config);
68
+ }
69
+
51
70
  constructor(
52
71
  readonly modelId: BlackForestLabsImageModelId,
53
72
  private readonly config: BlackForestLabsImageModelConfig,
@@ -108,10 +127,12 @@ export class BlackForestLabsImageModel implements ImageModelV4 {
108
127
  throw new Error('Black Forest Labs supports up to 10 input images.');
109
128
  }
110
129
 
130
+ const inputImageField =
131
+ this.modelId === 'flux-pro-1.0-fill' ? 'image' : 'input_image';
111
132
  const inputImagesObj: Record<string, string> = inputImages.reduce<
112
133
  Record<string, string>
113
134
  >((acc, img, index) => {
114
- acc[`input_image${index === 0 ? '' : `_${index + 1}`}`] = img;
135
+ acc[`${inputImageField}${index === 0 ? '' : `_${index + 1}`}`] = img;
115
136
  return acc;
116
137
  }, {});
117
138
 
@@ -221,7 +242,12 @@ export class BlackForestLabsImageModel implements ImageModelV4 {
221
242
 
222
243
  const { value: imageBytes, responseHeaders } = await getFromApi({
223
244
  url: imageUrl,
224
- headers: combinedHeaders,
245
+ // Only send credentials if the response-supplied URL points back at the
246
+ // provider; the image is typically delivered from a CDN, so the API key
247
+ // must not travel to a foreign host.
248
+ headers: isTrustedUrl(imageUrl, this.config.baseURL)
249
+ ? combinedHeaders
250
+ : undefined,
225
251
  abortSignal,
226
252
  failedResponseHandler: createStatusCodeErrorResponseHandler(),
227
253
  successfulResponseHandler: createBinaryResponseHandler(),
@@ -300,7 +326,11 @@ export class BlackForestLabsImageModel implements ImageModelV4 {
300
326
  for (let i = 0; i < maxPollAttempts; i++) {
301
327
  const { value } = await getFromApi({
302
328
  url: url.toString(),
303
- headers,
329
+ // The polling URL comes from the provider response; only send
330
+ // credentials when it stays on a trusted provider host.
331
+ headers: isTrustedUrl(url.toString(), this.config.baseURL)
332
+ ? headers
333
+ : undefined,
304
334
  failedResponseHandler: bflFailedResponseHandler,
305
335
  successfulResponseHandler: createJsonResponseHandler(bflPollSchema),
306
336
  abortSignal,
@@ -333,50 +363,28 @@ export class BlackForestLabsImageModel implements ImageModelV4 {
333
363
  }
334
364
  }
335
365
 
336
- export const blackForestLabsImageModelOptionsSchema = lazySchema(() =>
337
- zodSchema(
338
- z.object({
339
- imagePrompt: z.string().optional(),
340
- imagePromptStrength: z.number().min(0).max(1).optional(),
341
- /** @deprecated use prompt.images instead */
342
- inputImage: z.string().optional(),
343
- /** @deprecated use prompt.images instead */
344
- inputImage2: z.string().optional(),
345
- /** @deprecated use prompt.images instead */
346
- inputImage3: z.string().optional(),
347
- /** @deprecated use prompt.images instead */
348
- inputImage4: z.string().optional(),
349
- /** @deprecated use prompt.images instead */
350
- inputImage5: z.string().optional(),
351
- /** @deprecated use prompt.images instead */
352
- inputImage6: z.string().optional(),
353
- /** @deprecated use prompt.images instead */
354
- inputImage7: z.string().optional(),
355
- /** @deprecated use prompt.images instead */
356
- inputImage8: z.string().optional(),
357
- /** @deprecated use prompt.images instead */
358
- inputImage9: z.string().optional(),
359
- /** @deprecated use prompt.images instead */
360
- inputImage10: z.string().optional(),
361
- steps: z.number().int().positive().optional(),
362
- guidance: z.number().min(0).optional(),
363
- width: z.number().int().min(256).max(1920).optional(),
364
- height: z.number().int().min(256).max(1920).optional(),
365
- outputFormat: z.enum(['jpeg', 'png']).optional(),
366
- promptUpsampling: z.boolean().optional(),
367
- raw: z.boolean().optional(),
368
- safetyTolerance: z.number().int().min(0).max(6).optional(),
369
- webhookSecret: z.string().optional(),
370
- webhookUrl: z.url().optional(),
371
- pollIntervalMillis: z.number().int().positive().optional(),
372
- pollTimeoutMillis: z.number().int().positive().optional(),
373
- }),
374
- ),
375
- );
376
-
377
- export type BlackForestLabsImageModelOptions = InferSchema<
378
- typeof blackForestLabsImageModelOptionsSchema
379
- >;
366
+ /**
367
+ * Black Forest Labs returns response-supplied URLs (polling and delivery) on
368
+ * sibling cluster hosts of the API origin (e.g. `api.us1.bfl.ai` for a base
369
+ * URL on `api.bfl.ai`), so a strict same-origin check against the configured
370
+ * base URL is not enough. Credentials may also be sent to any https host under
371
+ * the official `bfl.ai` domain.
372
+ */
373
+ function isTrustedUrl(url: string, baseUrl: string): boolean {
374
+ if (isSameOrigin(url, baseUrl)) {
375
+ return true;
376
+ }
377
+
378
+ try {
379
+ const { protocol, hostname } = new URL(url);
380
+ return (
381
+ protocol === 'https:' &&
382
+ (hostname === 'bfl.ai' || hostname.endsWith('.bfl.ai'))
383
+ );
384
+ } catch {
385
+ return false;
386
+ }
387
+ }
380
388
 
381
389
  function convertSizeToAspectRatio(
382
390
  size: string,
@@ -1,12 +1,16 @@
1
- import { ImageModelV4, NoSuchModelError, ProviderV4 } from '@ai-sdk/provider';
2
- import type { FetchFunction } from '@ai-sdk/provider-utils';
1
+ import {
2
+ NoSuchModelError,
3
+ type ImageModelV4,
4
+ type ProviderV4,
5
+ } from '@ai-sdk/provider';
3
6
  import {
4
7
  loadApiKey,
5
8
  withoutTrailingSlash,
6
9
  withUserAgentSuffix,
10
+ type FetchFunction,
7
11
  } from '@ai-sdk/provider-utils';
8
12
  import { BlackForestLabsImageModel } from './black-forest-labs-image-model';
9
- import { BlackForestLabsImageModelId } from './black-forest-labs-image-settings';
13
+ import type { BlackForestLabsImageModelId } from './black-forest-labs-image-settings';
10
14
  import { VERSION } from './version';
11
15
 
12
16
  export interface BlackForestLabsProviderSettings {
package/src/index.ts CHANGED
@@ -14,5 +14,5 @@ export type {
14
14
  BlackForestLabsImageModelOptions,
15
15
  /** @deprecated Use `BlackForestLabsImageModelOptions` instead. */
16
16
  BlackForestLabsImageModelOptions as BlackForestLabsImageProviderOptions,
17
- } from './black-forest-labs-image-model';
17
+ } from './black-forest-labs-image-model-options';
18
18
  export { VERSION } from './version';
package/dist/index.d.mts DELETED
@@ -1,82 +0,0 @@
1
- import { ProviderV4, ImageModelV4 } from '@ai-sdk/provider';
2
- import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
3
- import { FetchFunction, InferSchema } from '@ai-sdk/provider-utils';
4
-
5
- type BlackForestLabsImageModelId = 'flux-kontext-pro' | 'flux-kontext-max' | 'flux-pro-1.1-ultra' | 'flux-pro-1.1' | 'flux-pro-1.0-fill' | (string & {});
6
- type BlackForestLabsAspectRatio = `${number}:${number}`;
7
-
8
- interface BlackForestLabsProviderSettings {
9
- /**
10
- * Black Forest Labs API key. Default value is taken from the `BFL_API_KEY` environment variable.
11
- */
12
- apiKey?: string;
13
- /**
14
- * Base URL for the API calls. Defaults to `https://api.bfl.ai/v1`.
15
- */
16
- baseURL?: string;
17
- /**
18
- * Custom headers to include in the requests.
19
- */
20
- headers?: Record<string, string>;
21
- /**
22
- * Custom fetch implementation. You can use it as a middleware to intercept
23
- * requests, or to provide a custom fetch implementation for e.g. testing.
24
- */
25
- fetch?: FetchFunction;
26
- /**
27
- * Poll interval in milliseconds between status checks. Defaults to 500ms.
28
- */
29
- pollIntervalMillis?: number;
30
- /**
31
- * Overall timeout in milliseconds for polling before giving up. Defaults to 60s.
32
- */
33
- pollTimeoutMillis?: number;
34
- }
35
- interface BlackForestLabsProvider extends ProviderV4 {
36
- /**
37
- * Creates a model for image generation.
38
- */
39
- image(modelId: BlackForestLabsImageModelId): ImageModelV4;
40
- /**
41
- * Creates a model for image generation.
42
- */
43
- imageModel(modelId: BlackForestLabsImageModelId): ImageModelV4;
44
- /**
45
- * @deprecated Use `embeddingModel` instead.
46
- */
47
- textEmbeddingModel(modelId: string): never;
48
- }
49
- declare function createBlackForestLabs(options?: BlackForestLabsProviderSettings): BlackForestLabsProvider;
50
- declare const blackForestLabs: BlackForestLabsProvider;
51
-
52
- declare const blackForestLabsImageModelOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
53
- imagePrompt?: string | undefined;
54
- imagePromptStrength?: number | undefined;
55
- inputImage?: string | undefined;
56
- inputImage2?: string | undefined;
57
- inputImage3?: string | undefined;
58
- inputImage4?: string | undefined;
59
- inputImage5?: string | undefined;
60
- inputImage6?: string | undefined;
61
- inputImage7?: string | undefined;
62
- inputImage8?: string | undefined;
63
- inputImage9?: string | undefined;
64
- inputImage10?: string | undefined;
65
- steps?: number | undefined;
66
- guidance?: number | undefined;
67
- width?: number | undefined;
68
- height?: number | undefined;
69
- outputFormat?: "jpeg" | "png" | undefined;
70
- promptUpsampling?: boolean | undefined;
71
- raw?: boolean | undefined;
72
- safetyTolerance?: number | undefined;
73
- webhookSecret?: string | undefined;
74
- webhookUrl?: string | undefined;
75
- pollIntervalMillis?: number | undefined;
76
- pollTimeoutMillis?: number | undefined;
77
- }>;
78
- type BlackForestLabsImageModelOptions = InferSchema<typeof blackForestLabsImageModelOptionsSchema>;
79
-
80
- declare const VERSION: string;
81
-
82
- export { type BlackForestLabsAspectRatio, type BlackForestLabsImageModelId, type BlackForestLabsImageModelOptions, type BlackForestLabsImageModelOptions as BlackForestLabsImageProviderOptions, type BlackForestLabsProvider, type BlackForestLabsProviderSettings, VERSION, blackForestLabs, createBlackForestLabs };