@ai-sdk/fal 1.0.21 → 1.0.23

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/dist/index.mjs CHANGED
@@ -15,10 +15,94 @@ import {
15
15
  createJsonErrorResponseHandler,
16
16
  createStatusCodeErrorResponseHandler,
17
17
  getFromApi,
18
+ parseProviderOptions,
18
19
  postJsonToApi,
19
20
  resolve
20
21
  } from "@ai-sdk/provider-utils";
22
+ import { z as z2 } from "zod/v4";
23
+
24
+ // src/fal-image-options.ts
25
+ import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
21
26
  import { z } from "zod/v4";
27
+ var falImageProviderOptionsSchema = lazySchema(
28
+ () => zodSchema(
29
+ z.object({
30
+ imageUrl: z.string().nullish(),
31
+ guidanceScale: z.number().min(1).max(20).nullish(),
32
+ numInferenceSteps: z.number().min(1).max(50).nullish(),
33
+ enableSafetyChecker: z.boolean().nullish(),
34
+ outputFormat: z.enum(["jpeg", "png"]).nullish(),
35
+ syncMode: z.boolean().nullish(),
36
+ strength: z.number().nullish(),
37
+ acceleration: z.enum(["none", "regular", "high"]).nullish(),
38
+ safetyTolerance: z.enum(["1", "2", "3", "4", "5", "6"]).or(z.number().min(1).max(6)).nullish(),
39
+ // Deprecated snake_case versions
40
+ image_url: z.string().nullish(),
41
+ guidance_scale: z.number().min(1).max(20).nullish(),
42
+ num_inference_steps: z.number().min(1).max(50).nullish(),
43
+ enable_safety_checker: z.boolean().nullish(),
44
+ output_format: z.enum(["jpeg", "png"]).nullish(),
45
+ sync_mode: z.boolean().nullish(),
46
+ safety_tolerance: z.enum(["1", "2", "3", "4", "5", "6"]).or(z.number().min(1).max(6)).nullish()
47
+ }).passthrough().transform((data) => {
48
+ const result = {};
49
+ const deprecatedKeys = [];
50
+ const mapKey = (snakeKey, camelKey) => {
51
+ const snakeValue = data[snakeKey];
52
+ const camelValue = data[camelKey];
53
+ if (snakeValue !== void 0 && snakeValue !== null) {
54
+ deprecatedKeys.push(snakeKey);
55
+ result[camelKey] = snakeValue;
56
+ } else if (camelValue !== void 0 && camelValue !== null) {
57
+ result[camelKey] = camelValue;
58
+ }
59
+ };
60
+ mapKey("image_url", "imageUrl");
61
+ mapKey("guidance_scale", "guidanceScale");
62
+ mapKey("num_inference_steps", "numInferenceSteps");
63
+ mapKey("enable_safety_checker", "enableSafetyChecker");
64
+ mapKey("output_format", "outputFormat");
65
+ mapKey("sync_mode", "syncMode");
66
+ mapKey("safety_tolerance", "safetyTolerance");
67
+ if (data.strength !== void 0 && data.strength !== null) {
68
+ result.strength = data.strength;
69
+ }
70
+ if (data.acceleration !== void 0 && data.acceleration !== null) {
71
+ result.acceleration = data.acceleration;
72
+ }
73
+ for (const [key, value] of Object.entries(data)) {
74
+ if (![
75
+ // camelCase known keys
76
+ "imageUrl",
77
+ "guidanceScale",
78
+ "numInferenceSteps",
79
+ "enableSafetyChecker",
80
+ "outputFormat",
81
+ "syncMode",
82
+ "strength",
83
+ "acceleration",
84
+ "safetyTolerance",
85
+ // snake_case known keys
86
+ "image_url",
87
+ "guidance_scale",
88
+ "num_inference_steps",
89
+ "enable_safety_checker",
90
+ "output_format",
91
+ "sync_mode",
92
+ "safety_tolerance"
93
+ ].includes(key)) {
94
+ result[key] = value;
95
+ }
96
+ }
97
+ if (deprecatedKeys.length > 0) {
98
+ result.__deprecatedKeys = deprecatedKeys;
99
+ }
100
+ return result;
101
+ })
102
+ )
103
+ );
104
+
105
+ // src/fal-image-model.ts
22
106
  var FalImageModel = class {
23
107
  constructor(modelId, config) {
24
108
  this.modelId = modelId;
@@ -29,17 +113,15 @@ var FalImageModel = class {
29
113
  get provider() {
30
114
  return this.config.provider;
31
115
  }
32
- async doGenerate({
116
+ async getArgs({
33
117
  prompt,
34
118
  n,
35
119
  size,
36
120
  aspectRatio,
37
121
  seed,
38
- providerOptions,
39
- headers,
40
- abortSignal
122
+ providerOptions
41
123
  }) {
42
- var _a, _b, _c, _d;
124
+ var _a;
43
125
  const warnings = [];
44
126
  let imageSize;
45
127
  if (size) {
@@ -48,22 +130,66 @@ var FalImageModel = class {
48
130
  } else if (aspectRatio) {
49
131
  imageSize = convertAspectRatioToSize(aspectRatio);
50
132
  }
133
+ const falOptions = await parseProviderOptions({
134
+ provider: "fal",
135
+ providerOptions,
136
+ schema: falImageProviderOptionsSchema
137
+ });
138
+ const requestBody = {
139
+ prompt,
140
+ seed,
141
+ image_size: imageSize,
142
+ num_images: n
143
+ };
144
+ if (falOptions) {
145
+ const deprecatedKeys = "__deprecatedKeys" in falOptions ? falOptions.__deprecatedKeys : void 0;
146
+ if (deprecatedKeys && deprecatedKeys.length > 0) {
147
+ warnings.push({
148
+ type: "other",
149
+ message: `The following provider options use deprecated snake_case and will be removed in @ai-sdk/fal v2.0. Please use camelCase instead: ${deprecatedKeys.map((key) => {
150
+ const camelCase = key.replace(
151
+ /_([a-z])/g,
152
+ (_, letter) => letter.toUpperCase()
153
+ );
154
+ return `'${key}' (use '${camelCase}')`;
155
+ }).join(", ")}`
156
+ });
157
+ }
158
+ const fieldMapping = {
159
+ imageUrl: "image_url",
160
+ guidanceScale: "guidance_scale",
161
+ numInferenceSteps: "num_inference_steps",
162
+ enableSafetyChecker: "enable_safety_checker",
163
+ outputFormat: "output_format",
164
+ syncMode: "sync_mode",
165
+ safetyTolerance: "safety_tolerance"
166
+ };
167
+ for (const [key, value] of Object.entries(falOptions)) {
168
+ if (key === "__deprecatedKeys") continue;
169
+ const apiKey = (_a = fieldMapping[key]) != null ? _a : key;
170
+ if (value !== void 0) {
171
+ requestBody[apiKey] = value;
172
+ }
173
+ }
174
+ }
175
+ return { requestBody, warnings };
176
+ }
177
+ async doGenerate(options) {
178
+ var _a, _b, _c;
179
+ const { requestBody, warnings } = await this.getArgs(options);
51
180
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
52
181
  const { value, responseHeaders } = await postJsonToApi({
53
182
  url: `${this.config.baseURL}/${this.modelId}`,
54
- headers: combineHeaders(await resolve(this.config.headers), headers),
55
- body: {
56
- prompt,
57
- seed,
58
- image_size: imageSize,
59
- num_images: n,
60
- ...(_d = providerOptions.fal) != null ? _d : {}
61
- },
183
+ headers: combineHeaders(
184
+ await resolve(this.config.headers),
185
+ options.headers
186
+ ),
187
+ body: requestBody,
62
188
  failedResponseHandler: falFailedResponseHandler,
63
189
  successfulResponseHandler: createJsonResponseHandler(
64
190
  falImageResponseSchema
65
191
  ),
66
- abortSignal,
192
+ abortSignal: options.abortSignal,
67
193
  fetch: this.config.fetch
68
194
  });
69
195
  const {
@@ -77,7 +203,9 @@ var FalImageModel = class {
77
203
  ...responseMetaData
78
204
  } = value;
79
205
  const downloadedImages = await Promise.all(
80
- targetImages.map((image) => this.downloadImage(image.url, abortSignal))
206
+ targetImages.map(
207
+ (image) => this.downloadImage(image.url, options.abortSignal)
208
+ )
81
209
  );
82
210
  return {
83
211
  images: downloadedImages,
@@ -157,56 +285,56 @@ function convertAspectRatioToSize(aspectRatio) {
157
285
  }
158
286
  return void 0;
159
287
  }
160
- var falValidationErrorSchema = z.object({
161
- detail: z.array(
162
- z.object({
163
- loc: z.array(z.string()),
164
- msg: z.string(),
165
- type: z.string()
288
+ var falValidationErrorSchema = z2.object({
289
+ detail: z2.array(
290
+ z2.object({
291
+ loc: z2.array(z2.string()),
292
+ msg: z2.string(),
293
+ type: z2.string()
166
294
  })
167
295
  )
168
296
  });
169
- var falHttpErrorSchema = z.object({
170
- message: z.string()
297
+ var falHttpErrorSchema = z2.object({
298
+ message: z2.string()
171
299
  });
172
- var falErrorSchema = z.union([falValidationErrorSchema, falHttpErrorSchema]);
173
- var falImageSchema = z.object({
174
- url: z.string(),
175
- width: z.number().nullish(),
176
- height: z.number().nullish(),
300
+ var falErrorSchema = z2.union([falValidationErrorSchema, falHttpErrorSchema]);
301
+ var falImageSchema = z2.object({
302
+ url: z2.string(),
303
+ width: z2.number().nullish(),
304
+ height: z2.number().nullish(),
177
305
  // e.g. https://fal.ai/models/fal-ai/fashn/tryon/v1.6/api#schema-output
178
- content_type: z.string().nullish(),
306
+ content_type: z2.string().nullish(),
179
307
  // e.g. https://fal.ai/models/fal-ai/flowedit/api#schema-output
180
- file_name: z.string().nullish(),
181
- file_data: z.string().optional(),
182
- file_size: z.number().nullish()
308
+ file_name: z2.string().nullish(),
309
+ file_data: z2.string().optional(),
310
+ file_size: z2.number().nullish()
183
311
  });
184
- var loraFileSchema = z.object({
185
- url: z.string(),
186
- content_type: z.string().optional(),
187
- file_name: z.string().nullable().optional(),
188
- file_data: z.string().optional(),
189
- file_size: z.number().nullable().optional()
312
+ var loraFileSchema = z2.object({
313
+ url: z2.string(),
314
+ content_type: z2.string().optional(),
315
+ file_name: z2.string().nullable().optional(),
316
+ file_data: z2.string().optional(),
317
+ file_size: z2.number().nullable().optional()
190
318
  });
191
- var commonResponseSchema = z.object({
192
- timings: z.object({
193
- inference: z.number().optional()
319
+ var commonResponseSchema = z2.object({
320
+ timings: z2.object({
321
+ inference: z2.number().optional()
194
322
  }).optional(),
195
- seed: z.number().optional(),
196
- has_nsfw_concepts: z.array(z.boolean()).optional(),
197
- prompt: z.string().optional(),
323
+ seed: z2.number().optional(),
324
+ has_nsfw_concepts: z2.array(z2.boolean()).optional(),
325
+ prompt: z2.string().optional(),
198
326
  // https://fal.ai/models/fal-ai/lcm/api#schema-output
199
- nsfw_content_detected: z.array(z.boolean()).optional(),
200
- num_inference_steps: z.number().optional(),
327
+ nsfw_content_detected: z2.array(z2.boolean()).optional(),
328
+ num_inference_steps: z2.number().optional(),
201
329
  // https://fal.ai/models/fal-ai/lora/api#schema-output
202
330
  debug_latents: loraFileSchema.optional(),
203
331
  debug_per_pass_latents: loraFileSchema.optional()
204
332
  });
205
- var base = z.looseObject(commonResponseSchema.shape);
206
- var falImageResponseSchema = z.union([
207
- base.extend({ images: z.array(falImageSchema) }),
333
+ var base = z2.looseObject(commonResponseSchema.shape);
334
+ var falImageResponseSchema = z2.union([
335
+ base.extend({ images: z2.array(falImageSchema) }),
208
336
  base.extend({ image: falImageSchema })
209
- ]).transform((v) => "images" in v ? v : { ...v, images: [v.image] }).pipe(base.extend({ images: z.array(falImageSchema) }));
337
+ ]).transform((v) => "images" in v ? v : { ...v, images: [v.image] }).pipe(base.extend({ images: z2.array(falImageSchema) }));
210
338
  function isValidationError(error) {
211
339
  return falValidationErrorSchema.safeParse(error).success;
212
340
  }
@@ -232,18 +360,18 @@ import {
232
360
  createJsonResponseHandler as createJsonResponseHandler2,
233
361
  delay,
234
362
  getFromApi as getFromApi2,
235
- parseProviderOptions,
363
+ parseProviderOptions as parseProviderOptions2,
236
364
  postJsonToApi as postJsonToApi2
237
365
  } from "@ai-sdk/provider-utils";
238
- import { z as z3 } from "zod/v4";
366
+ import { z as z4 } from "zod/v4";
239
367
 
240
368
  // src/fal-error.ts
241
- import { z as z2 } from "zod/v4";
369
+ import { z as z3 } from "zod/v4";
242
370
  import { createJsonErrorResponseHandler as createJsonErrorResponseHandler2 } from "@ai-sdk/provider-utils";
243
- var falErrorDataSchema = z2.object({
244
- error: z2.object({
245
- message: z2.string(),
246
- code: z2.number()
371
+ var falErrorDataSchema = z3.object({
372
+ error: z3.object({
373
+ message: z3.string(),
374
+ code: z3.number()
247
375
  })
248
376
  });
249
377
  var falFailedResponseHandler2 = createJsonErrorResponseHandler2({
@@ -252,33 +380,33 @@ var falFailedResponseHandler2 = createJsonErrorResponseHandler2({
252
380
  });
253
381
 
254
382
  // src/fal-transcription-model.ts
255
- var falProviderOptionsSchema = z3.object({
383
+ var falProviderOptionsSchema = z4.object({
256
384
  /**
257
385
  * Language of the audio file. If set to null, the language will be automatically detected. Defaults to null.
258
386
  *
259
387
  * If translate is selected as the task, the audio will be translated to English, regardless of the language selected.
260
388
  */
261
- language: z3.union([z3.enum(["en"]), z3.string()]).nullish().default("en"),
389
+ language: z4.union([z4.enum(["en"]), z4.string()]).nullish().default("en"),
262
390
  /**
263
391
  * Whether to diarize the audio file. Defaults to true.
264
392
  */
265
- diarize: z3.boolean().nullish().default(true),
393
+ diarize: z4.boolean().nullish().default(true),
266
394
  /**
267
395
  * Level of the chunks to return. Either segment or word. Default value: "segment"
268
396
  */
269
- chunkLevel: z3.enum(["segment", "word"]).nullish().default("segment"),
397
+ chunkLevel: z4.enum(["segment", "word"]).nullish().default("segment"),
270
398
  /**
271
399
  * Version of the model to use. All of the models are the Whisper large variant. Default value: "3"
272
400
  */
273
- version: z3.enum(["3"]).nullish().default("3"),
401
+ version: z4.enum(["3"]).nullish().default("3"),
274
402
  /**
275
403
  * Default value: 64
276
404
  */
277
- batchSize: z3.number().nullish().default(64),
405
+ batchSize: z4.number().nullish().default(64),
278
406
  /**
279
407
  * Number of speakers in the audio file. Defaults to null. If not provided, the number of speakers will be automatically detected.
280
408
  */
281
- numSpeakers: z3.number().nullable().nullish()
409
+ numSpeakers: z4.number().nullable().nullish()
282
410
  });
283
411
  var FalTranscriptionModel = class {
284
412
  constructor(modelId, config) {
@@ -294,7 +422,7 @@ var FalTranscriptionModel = class {
294
422
  }) {
295
423
  var _a, _b, _c;
296
424
  const warnings = [];
297
- const falOptions = await parseProviderOptions({
425
+ const falOptions = await parseProviderOptions2({
298
426
  provider: "fal",
299
427
  providerOptions,
300
428
  schema: falProviderOptionsSchema
@@ -426,18 +554,18 @@ var FalTranscriptionModel = class {
426
554
  };
427
555
  }
428
556
  };
429
- var falJobResponseSchema = z3.object({
430
- request_id: z3.string().nullish()
557
+ var falJobResponseSchema = z4.object({
558
+ request_id: z4.string().nullish()
431
559
  });
432
- var falTranscriptionResponseSchema = z3.object({
433
- text: z3.string(),
434
- chunks: z3.array(
435
- z3.object({
436
- text: z3.string(),
437
- timestamp: z3.array(z3.number()).nullish()
560
+ var falTranscriptionResponseSchema = z4.object({
561
+ text: z4.string(),
562
+ chunks: z4.array(
563
+ z4.object({
564
+ text: z4.string(),
565
+ timestamp: z4.array(z4.number()).nullish()
438
566
  })
439
567
  ).nullish(),
440
- inferred_languages: z3.array(z3.string()).nullish()
568
+ inferred_languages: z4.array(z4.string()).nullish()
441
569
  });
442
570
 
443
571
  // src/fal-speech-model.ts
@@ -447,10 +575,10 @@ import {
447
575
  createJsonResponseHandler as createJsonResponseHandler3,
448
576
  createStatusCodeErrorResponseHandler as createStatusCodeErrorResponseHandler2,
449
577
  getFromApi as getFromApi3,
450
- parseProviderOptions as parseProviderOptions2,
578
+ parseProviderOptions as parseProviderOptions3,
451
579
  postJsonToApi as postJsonToApi3
452
580
  } from "@ai-sdk/provider-utils";
453
- import { z as z4 } from "zod/v4";
581
+ import { z as z5 } from "zod/v4";
454
582
 
455
583
  // src/fal-api-types.ts
456
584
  var FAL_LANGUAGE_BOOSTS = [
@@ -491,18 +619,18 @@ var FAL_EMOTIONS = [
491
619
  ];
492
620
 
493
621
  // src/fal-speech-model.ts
494
- var falSpeechProviderOptionsSchema = z4.looseObject({
495
- voice_setting: z4.object({
496
- speed: z4.number().nullish(),
497
- vol: z4.number().nullish(),
498
- voice_id: z4.string().nullish(),
499
- pitch: z4.number().nullish(),
500
- english_normalization: z4.boolean().nullish(),
501
- emotion: z4.enum(FAL_EMOTIONS).nullish()
622
+ var falSpeechProviderOptionsSchema = z5.looseObject({
623
+ voice_setting: z5.object({
624
+ speed: z5.number().nullish(),
625
+ vol: z5.number().nullish(),
626
+ voice_id: z5.string().nullish(),
627
+ pitch: z5.number().nullish(),
628
+ english_normalization: z5.boolean().nullish(),
629
+ emotion: z5.enum(FAL_EMOTIONS).nullish()
502
630
  }).partial().nullish(),
503
- audio_setting: z4.record(z4.string(), z4.unknown()).nullish(),
504
- language_boost: z4.enum(FAL_LANGUAGE_BOOSTS).nullish(),
505
- pronunciation_dict: z4.record(z4.string(), z4.string()).nullish()
631
+ audio_setting: z5.record(z5.string(), z5.unknown()).nullish(),
632
+ language_boost: z5.enum(FAL_LANGUAGE_BOOSTS).nullish(),
633
+ pronunciation_dict: z5.record(z5.string(), z5.string()).nullish()
506
634
  });
507
635
  var FalSpeechModel = class {
508
636
  constructor(modelId, config) {
@@ -522,7 +650,7 @@ var FalSpeechModel = class {
522
650
  providerOptions
523
651
  }) {
524
652
  const warnings = [];
525
- const falOptions = await parseProviderOptions2({
653
+ const falOptions = await parseProviderOptions3({
526
654
  provider: "fal",
527
655
  providerOptions,
528
656
  schema: falSpeechProviderOptionsSchema
@@ -595,14 +723,14 @@ var FalSpeechModel = class {
595
723
  };
596
724
  }
597
725
  };
598
- var falSpeechResponseSchema = z4.object({
599
- audio: z4.object({ url: z4.string() }),
600
- duration_ms: z4.number().optional(),
601
- request_id: z4.string().optional()
726
+ var falSpeechResponseSchema = z5.object({
727
+ audio: z5.object({ url: z5.string() }),
728
+ duration_ms: z5.number().optional(),
729
+ request_id: z5.string().optional()
602
730
  });
603
731
 
604
732
  // src/version.ts
605
- var VERSION = true ? "1.0.21" : "0.0.0-test";
733
+ var VERSION = true ? "1.0.23" : "0.0.0-test";
606
734
 
607
735
  // src/fal-provider.ts
608
736
  var defaultBaseURL = "https://fal.run";