@ai-sdk/fal 3.0.48 → 3.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @ai-sdk/fal
2
2
 
3
+ ## 3.0.51
4
+
5
+ ### Patch Changes
6
+
7
+ - 525efc5: feat(provider): advertise image model file and mask input support
8
+
9
+ Use confirmed model IDs for capability declarations so unrecognized model names
10
+ remain unknown. Include Together AI FLUX.2 Pro and Flex single-image editing, and
11
+ allow asynchronous capability lookups and middleware overrides to resolve to
12
+ unknown.
13
+
14
+ Advertise QuiverAI Arrow 2 and Arrow 2 Telos file-input support, and mark Together
15
+ AI Gemini image inputs unsupported by the current single-image request mapping.
16
+
17
+ - Updated dependencies [e3605f6]
18
+ - Updated dependencies [525efc5]
19
+ - @ai-sdk/provider-utils@5.0.50
20
+ - @ai-sdk/provider@4.0.19
21
+
22
+ ## 3.0.50
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies [af9597b]
27
+ - Updated dependencies [bc49f78]
28
+ - @ai-sdk/provider-utils@5.0.49
29
+
30
+ ## 3.0.49
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies [be877ff]
35
+ - @ai-sdk/provider-utils@5.0.48
36
+
3
37
  ## 3.0.48
4
38
 
5
39
  ### Patch Changes
package/dist/index.js CHANGED
@@ -134,6 +134,39 @@ var FalImageModel = class _FalImageModel {
134
134
  this.specificationVersion = "v4";
135
135
  this.maxImagesPerCall = 1;
136
136
  }
137
+ get supportsFileInputs() {
138
+ if ([
139
+ "fal-ai/flux-2/edit",
140
+ "fal-ai/flux-pro/kontext",
141
+ "fal-ai/flux-pro/kontext/max",
142
+ "fal-ai/flux-general/image-to-image",
143
+ "fal-ai/flux-general/inpainting",
144
+ "fal-ai/flux-lora/image-to-image",
145
+ "fal-ai/flux-lora/inpainting",
146
+ "fal-ai/flux/dev/image-to-image",
147
+ "fal-ai/flux/krea/image-to-image",
148
+ "fal-ai/recraft/v3/image-to-image"
149
+ ].includes(this.modelId)) {
150
+ return true;
151
+ }
152
+ return [
153
+ "bria/text-to-image/3.2",
154
+ "fal-ai/bria/text-to-image/base",
155
+ "fal-ai/bria/text-to-image/fast",
156
+ "fal-ai/bria/text-to-image/hd",
157
+ "fal-ai/bytedance/dreamina/v3.1/text-to-image",
158
+ "fal-ai/flux-kontext-lora/text-to-image",
159
+ "fal-ai/recraft/v3/text-to-image",
160
+ "fal-ai/wan/v2.2-5b/text-to-image",
161
+ "fal-ai/wan/v2.2-a14b/text-to-image"
162
+ ].includes(this.modelId) ? false : void 0;
163
+ }
164
+ get supportsMaskInputs() {
165
+ if (this.modelId === "fal-ai/flux-general/inpainting" || this.modelId === "fal-ai/flux-lora/inpainting") {
166
+ return true;
167
+ }
168
+ return this.supportsFileInputs == null ? void 0 : false;
169
+ }
137
170
  get provider() {
138
171
  return this.config.provider;
139
172
  }
@@ -156,7 +189,6 @@ var FalImageModel = class _FalImageModel {
156
189
  files,
157
190
  mask
158
191
  }) {
159
- var _a;
160
192
  const warnings = [];
161
193
  let imageSize;
162
194
  if (size) {
@@ -177,7 +209,7 @@ var FalImageModel = class _FalImageModel {
177
209
  num_images: n
178
210
  };
179
211
  if (files != null && files.length > 0) {
180
- const useMultipleImages = (falOptions == null ? void 0 : falOptions.useMultipleImages) === true;
212
+ const useMultipleImages = falOptions?.useMultipleImages === true;
181
213
  if (useMultipleImages) {
182
214
  requestBody.image_urls = files.map(
183
215
  (file) => convertImageModelFileToDataUri(file)
@@ -222,7 +254,7 @@ var FalImageModel = class _FalImageModel {
222
254
  for (const [key, value] of Object.entries(falOptions)) {
223
255
  if (key === "__deprecatedKeys") continue;
224
256
  if (key === "useMultipleImages") continue;
225
- const apiKey = (_a = fieldMapping[key]) != null ? _a : key;
257
+ const apiKey = fieldMapping[key] ?? key;
226
258
  if (value !== void 0) {
227
259
  requestBody[apiKey] = value;
228
260
  }
@@ -231,9 +263,8 @@ var FalImageModel = class _FalImageModel {
231
263
  return { requestBody, warnings };
232
264
  }
233
265
  async doGenerate(options) {
234
- var _a, _b, _c;
235
266
  const { requestBody, warnings } = await this.getArgs(options);
236
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
267
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
237
268
  const { value, responseHeaders } = await postJsonToApi({
238
269
  url: `${this.config.baseURL}/${this.modelId}`,
239
270
  headers: combineHeaders(
@@ -274,7 +305,6 @@ var FalImageModel = class _FalImageModel {
274
305
  providerMetadata: {
275
306
  fal: {
276
307
  images: targetImages.map((image, index) => {
277
- var _a2;
278
308
  const {
279
309
  url: _url,
280
310
  content_type: contentType,
@@ -283,7 +313,7 @@ var FalImageModel = class _FalImageModel {
283
313
  file_size: fileSize,
284
314
  ...imageMetaData
285
315
  } = image;
286
- const nsfw = (_a2 = has_nsfw_concepts == null ? void 0 : has_nsfw_concepts[index]) != null ? _a2 : nsfw_content_detected == null ? void 0 : nsfw_content_detected[index];
316
+ const nsfw = has_nsfw_concepts?.[index] ?? nsfw_content_detected?.[index];
287
317
  return {
288
318
  ...imageMetaData,
289
319
  ...removeOnlyUndefined({
@@ -399,11 +429,10 @@ function isValidationError(error) {
399
429
  var falFailedResponseHandler = createJsonErrorResponseHandler({
400
430
  errorSchema: falErrorSchema,
401
431
  errorToMessage: (error) => {
402
- var _a;
403
432
  if (isValidationError(error)) {
404
433
  return error.detail.map((detail) => `${detail.loc.join(".")}: ${detail.msg}`).join("\n");
405
434
  }
406
- return (_a = error.message) != null ? _a : "Unknown fal error";
435
+ return error.message ?? "Unknown fal error";
407
436
  }
408
437
  });
409
438
 
@@ -493,7 +522,6 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
493
522
  async getArgs({
494
523
  providerOptions
495
524
  }) {
496
- var _a, _b, _c;
497
525
  const warnings = [];
498
526
  const falOptions = await parseProviderOptions2({
499
527
  provider: "fal",
@@ -507,9 +535,9 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
507
535
  };
508
536
  if (falOptions) {
509
537
  body.language = falOptions.language;
510
- body.version = (_a = falOptions.version) != null ? _a : void 0;
511
- body.batch_size = (_b = falOptions.batchSize) != null ? _b : void 0;
512
- body.num_speakers = (_c = falOptions.numSpeakers) != null ? _c : void 0;
538
+ body.version = falOptions.version ?? void 0;
539
+ body.batch_size = falOptions.batchSize ?? void 0;
540
+ body.num_speakers = falOptions.numSpeakers ?? void 0;
513
541
  if (typeof falOptions.diarize === "boolean") {
514
542
  body.diarize = falOptions.diarize;
515
543
  }
@@ -523,8 +551,7 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
523
551
  };
524
552
  }
525
553
  async doGenerate(options) {
526
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
527
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
554
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
528
555
  const { body, warnings } = await this.getArgs(options);
529
556
  const base64Audio = typeof options.audio === "string" ? options.audio : convertUint8ArrayToBase64(options.audio);
530
557
  const audioUrl = `data:${options.mediaType};base64,${base64Audio}`;
@@ -533,7 +560,7 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
533
560
  path: `https://queue.fal.run/fal-ai/${this.modelId}`,
534
561
  modelId: this.modelId
535
562
  }),
536
- headers: combineHeaders2((_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d), options.headers),
563
+ headers: combineHeaders2(this.config.headers?.(), options.headers),
537
564
  body: {
538
565
  ...body,
539
566
  audio_url: audioUrl
@@ -561,7 +588,7 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
561
588
  modelId: this.modelId
562
589
  }),
563
590
  validateUrl: false,
564
- headers: combineHeaders2((_g = (_f = this.config).headers) == null ? void 0 : _g.call(_f), options.headers),
591
+ headers: combineHeaders2(this.config.headers?.(), options.headers),
565
592
  failedResponseHandler: async ({
566
593
  requestBodyValues,
567
594
  response: response2,
@@ -608,16 +635,13 @@ var FalTranscriptionModel = class _FalTranscriptionModel {
608
635
  }
609
636
  return {
610
637
  text: response.text,
611
- segments: (_i = (_h = response.chunks) == null ? void 0 : _h.map((chunk) => {
612
- var _a2, _b2, _c2, _d2;
613
- return {
614
- text: chunk.text,
615
- startSecond: (_b2 = (_a2 = chunk.timestamp) == null ? void 0 : _a2.at(0)) != null ? _b2 : 0,
616
- endSecond: (_d2 = (_c2 = chunk.timestamp) == null ? void 0 : _c2.at(1)) != null ? _d2 : 0
617
- };
618
- })) != null ? _i : [],
619
- language: (_k = (_j = response.inferred_languages) == null ? void 0 : _j.at(0)) != null ? _k : void 0,
620
- durationInSeconds: (_o = (_n = (_m = (_l = response.chunks) == null ? void 0 : _l.at(-1)) == null ? void 0 : _m.timestamp) == null ? void 0 : _n.at(1)) != null ? _o : void 0,
638
+ segments: response.chunks?.map((chunk) => ({
639
+ text: chunk.text,
640
+ startSecond: chunk.timestamp?.at(0) ?? 0,
641
+ endSecond: chunk.timestamp?.at(1) ?? 0
642
+ })) ?? [],
643
+ language: response.inferred_languages?.at(0) ?? void 0,
644
+ durationInSeconds: response.chunks?.at(-1)?.timestamp?.at(1) ?? void 0,
621
645
  warnings,
622
646
  response: {
623
647
  timestamp: currentDate,
@@ -770,8 +794,7 @@ var FalSpeechModel = class _FalSpeechModel {
770
794
  return { requestBody, warnings };
771
795
  }
772
796
  async doGenerate(options) {
773
- var _a, _b, _c, _d, _e;
774
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
797
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
775
798
  const { requestBody, warnings } = await this.getArgs(options);
776
799
  const requestUrl = this.config.url({
777
800
  path: `https://fal.run/${this.modelId}`,
@@ -783,7 +806,7 @@ var FalSpeechModel = class _FalSpeechModel {
783
806
  rawValue
784
807
  } = await postJsonToApi3({
785
808
  url: requestUrl,
786
- headers: combineHeaders3((_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d), options.headers),
809
+ headers: combineHeaders3(this.config.headers?.(), options.headers),
787
810
  body: requestBody,
788
811
  failedResponseHandler: falFailedResponseHandler2,
789
812
  successfulResponseHandler: createJsonResponseHandler3(
@@ -879,8 +902,7 @@ var FalVideoModel = class {
879
902
  return { webhookUrl: url, received };
880
903
  }
881
904
  async doStart(options) {
882
- var _a, _b, _c;
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();
905
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
884
906
  const warnings = [];
885
907
  const { body } = await this.buildRequestBody(options);
886
908
  const { responseUrl, submitUrl } = await this.submitToQueue(
@@ -902,8 +924,7 @@ var FalVideoModel = class {
902
924
  };
903
925
  }
904
926
  async doStatus(options) {
905
- var _a, _b, _c;
906
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
927
+ const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
907
928
  const { responseUrl, submitUrl } = options.operation;
908
929
  try {
909
930
  const { value: response, responseHeaders } = await this.fetchStatus({
@@ -1001,7 +1022,6 @@ var FalVideoModel = class {
1001
1022
  return { body, falOptions };
1002
1023
  }
1003
1024
  async submitToQueue(options, body) {
1004
- var _a, _b;
1005
1025
  let queuePath = `https://queue.fal.run/fal-ai/${this.normalizedModelId}`;
1006
1026
  if (options.webhookUrl) {
1007
1027
  queuePath += `?fal_webhook=${encodeURIComponent(options.webhookUrl)}`;
@@ -1012,7 +1032,7 @@ var FalVideoModel = class {
1012
1032
  });
1013
1033
  const { value: queueResponse } = await postJsonToApi4({
1014
1034
  url: submitUrl,
1015
- headers: combineHeaders4((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
1035
+ headers: combineHeaders4(this.config.headers?.(), options.headers),
1016
1036
  body,
1017
1037
  failedResponseHandler: falFailedResponseHandler2,
1018
1038
  successfulResponseHandler: createJsonResponseHandler4(falJobResponseSchema2),
@@ -1034,7 +1054,6 @@ var FalVideoModel = class {
1034
1054
  headers,
1035
1055
  abortSignal
1036
1056
  }) {
1037
- var _a, _b;
1038
1057
  const statusUrl = this.config.url({
1039
1058
  path: responseUrl,
1040
1059
  modelId: this.modelId
@@ -1045,7 +1064,7 @@ var FalVideoModel = class {
1045
1064
  validateUrl: true,
1046
1065
  credentialedOrigin: submitUrl,
1047
1066
  trustedOrigin: submitUrl,
1048
- headers: combineHeaders4((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), headers),
1067
+ headers: combineHeaders4(this.config.headers?.(), headers),
1049
1068
  failedResponseHandler: async ({ response, url, requestBodyValues }) => {
1050
1069
  const body = await response.clone().json();
1051
1070
  if (body.detail === "Request is still in progress") {
@@ -1073,8 +1092,7 @@ var FalVideoModel = class {
1073
1092
  warnings,
1074
1093
  currentDate
1075
1094
  }) {
1076
- var _a;
1077
- const videoUrl = (_a = response.video) == null ? void 0 : _a.url;
1095
+ const videoUrl = response.video?.url;
1078
1096
  if (!videoUrl || !response.video) {
1079
1097
  throw new AISDKError2({
1080
1098
  name: "FAL_VIDEO_GENERATION_ERROR",
@@ -1139,7 +1157,7 @@ var falVideoResponseSchema = z9.object({
1139
1157
  });
1140
1158
 
1141
1159
  // src/version.ts
1142
- var VERSION = true ? "3.0.48" : "0.0.0-test";
1160
+ var VERSION = true ? "3.0.51" : "0.0.0-test";
1143
1161
 
1144
1162
  // src/fal-provider.ts
1145
1163
  var defaultBaseURL = "https://fal.run";
@@ -1175,8 +1193,7 @@ function loadFalApiKey({
1175
1193
  return envApiKey;
1176
1194
  }
1177
1195
  function createFal(options = {}) {
1178
- var _a;
1179
- const baseURL = withoutTrailingSlash((_a = options.baseURL) != null ? _a : defaultBaseURL);
1196
+ const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);
1180
1197
  const getHeaders = () => withUserAgentSuffix(
1181
1198
  {
1182
1199
  Authorization: `Key ${loadFalApiKey({
@@ -1188,7 +1205,7 @@ function createFal(options = {}) {
1188
1205
  );
1189
1206
  const createImageModel = (modelId) => new FalImageModel(modelId, {
1190
1207
  provider: "fal.image",
1191
- baseURL: baseURL != null ? baseURL : defaultBaseURL,
1208
+ baseURL: baseURL ?? defaultBaseURL,
1192
1209
  headers: getHeaders,
1193
1210
  fetch: options.fetch
1194
1211
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fal-provider.ts","../src/fal-image-model.ts","../src/fal-image-model-options.ts","../src/fal-transcription-model.ts","../src/fal-error.ts","../src/fal-transcription-model-options.ts","../src/fal-speech-model.ts","../src/fal-speech-model-options.ts","../src/fal-api-types.ts","../src/fal-video-model.ts","../src/fal-video-model-options.ts","../src/version.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type Experimental_VideoModelV4,\n type ImageModelV4,\n type ProviderV4,\n type SpeechModelV4,\n type TranscriptionModelV4,\n} from '@ai-sdk/provider';\nimport {\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { FalImageModel } from './fal-image-model';\nimport type { FalImageModelId } from './fal-image-settings';\nimport type { FalTranscriptionModelId } from './fal-transcription-options';\nimport { FalTranscriptionModel } from './fal-transcription-model';\nimport type { FalSpeechModelId } from './fal-speech-settings';\nimport { FalSpeechModel } from './fal-speech-model';\nimport { FalVideoModel } from './fal-video-model';\nimport type { FalVideoModelId } from './fal-video-settings';\nimport { VERSION } from './version';\n\nexport interface FalProviderSettings {\n /**\n * fal.ai API key. Default value is taken from the `FAL_API_KEY` environment\n * variable, falling back to `FAL_KEY`.\n */\n apiKey?: string;\n\n /**\n * Base URL for the API calls.\n * The default prefix is `https://fal.run`.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept\n * requests, or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface FalProvider extends ProviderV4 {\n /**\n * Creates a model for image generation.\n */\n image(modelId: FalImageModelId): ImageModelV4;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: FalImageModelId): ImageModelV4;\n\n /**\n * Creates a model for transcription.\n */\n transcription(modelId: FalTranscriptionModelId): TranscriptionModelV4;\n\n /**\n * Creates a model for video generation.\n */\n video(modelId: FalVideoModelId): Experimental_VideoModelV4;\n\n /**\n * Creates a model for video generation.\n */\n videoModel(modelId: FalVideoModelId): Experimental_VideoModelV4;\n\n /**\n * Creates a model for speech generation.\n */\n speech(modelId: FalSpeechModelId): SpeechModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n}\n\nconst defaultBaseURL = 'https://fal.run';\n\nfunction loadFalApiKey({\n apiKey,\n description = 'fal.ai',\n}: {\n apiKey: string | undefined;\n description?: string;\n}): string {\n if (typeof apiKey === 'string') {\n return apiKey;\n }\n\n if (apiKey != null) {\n throw new Error(`${description} API key must be a string.`);\n }\n\n if (typeof process === 'undefined') {\n throw new Error(\n `${description} API key is missing. Pass it using the 'apiKey' parameter. Environment variables are not supported in this environment.`,\n );\n }\n\n let envApiKey = process.env.FAL_API_KEY;\n if (envApiKey == null) {\n envApiKey = process.env.FAL_KEY;\n }\n\n if (envApiKey == null) {\n throw new Error(\n `${description} API key is missing. Pass it using the 'apiKey' parameter or set either the FAL_API_KEY or FAL_KEY environment variable.`,\n );\n }\n\n if (typeof envApiKey !== 'string') {\n throw new Error(\n `${description} API key must be a string. The value of the environment variable is not a string.`,\n );\n }\n\n return envApiKey;\n}\n\n/**\n * Create a fal.ai provider instance.\n */\nexport function createFal(options: FalProviderSettings = {}): FalProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Key ${loadFalApiKey({\n apiKey: options.apiKey,\n })}`,\n ...options.headers,\n },\n `ai-sdk/fal/${VERSION}`,\n );\n\n const createImageModel = (modelId: FalImageModelId) =>\n new FalImageModel(modelId, {\n provider: 'fal.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createSpeechModel = (modelId: FalSpeechModelId) =>\n new FalSpeechModel(modelId, {\n provider: `fal.speech`,\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createTranscriptionModel = (modelId: FalTranscriptionModelId) =>\n new FalTranscriptionModel(modelId, {\n provider: `fal.transcription`,\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createVideoModel = (modelId: FalVideoModelId) =>\n new FalVideoModel(modelId, {\n provider: 'fal.video',\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'embeddingModel',\n });\n };\n\n return {\n specificationVersion: 'v4' as const,\n imageModel: createImageModel,\n image: createImageModel,\n languageModel: (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'languageModel',\n });\n },\n speech: createSpeechModel,\n embeddingModel,\n textEmbeddingModel: embeddingModel,\n transcription: createTranscriptionModel,\n video: createVideoModel,\n videoModel: createVideoModel,\n };\n}\n\n/**\n * Default fal.ai provider instance.\n */\nexport const fal = createFal();\n","import type { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertImageModelFileToDataUri,\n createBinaryResponseHandler,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n createStatusCodeErrorResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n resolve,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n type Resolvable,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalImageModelId, FalImageSize } from './fal-image-settings';\nimport { falImageModelOptionsSchema } from './fal-image-model-options';\n\ninterface FalImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalImageModel implements ImageModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxImagesPerCall = 1;\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalImageModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalImageModelId;\n config: FalImageModelConfig;\n }) {\n return new FalImageModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalImageModelId,\n private readonly config: FalImageModelConfig,\n ) {}\n\n private async getArgs({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n files,\n mask,\n }: Parameters<ImageModelV4['doGenerate']>[0]) {\n const warnings: Array<SharedV4Warning> = [];\n\n let imageSize: FalImageSize | undefined;\n if (size) {\n const [width, height] = size.split('x').map(Number);\n imageSize = { width, height };\n } else if (aspectRatio) {\n imageSize = convertAspectRatioToSize(aspectRatio);\n }\n\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falImageModelOptionsSchema,\n });\n\n const requestBody: Record<string, unknown> = {\n prompt,\n seed,\n image_size: imageSize,\n num_images: n,\n };\n\n // Handle image editing: convert files to image_url or image_urls\n if (files != null && files.length > 0) {\n const useMultipleImages = falOptions?.useMultipleImages === true;\n\n if (useMultipleImages) {\n // Use image_urls array for models that support multiple images (e.g., flux-2/edit)\n requestBody.image_urls = files.map(file =>\n convertImageModelFileToDataUri(file),\n );\n } else {\n // Use single image_url for standard image editing models\n requestBody.image_url = convertImageModelFileToDataUri(files[0]);\n\n if (files.length > 1) {\n warnings.push({\n type: 'other',\n message:\n 'Multiple input images provided but useMultipleImages is not enabled. ' +\n 'Only the first image will be used. Set providerOptions.fal.useMultipleImages ' +\n 'to true for models that support multiple images (e.g., fal-ai/flux-2/edit).',\n });\n }\n }\n }\n\n // Handle mask for inpainting\n if (mask != null) {\n requestBody.mask_url = convertImageModelFileToDataUri(mask);\n }\n\n if (falOptions) {\n const deprecatedKeys =\n '__deprecatedKeys' in falOptions\n ? (falOptions.__deprecatedKeys as string[])\n : undefined;\n\n if (deprecatedKeys && deprecatedKeys.length > 0) {\n warnings.push({\n type: 'other',\n message: `The following provider options use deprecated snake_case and will be removed in @ai-sdk/fal v2.0. Please use camelCase instead: ${deprecatedKeys\n .map(key => {\n const camelCase = key.replace(/_([a-z])/g, (_, letter) =>\n letter.toUpperCase(),\n );\n return `'${key}' (use '${camelCase}')`;\n })\n .join(', ')}`,\n });\n }\n\n const fieldMapping: Record<string, string> = {\n imageUrl: 'image_url',\n maskUrl: 'mask_url',\n guidanceScale: 'guidance_scale',\n numInferenceSteps: 'num_inference_steps',\n enableSafetyChecker: 'enable_safety_checker',\n outputFormat: 'output_format',\n syncMode: 'sync_mode',\n safetyTolerance: 'safety_tolerance',\n };\n\n for (const [key, value] of Object.entries(falOptions)) {\n if (key === '__deprecatedKeys') continue;\n if (key === 'useMultipleImages') continue; // Don't send to API\n const apiKey = fieldMapping[key] ?? key;\n\n if (value !== undefined) {\n requestBody[apiKey] = value;\n }\n }\n }\n\n return { requestBody, warnings } as const;\n }\n\n async doGenerate(\n options: Parameters<ImageModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {\n const { requestBody, warnings } = await this.getArgs(options);\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { value, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(\n this.config.headers ? await resolve(this.config.headers) : undefined,\n options.headers,\n ),\n body: requestBody,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n falImageResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const {\n images: targetImages,\n // prompt is just passed through and not a revised prompt per image\n prompt: _prompt,\n // NSFW information is normalized merged into `providerMetadata.fal.images`\n has_nsfw_concepts,\n nsfw_content_detected,\n // pass through other properties to providerMetadata\n ...responseMetaData\n } = value;\n\n // download the images:\n const downloadedImages = await Promise.all(\n targetImages.map(image =>\n this.downloadImage(image.url, options.abortSignal),\n ),\n );\n\n return {\n images: downloadedImages,\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n providerMetadata: {\n fal: {\n images: targetImages.map((image, index) => {\n const {\n url: _url,\n content_type: contentType,\n file_name: fileName,\n file_data: fileData,\n file_size: fileSize,\n ...imageMetaData\n } = image;\n\n const nsfw =\n has_nsfw_concepts?.[index] ?? nsfw_content_detected?.[index];\n\n return {\n ...imageMetaData,\n ...removeOnlyUndefined({\n contentType,\n fileName,\n fileData,\n fileSize,\n nsfw,\n }),\n };\n }),\n ...responseMetaData,\n },\n },\n };\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // url is a generated-image URL from the provider response; validate it.\n validateUrl: true,\n trustedOrigin: this.config.baseURL,\n // No specific headers should be needed for this request as it's a\n // generated image provided by fal.ai.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\nfunction removeOnlyUndefined<T extends Record<string, unknown>>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).filter(([, v]) => v !== undefined),\n ) as Partial<T>;\n}\n\n/**\n * Converts an aspect ratio to an image size compatible with fal.ai APIs.\n * @param aspectRatio - The aspect ratio to convert.\n * @returns The image size.\n */\nfunction convertAspectRatioToSize(\n aspectRatio: `${number}:${number}`,\n): FalImageSize | undefined {\n switch (aspectRatio) {\n case '1:1':\n return 'square_hd';\n case '16:9':\n return 'landscape_16_9';\n case '9:16':\n return 'portrait_16_9';\n case '4:3':\n return 'landscape_4_3';\n case '3:4':\n return 'portrait_4_3';\n case '16:10':\n return { width: 1280, height: 800 };\n case '10:16':\n return { width: 800, height: 1280 };\n case '21:9':\n return { width: 2560, height: 1080 };\n case '9:21':\n return { width: 1080, height: 2560 };\n }\n}\n\n// Validation error has a particular payload to inform the exact property that is invalid\nconst falValidationErrorSchema = z.object({\n detail: z.array(\n z.object({\n loc: z.array(z.string()),\n msg: z.string(),\n type: z.string(),\n }),\n ),\n});\n\ntype ValidationError = z.infer<typeof falValidationErrorSchema>;\n\n// Other errors have a message property\nconst falHttpErrorSchema = z.object({\n message: z.string(),\n});\n\nconst falErrorSchema = z.union([falValidationErrorSchema, falHttpErrorSchema]);\n\nconst falImageSchema = z.object({\n url: z.string(),\n width: z.number().nullish(),\n height: z.number().nullish(),\n // e.g. https://fal.ai/models/fal-ai/fashn/tryon/v1.6/api#schema-output\n content_type: z.string().nullish(),\n // e.g. https://fal.ai/models/fal-ai/flowedit/api#schema-output\n file_name: z.string().nullish(),\n file_data: z.string().optional(),\n file_size: z.number().nullish(),\n});\n\n// https://fal.ai/models/fal-ai/lora/api#type-File\nconst loraFileSchema = z.object({\n url: z.string(),\n content_type: z.string().optional(),\n file_name: z.string().nullable().optional(),\n file_data: z.string().optional(),\n file_size: z.number().nullable().optional(),\n});\n\nconst commonResponseSchema = z.object({\n timings: z\n .object({\n inference: z.number().optional(),\n })\n .optional(),\n seed: z.number().optional(),\n has_nsfw_concepts: z.array(z.boolean()).optional(),\n prompt: z.string().optional(),\n // https://fal.ai/models/fal-ai/lcm/api#schema-output\n nsfw_content_detected: z.array(z.boolean()).optional(),\n num_inference_steps: z.number().optional(),\n // https://fal.ai/models/fal-ai/lora/api#schema-output\n debug_latents: loraFileSchema.optional(),\n debug_per_pass_latents: loraFileSchema.optional(),\n});\n\n// Most FAL image models respond with an array of images, but some have a response\n// with a single image, e.g. https://fal.ai/models/easel-ai/easel-avatar/api#schema-output\nconst base = z.looseObject(commonResponseSchema.shape);\nconst falImageResponseSchema = z\n .union([\n base.extend({ images: z.array(falImageSchema) }),\n base.extend({ image: falImageSchema }),\n ])\n .transform(v => ('images' in v ? v : { ...v, images: [v.image] }))\n .pipe(base.extend({ images: z.array(falImageSchema) }));\n\nfunction isValidationError(error: unknown): error is ValidationError {\n return falValidationErrorSchema.safeParse(error).success;\n}\n\nconst falFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: falErrorSchema,\n errorToMessage: error => {\n if (isValidationError(error)) {\n return error.detail\n .map(detail => `${detail.loc.join('.')}: ${detail.msg}`)\n .join('\\n');\n }\n return error.message ?? 'Unknown fal error';\n },\n});\n","import {\n lazySchema,\n zodSchema,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nexport const falImageModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z\n .looseObject({\n /** @deprecated use prompt.images instead */\n imageUrl: z.string().nullish().meta({\n deprecated: true,\n description: 'Use `prompt.images` instead',\n }),\n maskUrl: z\n .string()\n .nullish()\n .meta({ deprecated: true, description: 'Use `prompt.mask` instead' }),\n guidanceScale: z.number().min(1).max(20).nullish(),\n numInferenceSteps: z.number().min(1).max(50).nullish(),\n enableSafetyChecker: z.boolean().nullish(),\n outputFormat: z.enum(['jpeg', 'png']).nullish(),\n syncMode: z.boolean().nullish(),\n strength: z.number().nullish(),\n acceleration: z.enum(['none', 'regular', 'high']).nullish(),\n safetyTolerance: z\n .enum(['1', '2', '3', '4', '5', '6'])\n .or(z.number().min(1).max(6))\n .nullish(),\n /**\n * When true, converts multiple input images to `image_urls` array instead of `image_url` string.\n */\n useMultipleImages: z.boolean().nullish(),\n\n // Deprecated snake_case versions\n image_url: z.string().nullish(),\n mask_url: z.string().nullish(),\n guidance_scale: z.number().min(1).max(20).nullish(),\n num_inference_steps: z.number().min(1).max(50).nullish(),\n enable_safety_checker: z.boolean().nullish(),\n output_format: z.enum(['jpeg', 'png']).nullish(),\n sync_mode: z.boolean().nullish(),\n safety_tolerance: z\n .enum(['1', '2', '3', '4', '5', '6'])\n .or(z.number().min(1).max(6))\n .nullish(),\n })\n .transform(data => {\n const result: Record<string, unknown> = {};\n const deprecatedKeys: string[] = [];\n\n const mapKey = (snakeKey: string, camelKey: string) => {\n const snakeValue = data[snakeKey as keyof typeof data];\n const camelValue = data[camelKey as keyof typeof data];\n\n // If snake_case is used, mark it as deprecated\n if (snakeValue !== undefined && snakeValue !== null) {\n deprecatedKeys.push(snakeKey);\n result[camelKey] = snakeValue;\n } else if (camelValue !== undefined && camelValue !== null) {\n result[camelKey] = camelValue;\n }\n };\n\n // Map all known parameters\n mapKey('image_url', 'imageUrl');\n mapKey('mask_url', 'maskUrl');\n mapKey('guidance_scale', 'guidanceScale');\n mapKey('num_inference_steps', 'numInferenceSteps');\n mapKey('enable_safety_checker', 'enableSafetyChecker');\n mapKey('output_format', 'outputFormat');\n mapKey('sync_mode', 'syncMode');\n mapKey('safety_tolerance', 'safetyTolerance');\n\n // These don't have snake_case equivalents\n if (data.strength !== undefined && data.strength !== null) {\n result.strength = data.strength;\n }\n if (data.acceleration !== undefined && data.acceleration !== null) {\n result.acceleration = data.acceleration;\n }\n if (\n data.useMultipleImages !== undefined &&\n data.useMultipleImages !== null\n ) {\n result.useMultipleImages = data.useMultipleImages;\n }\n\n for (const [key, value] of Object.entries(data)) {\n if (\n ![\n // camelCase known keys\n 'imageUrl',\n 'maskUrl',\n 'guidanceScale',\n 'numInferenceSteps',\n 'enableSafetyChecker',\n 'outputFormat',\n 'syncMode',\n 'strength',\n 'acceleration',\n 'safetyTolerance',\n 'useMultipleImages',\n // snake_case known keys\n 'image_url',\n 'mask_url',\n 'guidance_scale',\n 'num_inference_steps',\n 'enable_safety_checker',\n 'output_format',\n 'sync_mode',\n 'safety_tolerance',\n ].includes(key)\n ) {\n result[key] = value;\n }\n }\n\n if (deprecatedKeys.length > 0) {\n (result as any).__deprecatedKeys = deprecatedKeys;\n }\n\n return result;\n }),\n ),\n);\n\nexport type FalImageModelOptions = InferSchema<\n typeof falImageModelOptionsSchema\n>;\n","import {\n AISDKError,\n type TranscriptionModelV4,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertUint8ArrayToBase64,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n delay,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falErrorDataSchema, falFailedResponseHandler } from './fal-error';\nimport { falTranscriptionModelOptionsSchema } from './fal-transcription-model-options';\nimport type { FalTranscriptionModelId } from './fal-transcription-options';\nimport type { FalTranscriptionAPITypes } from './fal-api-types';\n\ninterface FalTranscriptionModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalTranscriptionModel implements TranscriptionModelV4 {\n readonly specificationVersion = 'v4';\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalTranscriptionModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalTranscriptionModelId;\n config: FalTranscriptionModelConfig;\n }) {\n return new FalTranscriptionModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalTranscriptionModelId,\n private readonly config: FalTranscriptionModelConfig,\n ) {}\n\n private async getArgs({\n providerOptions,\n }: Parameters<TranscriptionModelV4['doGenerate']>[0]) {\n const warnings: SharedV4Warning[] = [];\n\n // Parse provider options\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falTranscriptionModelOptionsSchema,\n });\n\n // Create form data with base fields\n const body: Omit<FalTranscriptionAPITypes, 'audio_url'> = {\n task: 'transcribe',\n diarize: true,\n chunk_level: 'word',\n };\n\n // Add provider-specific options\n if (falOptions) {\n body.language = falOptions.language as never;\n body.version = falOptions.version ?? undefined;\n body.batch_size = falOptions.batchSize ?? undefined;\n body.num_speakers = falOptions.numSpeakers ?? undefined;\n\n if (typeof falOptions.diarize === 'boolean') {\n body.diarize = falOptions.diarize;\n }\n\n if (falOptions.chunkLevel) {\n body.chunk_level = falOptions.chunkLevel;\n }\n }\n\n return {\n body,\n warnings,\n };\n }\n\n async doGenerate(\n options: Parameters<TranscriptionModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<TranscriptionModelV4['doGenerate']>>> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { body, warnings } = await this.getArgs(options);\n\n const base64Audio =\n typeof options.audio === 'string'\n ? options.audio\n : convertUint8ArrayToBase64(options.audio);\n\n const audioUrl = `data:${options.mediaType};base64,${base64Audio}`;\n\n const { value: queueResponse } = await postJsonToApi({\n url: this.config.url({\n path: `https://queue.fal.run/fal-ai/${this.modelId}`,\n modelId: this.modelId,\n }),\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body: {\n ...body,\n audio_url: audioUrl,\n },\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler:\n createJsonResponseHandler(falJobResponseSchema),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n // Poll for completion with timeout\n const startTime = Date.now();\n const timeoutMs = 60000; // 60 seconds timeout\n const pollIntervalMs = 1000; // 1 second interval\n\n let response;\n let responseHeaders;\n let rawResponse;\n\n while (true) {\n try {\n const {\n value: statusResponse,\n responseHeaders: statusHeaders,\n rawValue: statusRawResponse,\n } = await getFromApi({\n url: this.config.url({\n path: `https://queue.fal.run/fal-ai/${this.modelId}/requests/${queueResponse.request_id}`,\n modelId: this.modelId,\n }),\n validateUrl: false,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n failedResponseHandler: async ({\n requestBodyValues,\n response,\n url,\n }) => {\n const clone = response.clone();\n const body = (await clone.json()) as { detail: string };\n\n if (body.detail === 'Request is still in progress') {\n // This is not an error, just a status update that the request is still processing\n // Continue polling by returning a special error that signals to continue\n return {\n value: new Error('Request is still in progress'),\n rawValue: body,\n responseHeaders: {},\n };\n }\n\n return createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n })({ requestBodyValues, response, url });\n },\n successfulResponseHandler: createJsonResponseHandler(\n falTranscriptionResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n response = statusResponse;\n responseHeaders = statusHeaders;\n rawResponse = statusRawResponse;\n break;\n } catch (error) {\n // If the error message indicates the request is still in progress, ignore it and continue polling\n if (\n error instanceof Error &&\n error.message === 'Request is still in progress'\n ) {\n // Continue with the polling loop\n } else {\n // Re-throw any other errors\n throw error;\n }\n }\n\n // Check if we've exceeded the timeout\n if (Date.now() - startTime > timeoutMs) {\n throw new AISDKError({\n message: 'Transcription request timed out after 60 seconds',\n name: 'TranscriptionRequestTimedOut',\n cause: response,\n });\n }\n\n // Wait before polling again\n await delay(pollIntervalMs);\n }\n\n return {\n text: response.text,\n segments:\n response.chunks?.map(chunk => ({\n text: chunk.text,\n startSecond: chunk.timestamp?.at(0) ?? 0,\n endSecond: chunk.timestamp?.at(1) ?? 0,\n })) ?? [],\n language: response.inferred_languages?.at(0) ?? undefined,\n durationInSeconds: response.chunks?.at(-1)?.timestamp?.at(1) ?? undefined,\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n body: rawResponse,\n },\n };\n }\n}\n\nconst falJobResponseSchema = z.object({\n request_id: z.string().nullish(),\n});\n\nconst falTranscriptionResponseSchema = z.object({\n text: z.string(),\n chunks: z\n .array(\n z.object({\n text: z.string(),\n timestamp: z.array(z.number()).nullish(),\n }),\n )\n .nullish(),\n inferred_languages: z.array(z.string()).nullish(),\n});\n","import { z } from 'zod/v4';\nimport { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\n\nexport const falErrorDataSchema = z.object({\n error: z.object({\n message: z.string(),\n code: z.number(),\n }),\n});\n\nexport type FalErrorData = z.infer<typeof falErrorDataSchema>;\n\nexport const falFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n});\n","import { z } from 'zod/v4';\n\n// https://fal.ai/models/fal-ai/whisper/api?platform=http\nexport const falTranscriptionModelOptionsSchema = z.object({\n /**\n * Language of the audio file. If set to null, the language will be automatically detected. Defaults to null.\n *\n * If translate is selected as the task, the audio will be translated to English, regardless of the language selected.\n */\n language: z\n .union([z.enum(['en']), z.string()])\n .nullish()\n .default('en'),\n\n /**\n * Whether to diarize the audio file. Defaults to true.\n */\n diarize: z.boolean().nullish().default(true),\n\n /**\n * Level of the chunks to return. Either segment or word. Default value: \"segment\"\n */\n chunkLevel: z.enum(['segment', 'word']).nullish().default('segment'),\n\n /**\n * Version of the model to use. All of the models are the Whisper large variant. Default value: \"3\"\n */\n version: z.enum(['3']).nullish().default('3'),\n\n /**\n * Default value: 64\n */\n batchSize: z.number().nullish().default(64),\n\n /**\n * Number of speakers in the audio file. Defaults to null. If not provided, the number of speakers will be automatically detected.\n */\n numSpeakers: z.number().nullable().nullish(),\n});\n\nexport type FalTranscriptionModelOptions = z.infer<\n typeof falTranscriptionModelOptionsSchema\n>;\n","import type { SpeechModelV4, SharedV4Warning } from '@ai-sdk/provider';\nimport {\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createStatusCodeErrorResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falFailedResponseHandler } from './fal-error';\nimport { falSpeechModelOptionsSchema } from './fal-speech-model-options';\nimport type { FalSpeechModelId } from './fal-speech-settings';\n\ninterface FalSpeechModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalSpeechModel implements SpeechModelV4 {\n readonly specificationVersion = 'v4';\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalSpeechModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalSpeechModelId;\n config: FalSpeechModelConfig;\n }) {\n return new FalSpeechModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalSpeechModelId,\n private readonly config: FalSpeechModelConfig,\n ) {}\n\n private async getArgs({\n text,\n voice,\n outputFormat,\n speed,\n language,\n providerOptions,\n }: Parameters<SpeechModelV4['doGenerate']>[0]) {\n const warnings: SharedV4Warning[] = [];\n\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falSpeechModelOptionsSchema,\n });\n\n const requestBody = {\n text,\n output_format: outputFormat === 'hex' ? 'hex' : 'url',\n voice,\n speed,\n ...falOptions,\n };\n\n // Language is not directly supported; warn and ignore\n if (language) {\n warnings.push({\n type: 'unsupported',\n feature: 'language',\n details:\n \"fal speech models don't support 'language' directly; consider providerOptions.fal.language_boost\",\n });\n }\n\n // warn on invalid values (and on hex until we support hex response handling)\n if (outputFormat && outputFormat !== 'url' && outputFormat !== 'hex') {\n warnings.push({\n type: 'unsupported',\n feature: 'outputFormat',\n details: `Unsupported outputFormat: ${outputFormat}. Using 'url' instead.`,\n });\n }\n\n return { requestBody, warnings } as const;\n }\n\n async doGenerate(\n options: Parameters<SpeechModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<SpeechModelV4['doGenerate']>>> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { requestBody, warnings } = await this.getArgs(options);\n\n const requestUrl = this.config.url({\n path: `https://fal.run/${this.modelId}`,\n modelId: this.modelId,\n });\n\n const {\n value: json,\n responseHeaders,\n rawValue,\n } = await postJsonToApi({\n url: requestUrl,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body: requestBody,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n falSpeechResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const audioUrl = json.audio.url;\n const { value: audio } = await getFromApi({\n url: audioUrl,\n // audioUrl comes from the provider response body; validate it.\n validateUrl: true,\n trustedOrigin: requestUrl,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n audio,\n warnings,\n request: {\n body: JSON.stringify(requestBody),\n },\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n body: rawValue,\n },\n };\n }\n}\n\nconst falSpeechResponseSchema = z.object({\n audio: z.object({ url: z.string() }),\n duration_ms: z.number().optional(),\n request_id: z.string().optional(),\n});\n","import { z } from 'zod/v4';\nimport { FAL_EMOTIONS, FAL_LANGUAGE_BOOSTS } from './fal-api-types';\n\nexport const falSpeechModelOptionsSchema = z.looseObject({\n voice_setting: z\n .object({\n speed: z.number().nullish(),\n vol: z.number().nullish(),\n voice_id: z.string().nullish(),\n pitch: z.number().nullish(),\n english_normalization: z.boolean().nullish(),\n emotion: z.enum(FAL_EMOTIONS).nullish(),\n })\n .partial()\n .nullish(),\n audio_setting: z.record(z.string(), z.unknown()).nullish(),\n language_boost: z.enum(FAL_LANGUAGE_BOOSTS).nullish(),\n pronunciation_dict: z.record(z.string(), z.string()).nullish(),\n});\n\nexport type FalSpeechModelOptions = z.infer<typeof falSpeechModelOptionsSchema>;\n","export type FalTranscriptionAPITypes = {\n /**\n * URL of the audio file to transcribe. Supported formats: mp3, mp4, mpeg, mpga, m4a, wav or webm.\n */\n audio_url: string;\n\n /**\n * Task to perform on the audio file. Either transcribe or translate. Default value: \"transcribe\"\n */\n task?: 'transcribe' | 'translate';\n\n /**\n * Language of the audio file. If set to null, the language will be automatically detected. Defaults to null.\n *\n * If translate is selected as the task, the audio will be translated to English, regardless of the language selected.\n */\n language?:\n | 'af'\n | 'am'\n | 'ar'\n | 'as'\n | 'az'\n | 'ba'\n | 'be'\n | 'bg'\n | 'bn'\n | 'bo'\n | 'br'\n | 'bs'\n | 'ca'\n | 'cs'\n | 'cy'\n | 'da'\n | 'de'\n | 'el'\n | 'en'\n | 'es'\n | 'et'\n | 'eu'\n | 'fa'\n | 'fi'\n | 'fo'\n | 'fr'\n | 'gl'\n | 'gu'\n | 'ha'\n | 'haw'\n | 'he'\n | 'hi'\n | 'hr'\n | 'ht'\n | 'hu'\n | 'hy'\n | 'id'\n | 'is'\n | 'it'\n | 'ja'\n | 'jw'\n | 'ka'\n | 'kk'\n | 'km'\n | 'kn'\n | 'ko'\n | 'la'\n | 'lb'\n | 'ln'\n | 'lo'\n | 'lt'\n | 'lv'\n | 'mg'\n | 'mi'\n | 'mk'\n | 'ml'\n | 'mn'\n | 'mr'\n | 'ms'\n | 'mt'\n | 'my'\n | 'ne'\n | 'nl'\n | 'nn'\n | 'no'\n | 'oc'\n | 'pa'\n | 'pl'\n | 'ps'\n | 'pt'\n | 'ro'\n | 'ru'\n | 'sa'\n | 'sd'\n | 'si'\n | 'sk'\n | 'sl'\n | 'sn'\n | 'so'\n | 'sq'\n | 'sr'\n | 'su'\n | 'sv'\n | 'sw'\n | 'ta'\n | 'te'\n | 'tg'\n | 'th'\n | 'tk'\n | 'tl'\n | 'tr'\n | 'tt'\n | 'uk'\n | 'ur'\n | 'uz'\n | 'vi'\n | 'yi'\n | 'yo'\n | 'yue'\n | 'zh'\n | null;\n\n /**\n * Whether to diarize the audio file. Defaults to true.\n */\n diarize?: boolean;\n\n /**\n * Level of the chunks to return. Either segment or word. Default value: \"segment\"\n */\n chunk_level?: 'segment' | 'word';\n\n /**\n * Version of the model to use. All of the models are the Whisper large variant. Default value: \"3\"\n */\n version?: '3';\n\n /**\n * Default value: 64\n */\n batch_size?: number;\n\n /**\n * Prompt to use for generation. Defaults to an empty string. Default value: \"\"\n */\n prompt?: string;\n\n /**\n * Number of speakers in the audio file. Defaults to null. If not provided, the number of speakers will be automatically detected.\n */\n num_speakers?: number | null;\n};\n\nexport const FAL_LANGUAGE_BOOSTS = [\n 'Chinese',\n 'Chinese,Yue',\n 'English',\n 'Arabic',\n 'Russian',\n 'Spanish',\n 'French',\n 'Portuguese',\n 'German',\n 'Turkish',\n 'Dutch',\n 'Ukrainian',\n 'Vietnamese',\n 'Indonesian',\n 'Japanese',\n 'Italian',\n 'Korean',\n 'Thai',\n 'Polish',\n 'Romanian',\n 'Greek',\n 'Czech',\n 'Finnish',\n 'Hindi',\n 'auto',\n] as const;\nexport type FalLanguageBoost = (typeof FAL_LANGUAGE_BOOSTS)[number];\n\nexport const FAL_EMOTIONS = [\n 'happy',\n 'sad',\n 'angry',\n 'fearful',\n 'disgusted',\n 'surprised',\n 'neutral',\n] as const;\nexport type FalEmotion = (typeof FAL_EMOTIONS)[number];\n","import {\n AISDKError,\n APICallError,\n type Experimental_VideoModelV4 as VideoModelV4,\n type Experimental_VideoModelV4OperationStartResult as VideoModelV4OperationStartResult,\n type Experimental_VideoModelV4OperationStatusResult as VideoModelV4OperationStatusResult,\n type SharedV4ProviderMetadata,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertImageModelFileToDataUri,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falErrorDataSchema, falFailedResponseHandler } from './fal-error';\nimport {\n falVideoModelOptionsSchema,\n type FalVideoModelOptions,\n} from './fal-video-model-options';\nimport type { FalVideoModelId } from './fal-video-settings';\n\ninterface FalVideoModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalVideoModel implements VideoModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxVideosPerCall = 1; // FAL video models support 1 video at a time\n\n get provider(): string {\n return this.config.provider;\n }\n\n private get normalizedModelId(): string {\n return this.modelId.replace(/^fal-ai\\//, '').replace(/^fal\\//, '');\n }\n\n constructor(\n readonly modelId: FalVideoModelId,\n private readonly config: FalVideoModelConfig,\n ) {}\n\n async handleWebhookOption(\n options: Parameters<NonNullable<VideoModelV4['handleWebhookOption']>>[0],\n ) {\n const { url, received } = await options.webhook();\n return { webhookUrl: url, received };\n }\n\n async doStart(\n options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],\n ): Promise<VideoModelV4OperationStartResult> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const warnings: SharedV4Warning[] = [];\n\n const { body } = await this.buildRequestBody(options);\n\n const { responseUrl, submitUrl } = await this.submitToQueue(\n {\n headers: options.headers,\n abortSignal: options.abortSignal,\n webhookUrl: options.webhookUrl,\n },\n body,\n );\n\n return {\n operation: { responseUrl, submitUrl },\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: undefined,\n },\n };\n }\n\n async doStatus(\n options: Parameters<NonNullable<VideoModelV4['doStatus']>>[0],\n ): Promise<VideoModelV4OperationStatusResult> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { responseUrl, submitUrl } = options.operation as {\n responseUrl: string;\n submitUrl: string;\n };\n\n try {\n const { value: response, responseHeaders } = await this.fetchStatus({\n responseUrl,\n submitUrl,\n headers: options.headers,\n abortSignal: options.abortSignal,\n });\n\n return this.buildResult({\n response,\n responseHeaders,\n warnings: [],\n currentDate,\n });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message === 'Request is still in progress'\n ) {\n return {\n status: 'pending' as const,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: undefined,\n },\n };\n }\n\n if (APICallError.isInstance(error)) {\n return {\n status: 'error' as const,\n error: error.message,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: error.responseHeaders,\n },\n };\n }\n\n throw error;\n }\n }\n\n private async buildRequestBody(\n options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],\n ): Promise<{\n body: Record<string, unknown>;\n falOptions: FalVideoModelOptions | undefined;\n }> {\n const falOptions = (await parseProviderOptions({\n provider: 'fal',\n providerOptions: options.providerOptions,\n schema: falVideoModelOptionsSchema,\n })) as FalVideoModelOptions | undefined;\n\n const body: Record<string, unknown> = {};\n\n if (options.prompt != null) {\n body.prompt = options.prompt;\n }\n\n if (options.image != null) {\n if (options.image.type === 'url') {\n body.image_url = options.image.url;\n } else {\n body.image_url = convertImageModelFileToDataUri(options.image);\n }\n }\n\n if (options.aspectRatio) {\n body.aspect_ratio = options.aspectRatio;\n }\n\n if (options.duration) {\n body.duration = `${options.duration}s`;\n }\n\n if (options.seed) {\n body.seed = options.seed;\n }\n\n if (falOptions != null) {\n const opts = falOptions;\n if (opts.loop !== undefined && opts.loop !== null) {\n body.loop = opts.loop;\n }\n if (opts.motionStrength !== undefined && opts.motionStrength !== null) {\n body.motion_strength = opts.motionStrength;\n }\n if (opts.resolution !== undefined && opts.resolution !== null) {\n body.resolution = opts.resolution;\n }\n if (opts.negativePrompt !== undefined && opts.negativePrompt !== null) {\n body.negative_prompt = opts.negativePrompt;\n }\n if (opts.promptOptimizer !== undefined && opts.promptOptimizer !== null) {\n body.prompt_optimizer = opts.promptOptimizer;\n }\n\n for (const [key, value] of Object.entries(opts)) {\n if (\n ![\n 'loop',\n 'motionStrength',\n 'resolution',\n 'negativePrompt',\n 'promptOptimizer',\n ].includes(key)\n ) {\n body[key] = value;\n }\n }\n }\n\n return { body, falOptions };\n }\n\n private async submitToQueue(\n options: {\n headers?: Record<string, string | undefined>;\n abortSignal?: AbortSignal;\n webhookUrl?: string;\n },\n body: Record<string, unknown>,\n ): Promise<{ responseUrl: string; submitUrl: string }> {\n let queuePath = `https://queue.fal.run/fal-ai/${this.normalizedModelId}`;\n if (options.webhookUrl) {\n queuePath += `?fal_webhook=${encodeURIComponent(options.webhookUrl)}`;\n }\n\n const submitUrl = this.config.url({\n path: queuePath,\n modelId: this.modelId,\n });\n const { value: queueResponse } = await postJsonToApi({\n url: submitUrl,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler:\n createJsonResponseHandler(falJobResponseSchema),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const responseUrl = queueResponse.response_url;\n if (!responseUrl) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_ERROR',\n message: 'No response URL returned from queue endpoint',\n });\n }\n\n return { responseUrl, submitUrl };\n }\n\n private async fetchStatus({\n responseUrl,\n submitUrl,\n headers,\n abortSignal,\n }: {\n responseUrl: string;\n submitUrl: string;\n headers?: Record<string, string | undefined>;\n abortSignal?: AbortSignal;\n }): Promise<{\n value: FalVideoResponse;\n responseHeaders?: Record<string, string>;\n }> {\n const statusUrl = this.config.url({\n path: responseUrl,\n modelId: this.modelId,\n });\n\n return getFromApi({\n url: statusUrl,\n // statusUrl comes from the queue response body.\n validateUrl: true,\n credentialedOrigin: submitUrl,\n trustedOrigin: submitUrl,\n headers: combineHeaders(this.config.headers?.(), headers),\n failedResponseHandler: async ({ response, url, requestBodyValues }) => {\n const body = await response.clone().json();\n\n if (body.detail === 'Request is still in progress') {\n return {\n value: new Error('Request is still in progress'),\n rawValue: body,\n responseHeaders: {},\n };\n }\n\n return createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n })({ response, url, requestBodyValues });\n },\n successfulResponseHandler: createJsonResponseHandler(\n falVideoResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n }\n\n private buildResult({\n response,\n responseHeaders,\n warnings,\n currentDate,\n }: {\n response: FalVideoResponse;\n responseHeaders?: Record<string, string>;\n warnings: SharedV4Warning[];\n currentDate: Date;\n }): {\n status: 'completed';\n videos: Array<{ type: 'url'; url: string; mediaType: string }>;\n warnings: SharedV4Warning[];\n providerMetadata: SharedV4ProviderMetadata;\n response: {\n timestamp: Date;\n modelId: string;\n headers: Record<string, string> | undefined;\n };\n } {\n const videoUrl = response.video?.url;\n\n if (!videoUrl || !response.video) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_ERROR',\n message: 'No video URL in response',\n });\n }\n\n return {\n status: 'completed',\n videos: [\n {\n type: 'url',\n url: videoUrl,\n mediaType: response.video.content_type || 'video/mp4',\n },\n ],\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n providerMetadata: {\n fal: {\n videos: [\n {\n url: videoUrl,\n width: response.video.width,\n height: response.video.height,\n duration: response.video.duration,\n fps: response.video.fps,\n contentType: response.video.content_type,\n },\n ],\n ...(response.seed !== undefined ? { seed: response.seed } : {}),\n ...(response.timings ? { timings: response.timings } : {}),\n ...(response.has_nsfw_concepts !== undefined\n ? { has_nsfw_concepts: response.has_nsfw_concepts }\n : {}),\n ...(response.prompt ? { prompt: response.prompt } : {}),\n },\n },\n };\n }\n}\n\nconst falJobResponseSchema = z.object({\n request_id: z.string().nullish(),\n response_url: z.string().nullish(),\n});\n\nconst falVideoResponseSchema = z.object({\n video: z\n .object({\n url: z.string(),\n width: z.number().nullish(),\n height: z.number().nullish(),\n duration: z.number().nullish(),\n fps: z.number().nullish(),\n content_type: z.string().nullish(),\n })\n .nullish(),\n seed: z.number().nullish(),\n timings: z\n .object({\n inference: z.number().nullish(),\n })\n .nullish(),\n has_nsfw_concepts: z.array(z.boolean()).nullish(),\n prompt: z.string().nullish(),\n});\n\ntype FalVideoResponse = z.infer<typeof falVideoResponseSchema>;\n","import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nexport type FalVideoModelOptions = {\n loop?: boolean | null;\n motionStrength?: number | null;\n resolution?: string | null;\n negativePrompt?: string | null;\n promptOptimizer?: boolean | null;\n [key: string]: unknown; // For passthrough\n};\n\n// Provider options schema for FAL video generation\nexport const falVideoModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z.looseObject({\n // Video loop - only for Luma models\n loop: z.boolean().nullish(),\n\n // Motion strength (provider-specific)\n motionStrength: z.number().min(0).max(1).nullish(),\n\n // Resolution (model-specific, e.g., '480p', '720p', '1080p')\n resolution: z.string().nullish(),\n\n // Model-specific parameters\n negativePrompt: z.string().nullish(),\n promptOptimizer: z.boolean().nullish(),\n }),\n ),\n);\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["z","_a","z","combineHeaders","createJsonErrorResponseHandler","createJsonResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","serializeModelOptions","WORKFLOW_SERIALIZE","WORKFLOW_DESERIALIZE","z","z","createJsonErrorResponseHandler","falFailedResponseHandler","z","WORKFLOW_SERIALIZE","serializeModelOptions","WORKFLOW_DESERIALIZE","parseProviderOptions","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","getFromApi","response","body","createJsonErrorResponseHandler","_a","_b","_c","_d","z","combineHeaders","createBinaryResponseHandler","createJsonResponseHandler","createStatusCodeErrorResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","serializeModelOptions","WORKFLOW_SERIALIZE","WORKFLOW_DESERIALIZE","z","z","z","WORKFLOW_SERIALIZE","serializeModelOptions","WORKFLOW_DESERIALIZE","parseProviderOptions","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","getFromApi","createStatusCodeErrorResponseHandler","createBinaryResponseHandler","z","AISDKError","combineHeaders","convertImageModelFileToDataUri","createJsonErrorResponseHandler","createJsonResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","z","lazySchema","zodSchema","z","parseProviderOptions","convertImageModelFileToDataUri","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","falJobResponseSchema","AISDKError","getFromApi","createJsonErrorResponseHandler","z"]}
1
+ {"version":3,"sources":["../src/fal-provider.ts","../src/fal-image-model.ts","../src/fal-image-model-options.ts","../src/fal-transcription-model.ts","../src/fal-error.ts","../src/fal-transcription-model-options.ts","../src/fal-speech-model.ts","../src/fal-speech-model-options.ts","../src/fal-api-types.ts","../src/fal-video-model.ts","../src/fal-video-model-options.ts","../src/version.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type Experimental_VideoModelV4,\n type ImageModelV4,\n type ProviderV4,\n type SpeechModelV4,\n type TranscriptionModelV4,\n} from '@ai-sdk/provider';\nimport {\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { FalImageModel } from './fal-image-model';\nimport type { FalImageModelId } from './fal-image-settings';\nimport type { FalTranscriptionModelId } from './fal-transcription-options';\nimport { FalTranscriptionModel } from './fal-transcription-model';\nimport type { FalSpeechModelId } from './fal-speech-settings';\nimport { FalSpeechModel } from './fal-speech-model';\nimport { FalVideoModel } from './fal-video-model';\nimport type { FalVideoModelId } from './fal-video-settings';\nimport { VERSION } from './version';\n\nexport interface FalProviderSettings {\n /**\n * fal.ai API key. Default value is taken from the `FAL_API_KEY` environment\n * variable, falling back to `FAL_KEY`.\n */\n apiKey?: string;\n\n /**\n * Base URL for the API calls.\n * The default prefix is `https://fal.run`.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept\n * requests, or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface FalProvider extends ProviderV4 {\n /**\n * Creates a model for image generation.\n */\n image(modelId: FalImageModelId): ImageModelV4;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: FalImageModelId): ImageModelV4;\n\n /**\n * Creates a model for transcription.\n */\n transcription(modelId: FalTranscriptionModelId): TranscriptionModelV4;\n\n /**\n * Creates a model for video generation.\n */\n video(modelId: FalVideoModelId): Experimental_VideoModelV4;\n\n /**\n * Creates a model for video generation.\n */\n videoModel(modelId: FalVideoModelId): Experimental_VideoModelV4;\n\n /**\n * Creates a model for speech generation.\n */\n speech(modelId: FalSpeechModelId): SpeechModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n}\n\nconst defaultBaseURL = 'https://fal.run';\n\nfunction loadFalApiKey({\n apiKey,\n description = 'fal.ai',\n}: {\n apiKey: string | undefined;\n description?: string;\n}): string {\n if (typeof apiKey === 'string') {\n return apiKey;\n }\n\n if (apiKey != null) {\n throw new Error(`${description} API key must be a string.`);\n }\n\n if (typeof process === 'undefined') {\n throw new Error(\n `${description} API key is missing. Pass it using the 'apiKey' parameter. Environment variables are not supported in this environment.`,\n );\n }\n\n let envApiKey = process.env.FAL_API_KEY;\n if (envApiKey == null) {\n envApiKey = process.env.FAL_KEY;\n }\n\n if (envApiKey == null) {\n throw new Error(\n `${description} API key is missing. Pass it using the 'apiKey' parameter or set either the FAL_API_KEY or FAL_KEY environment variable.`,\n );\n }\n\n if (typeof envApiKey !== 'string') {\n throw new Error(\n `${description} API key must be a string. The value of the environment variable is not a string.`,\n );\n }\n\n return envApiKey;\n}\n\n/**\n * Create a fal.ai provider instance.\n */\nexport function createFal(options: FalProviderSettings = {}): FalProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Key ${loadFalApiKey({\n apiKey: options.apiKey,\n })}`,\n ...options.headers,\n },\n `ai-sdk/fal/${VERSION}`,\n );\n\n const createImageModel = (modelId: FalImageModelId) =>\n new FalImageModel(modelId, {\n provider: 'fal.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createSpeechModel = (modelId: FalSpeechModelId) =>\n new FalSpeechModel(modelId, {\n provider: `fal.speech`,\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createTranscriptionModel = (modelId: FalTranscriptionModelId) =>\n new FalTranscriptionModel(modelId, {\n provider: `fal.transcription`,\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createVideoModel = (modelId: FalVideoModelId) =>\n new FalVideoModel(modelId, {\n provider: 'fal.video',\n url: ({ path }) => path,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'embeddingModel',\n });\n };\n\n return {\n specificationVersion: 'v4' as const,\n imageModel: createImageModel,\n image: createImageModel,\n languageModel: (modelId: string) => {\n throw new NoSuchModelError({\n modelId,\n modelType: 'languageModel',\n });\n },\n speech: createSpeechModel,\n embeddingModel,\n textEmbeddingModel: embeddingModel,\n transcription: createTranscriptionModel,\n video: createVideoModel,\n videoModel: createVideoModel,\n };\n}\n\n/**\n * Default fal.ai provider instance.\n */\nexport const fal = createFal();\n","import type { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertImageModelFileToDataUri,\n createBinaryResponseHandler,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n createStatusCodeErrorResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n resolve,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n type Resolvable,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalImageModelId, FalImageSize } from './fal-image-settings';\nimport { falImageModelOptionsSchema } from './fal-image-model-options';\n\ninterface FalImageModelConfig {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalImageModel implements ImageModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxImagesPerCall = 1;\n\n get supportsFileInputs(): boolean | undefined {\n if (\n [\n 'fal-ai/flux-2/edit',\n 'fal-ai/flux-pro/kontext',\n 'fal-ai/flux-pro/kontext/max',\n 'fal-ai/flux-general/image-to-image',\n 'fal-ai/flux-general/inpainting',\n 'fal-ai/flux-lora/image-to-image',\n 'fal-ai/flux-lora/inpainting',\n 'fal-ai/flux/dev/image-to-image',\n 'fal-ai/flux/krea/image-to-image',\n 'fal-ai/recraft/v3/image-to-image',\n ].includes(this.modelId)\n ) {\n return true;\n }\n\n return [\n 'bria/text-to-image/3.2',\n 'fal-ai/bria/text-to-image/base',\n 'fal-ai/bria/text-to-image/fast',\n 'fal-ai/bria/text-to-image/hd',\n 'fal-ai/bytedance/dreamina/v3.1/text-to-image',\n 'fal-ai/flux-kontext-lora/text-to-image',\n 'fal-ai/recraft/v3/text-to-image',\n 'fal-ai/wan/v2.2-5b/text-to-image',\n 'fal-ai/wan/v2.2-a14b/text-to-image',\n ].includes(this.modelId)\n ? false\n : undefined;\n }\n\n get supportsMaskInputs(): boolean | undefined {\n if (\n this.modelId === 'fal-ai/flux-general/inpainting' ||\n this.modelId === 'fal-ai/flux-lora/inpainting'\n ) {\n return true;\n }\n\n return this.supportsFileInputs == null ? undefined : false;\n }\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalImageModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalImageModelId;\n config: FalImageModelConfig;\n }) {\n return new FalImageModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalImageModelId,\n private readonly config: FalImageModelConfig,\n ) {}\n\n private async getArgs({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n files,\n mask,\n }: Parameters<ImageModelV4['doGenerate']>[0]) {\n const warnings: Array<SharedV4Warning> = [];\n\n let imageSize: FalImageSize | undefined;\n if (size) {\n const [width, height] = size.split('x').map(Number);\n imageSize = { width, height };\n } else if (aspectRatio) {\n imageSize = convertAspectRatioToSize(aspectRatio);\n }\n\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falImageModelOptionsSchema,\n });\n\n const requestBody: Record<string, unknown> = {\n prompt,\n seed,\n image_size: imageSize,\n num_images: n,\n };\n\n // Handle image editing: convert files to image_url or image_urls\n if (files != null && files.length > 0) {\n const useMultipleImages = falOptions?.useMultipleImages === true;\n\n if (useMultipleImages) {\n // Use image_urls array for models that support multiple images (e.g., flux-2/edit)\n requestBody.image_urls = files.map(file =>\n convertImageModelFileToDataUri(file),\n );\n } else {\n // Use single image_url for standard image editing models\n requestBody.image_url = convertImageModelFileToDataUri(files[0]);\n\n if (files.length > 1) {\n warnings.push({\n type: 'other',\n message:\n 'Multiple input images provided but useMultipleImages is not enabled. ' +\n 'Only the first image will be used. Set providerOptions.fal.useMultipleImages ' +\n 'to true for models that support multiple images (e.g., fal-ai/flux-2/edit).',\n });\n }\n }\n }\n\n // Handle mask for inpainting\n if (mask != null) {\n requestBody.mask_url = convertImageModelFileToDataUri(mask);\n }\n\n if (falOptions) {\n const deprecatedKeys =\n '__deprecatedKeys' in falOptions\n ? (falOptions.__deprecatedKeys as string[])\n : undefined;\n\n if (deprecatedKeys && deprecatedKeys.length > 0) {\n warnings.push({\n type: 'other',\n message: `The following provider options use deprecated snake_case and will be removed in @ai-sdk/fal v2.0. Please use camelCase instead: ${deprecatedKeys\n .map(key => {\n const camelCase = key.replace(/_([a-z])/g, (_, letter) =>\n letter.toUpperCase(),\n );\n return `'${key}' (use '${camelCase}')`;\n })\n .join(', ')}`,\n });\n }\n\n const fieldMapping: Record<string, string> = {\n imageUrl: 'image_url',\n maskUrl: 'mask_url',\n guidanceScale: 'guidance_scale',\n numInferenceSteps: 'num_inference_steps',\n enableSafetyChecker: 'enable_safety_checker',\n outputFormat: 'output_format',\n syncMode: 'sync_mode',\n safetyTolerance: 'safety_tolerance',\n };\n\n for (const [key, value] of Object.entries(falOptions)) {\n if (key === '__deprecatedKeys') continue;\n if (key === 'useMultipleImages') continue; // Don't send to API\n const apiKey = fieldMapping[key] ?? key;\n\n if (value !== undefined) {\n requestBody[apiKey] = value;\n }\n }\n }\n\n return { requestBody, warnings } as const;\n }\n\n async doGenerate(\n options: Parameters<ImageModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {\n const { requestBody, warnings } = await this.getArgs(options);\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { value, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(\n this.config.headers ? await resolve(this.config.headers) : undefined,\n options.headers,\n ),\n body: requestBody,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n falImageResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const {\n images: targetImages,\n // prompt is just passed through and not a revised prompt per image\n prompt: _prompt,\n // NSFW information is normalized merged into `providerMetadata.fal.images`\n has_nsfw_concepts,\n nsfw_content_detected,\n // pass through other properties to providerMetadata\n ...responseMetaData\n } = value;\n\n // download the images:\n const downloadedImages = await Promise.all(\n targetImages.map(image =>\n this.downloadImage(image.url, options.abortSignal),\n ),\n );\n\n return {\n images: downloadedImages,\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n providerMetadata: {\n fal: {\n images: targetImages.map((image, index) => {\n const {\n url: _url,\n content_type: contentType,\n file_name: fileName,\n file_data: fileData,\n file_size: fileSize,\n ...imageMetaData\n } = image;\n\n const nsfw =\n has_nsfw_concepts?.[index] ?? nsfw_content_detected?.[index];\n\n return {\n ...imageMetaData,\n ...removeOnlyUndefined({\n contentType,\n fileName,\n fileData,\n fileSize,\n nsfw,\n }),\n };\n }),\n ...responseMetaData,\n },\n },\n };\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // url is a generated-image URL from the provider response; validate it.\n validateUrl: true,\n trustedOrigin: this.config.baseURL,\n // No specific headers should be needed for this request as it's a\n // generated image provided by fal.ai.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\nfunction removeOnlyUndefined<T extends Record<string, unknown>>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).filter(([, v]) => v !== undefined),\n ) as Partial<T>;\n}\n\n/**\n * Converts an aspect ratio to an image size compatible with fal.ai APIs.\n * @param aspectRatio - The aspect ratio to convert.\n * @returns The image size.\n */\nfunction convertAspectRatioToSize(\n aspectRatio: `${number}:${number}`,\n): FalImageSize | undefined {\n switch (aspectRatio) {\n case '1:1':\n return 'square_hd';\n case '16:9':\n return 'landscape_16_9';\n case '9:16':\n return 'portrait_16_9';\n case '4:3':\n return 'landscape_4_3';\n case '3:4':\n return 'portrait_4_3';\n case '16:10':\n return { width: 1280, height: 800 };\n case '10:16':\n return { width: 800, height: 1280 };\n case '21:9':\n return { width: 2560, height: 1080 };\n case '9:21':\n return { width: 1080, height: 2560 };\n }\n}\n\n// Validation error has a particular payload to inform the exact property that is invalid\nconst falValidationErrorSchema = z.object({\n detail: z.array(\n z.object({\n loc: z.array(z.string()),\n msg: z.string(),\n type: z.string(),\n }),\n ),\n});\n\ntype ValidationError = z.infer<typeof falValidationErrorSchema>;\n\n// Other errors have a message property\nconst falHttpErrorSchema = z.object({\n message: z.string(),\n});\n\nconst falErrorSchema = z.union([falValidationErrorSchema, falHttpErrorSchema]);\n\nconst falImageSchema = z.object({\n url: z.string(),\n width: z.number().nullish(),\n height: z.number().nullish(),\n // e.g. https://fal.ai/models/fal-ai/fashn/tryon/v1.6/api#schema-output\n content_type: z.string().nullish(),\n // e.g. https://fal.ai/models/fal-ai/flowedit/api#schema-output\n file_name: z.string().nullish(),\n file_data: z.string().optional(),\n file_size: z.number().nullish(),\n});\n\n// https://fal.ai/models/fal-ai/lora/api#type-File\nconst loraFileSchema = z.object({\n url: z.string(),\n content_type: z.string().optional(),\n file_name: z.string().nullable().optional(),\n file_data: z.string().optional(),\n file_size: z.number().nullable().optional(),\n});\n\nconst commonResponseSchema = z.object({\n timings: z\n .object({\n inference: z.number().optional(),\n })\n .optional(),\n seed: z.number().optional(),\n has_nsfw_concepts: z.array(z.boolean()).optional(),\n prompt: z.string().optional(),\n // https://fal.ai/models/fal-ai/lcm/api#schema-output\n nsfw_content_detected: z.array(z.boolean()).optional(),\n num_inference_steps: z.number().optional(),\n // https://fal.ai/models/fal-ai/lora/api#schema-output\n debug_latents: loraFileSchema.optional(),\n debug_per_pass_latents: loraFileSchema.optional(),\n});\n\n// Most FAL image models respond with an array of images, but some have a response\n// with a single image, e.g. https://fal.ai/models/easel-ai/easel-avatar/api#schema-output\nconst base = z.looseObject(commonResponseSchema.shape);\nconst falImageResponseSchema = z\n .union([\n base.extend({ images: z.array(falImageSchema) }),\n base.extend({ image: falImageSchema }),\n ])\n .transform(v => ('images' in v ? v : { ...v, images: [v.image] }))\n .pipe(base.extend({ images: z.array(falImageSchema) }));\n\nfunction isValidationError(error: unknown): error is ValidationError {\n return falValidationErrorSchema.safeParse(error).success;\n}\n\nconst falFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: falErrorSchema,\n errorToMessage: error => {\n if (isValidationError(error)) {\n return error.detail\n .map(detail => `${detail.loc.join('.')}: ${detail.msg}`)\n .join('\\n');\n }\n return error.message ?? 'Unknown fal error';\n },\n});\n","import {\n lazySchema,\n zodSchema,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nexport const falImageModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z\n .looseObject({\n /** @deprecated use prompt.images instead */\n imageUrl: z.string().nullish().meta({\n deprecated: true,\n description: 'Use `prompt.images` instead',\n }),\n maskUrl: z\n .string()\n .nullish()\n .meta({ deprecated: true, description: 'Use `prompt.mask` instead' }),\n guidanceScale: z.number().min(1).max(20).nullish(),\n numInferenceSteps: z.number().min(1).max(50).nullish(),\n enableSafetyChecker: z.boolean().nullish(),\n outputFormat: z.enum(['jpeg', 'png']).nullish(),\n syncMode: z.boolean().nullish(),\n strength: z.number().nullish(),\n acceleration: z.enum(['none', 'regular', 'high']).nullish(),\n safetyTolerance: z\n .enum(['1', '2', '3', '4', '5', '6'])\n .or(z.number().min(1).max(6))\n .nullish(),\n /**\n * When true, converts multiple input images to `image_urls` array instead of `image_url` string.\n */\n useMultipleImages: z.boolean().nullish(),\n\n // Deprecated snake_case versions\n image_url: z.string().nullish(),\n mask_url: z.string().nullish(),\n guidance_scale: z.number().min(1).max(20).nullish(),\n num_inference_steps: z.number().min(1).max(50).nullish(),\n enable_safety_checker: z.boolean().nullish(),\n output_format: z.enum(['jpeg', 'png']).nullish(),\n sync_mode: z.boolean().nullish(),\n safety_tolerance: z\n .enum(['1', '2', '3', '4', '5', '6'])\n .or(z.number().min(1).max(6))\n .nullish(),\n })\n .transform(data => {\n const result: Record<string, unknown> = {};\n const deprecatedKeys: string[] = [];\n\n const mapKey = (snakeKey: string, camelKey: string) => {\n const snakeValue = data[snakeKey as keyof typeof data];\n const camelValue = data[camelKey as keyof typeof data];\n\n // If snake_case is used, mark it as deprecated\n if (snakeValue !== undefined && snakeValue !== null) {\n deprecatedKeys.push(snakeKey);\n result[camelKey] = snakeValue;\n } else if (camelValue !== undefined && camelValue !== null) {\n result[camelKey] = camelValue;\n }\n };\n\n // Map all known parameters\n mapKey('image_url', 'imageUrl');\n mapKey('mask_url', 'maskUrl');\n mapKey('guidance_scale', 'guidanceScale');\n mapKey('num_inference_steps', 'numInferenceSteps');\n mapKey('enable_safety_checker', 'enableSafetyChecker');\n mapKey('output_format', 'outputFormat');\n mapKey('sync_mode', 'syncMode');\n mapKey('safety_tolerance', 'safetyTolerance');\n\n // These don't have snake_case equivalents\n if (data.strength !== undefined && data.strength !== null) {\n result.strength = data.strength;\n }\n if (data.acceleration !== undefined && data.acceleration !== null) {\n result.acceleration = data.acceleration;\n }\n if (\n data.useMultipleImages !== undefined &&\n data.useMultipleImages !== null\n ) {\n result.useMultipleImages = data.useMultipleImages;\n }\n\n for (const [key, value] of Object.entries(data)) {\n if (\n ![\n // camelCase known keys\n 'imageUrl',\n 'maskUrl',\n 'guidanceScale',\n 'numInferenceSteps',\n 'enableSafetyChecker',\n 'outputFormat',\n 'syncMode',\n 'strength',\n 'acceleration',\n 'safetyTolerance',\n 'useMultipleImages',\n // snake_case known keys\n 'image_url',\n 'mask_url',\n 'guidance_scale',\n 'num_inference_steps',\n 'enable_safety_checker',\n 'output_format',\n 'sync_mode',\n 'safety_tolerance',\n ].includes(key)\n ) {\n result[key] = value;\n }\n }\n\n if (deprecatedKeys.length > 0) {\n (result as any).__deprecatedKeys = deprecatedKeys;\n }\n\n return result;\n }),\n ),\n);\n\nexport type FalImageModelOptions = InferSchema<\n typeof falImageModelOptionsSchema\n>;\n","import {\n AISDKError,\n type TranscriptionModelV4,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertUint8ArrayToBase64,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n delay,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falErrorDataSchema, falFailedResponseHandler } from './fal-error';\nimport { falTranscriptionModelOptionsSchema } from './fal-transcription-model-options';\nimport type { FalTranscriptionModelId } from './fal-transcription-options';\nimport type { FalTranscriptionAPITypes } from './fal-api-types';\n\ninterface FalTranscriptionModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalTranscriptionModel implements TranscriptionModelV4 {\n readonly specificationVersion = 'v4';\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalTranscriptionModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalTranscriptionModelId;\n config: FalTranscriptionModelConfig;\n }) {\n return new FalTranscriptionModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalTranscriptionModelId,\n private readonly config: FalTranscriptionModelConfig,\n ) {}\n\n private async getArgs({\n providerOptions,\n }: Parameters<TranscriptionModelV4['doGenerate']>[0]) {\n const warnings: SharedV4Warning[] = [];\n\n // Parse provider options\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falTranscriptionModelOptionsSchema,\n });\n\n // Create form data with base fields\n const body: Omit<FalTranscriptionAPITypes, 'audio_url'> = {\n task: 'transcribe',\n diarize: true,\n chunk_level: 'word',\n };\n\n // Add provider-specific options\n if (falOptions) {\n body.language = falOptions.language as never;\n body.version = falOptions.version ?? undefined;\n body.batch_size = falOptions.batchSize ?? undefined;\n body.num_speakers = falOptions.numSpeakers ?? undefined;\n\n if (typeof falOptions.diarize === 'boolean') {\n body.diarize = falOptions.diarize;\n }\n\n if (falOptions.chunkLevel) {\n body.chunk_level = falOptions.chunkLevel;\n }\n }\n\n return {\n body,\n warnings,\n };\n }\n\n async doGenerate(\n options: Parameters<TranscriptionModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<TranscriptionModelV4['doGenerate']>>> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { body, warnings } = await this.getArgs(options);\n\n const base64Audio =\n typeof options.audio === 'string'\n ? options.audio\n : convertUint8ArrayToBase64(options.audio);\n\n const audioUrl = `data:${options.mediaType};base64,${base64Audio}`;\n\n const { value: queueResponse } = await postJsonToApi({\n url: this.config.url({\n path: `https://queue.fal.run/fal-ai/${this.modelId}`,\n modelId: this.modelId,\n }),\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body: {\n ...body,\n audio_url: audioUrl,\n },\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler:\n createJsonResponseHandler(falJobResponseSchema),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n // Poll for completion with timeout\n const startTime = Date.now();\n const timeoutMs = 60000; // 60 seconds timeout\n const pollIntervalMs = 1000; // 1 second interval\n\n let response;\n let responseHeaders;\n let rawResponse;\n\n while (true) {\n try {\n const {\n value: statusResponse,\n responseHeaders: statusHeaders,\n rawValue: statusRawResponse,\n } = await getFromApi({\n url: this.config.url({\n path: `https://queue.fal.run/fal-ai/${this.modelId}/requests/${queueResponse.request_id}`,\n modelId: this.modelId,\n }),\n validateUrl: false,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n failedResponseHandler: async ({\n requestBodyValues,\n response,\n url,\n }) => {\n const clone = response.clone();\n const body = (await clone.json()) as { detail: string };\n\n if (body.detail === 'Request is still in progress') {\n // This is not an error, just a status update that the request is still processing\n // Continue polling by returning a special error that signals to continue\n return {\n value: new Error('Request is still in progress'),\n rawValue: body,\n responseHeaders: {},\n };\n }\n\n return createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n })({ requestBodyValues, response, url });\n },\n successfulResponseHandler: createJsonResponseHandler(\n falTranscriptionResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n response = statusResponse;\n responseHeaders = statusHeaders;\n rawResponse = statusRawResponse;\n break;\n } catch (error) {\n // If the error message indicates the request is still in progress, ignore it and continue polling\n if (\n error instanceof Error &&\n error.message === 'Request is still in progress'\n ) {\n // Continue with the polling loop\n } else {\n // Re-throw any other errors\n throw error;\n }\n }\n\n // Check if we've exceeded the timeout\n if (Date.now() - startTime > timeoutMs) {\n throw new AISDKError({\n message: 'Transcription request timed out after 60 seconds',\n name: 'TranscriptionRequestTimedOut',\n cause: response,\n });\n }\n\n // Wait before polling again\n await delay(pollIntervalMs);\n }\n\n return {\n text: response.text,\n segments:\n response.chunks?.map(chunk => ({\n text: chunk.text,\n startSecond: chunk.timestamp?.at(0) ?? 0,\n endSecond: chunk.timestamp?.at(1) ?? 0,\n })) ?? [],\n language: response.inferred_languages?.at(0) ?? undefined,\n durationInSeconds: response.chunks?.at(-1)?.timestamp?.at(1) ?? undefined,\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n body: rawResponse,\n },\n };\n }\n}\n\nconst falJobResponseSchema = z.object({\n request_id: z.string().nullish(),\n});\n\nconst falTranscriptionResponseSchema = z.object({\n text: z.string(),\n chunks: z\n .array(\n z.object({\n text: z.string(),\n timestamp: z.array(z.number()).nullish(),\n }),\n )\n .nullish(),\n inferred_languages: z.array(z.string()).nullish(),\n});\n","import { z } from 'zod/v4';\nimport { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\n\nexport const falErrorDataSchema = z.object({\n error: z.object({\n message: z.string(),\n code: z.number(),\n }),\n});\n\nexport type FalErrorData = z.infer<typeof falErrorDataSchema>;\n\nexport const falFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n});\n","import { z } from 'zod/v4';\n\n// https://fal.ai/models/fal-ai/whisper/api?platform=http\nexport const falTranscriptionModelOptionsSchema = z.object({\n /**\n * Language of the audio file. If set to null, the language will be automatically detected. Defaults to null.\n *\n * If translate is selected as the task, the audio will be translated to English, regardless of the language selected.\n */\n language: z\n .union([z.enum(['en']), z.string()])\n .nullish()\n .default('en'),\n\n /**\n * Whether to diarize the audio file. Defaults to true.\n */\n diarize: z.boolean().nullish().default(true),\n\n /**\n * Level of the chunks to return. Either segment or word. Default value: \"segment\"\n */\n chunkLevel: z.enum(['segment', 'word']).nullish().default('segment'),\n\n /**\n * Version of the model to use. All of the models are the Whisper large variant. Default value: \"3\"\n */\n version: z.enum(['3']).nullish().default('3'),\n\n /**\n * Default value: 64\n */\n batchSize: z.number().nullish().default(64),\n\n /**\n * Number of speakers in the audio file. Defaults to null. If not provided, the number of speakers will be automatically detected.\n */\n numSpeakers: z.number().nullable().nullish(),\n});\n\nexport type FalTranscriptionModelOptions = z.infer<\n typeof falTranscriptionModelOptionsSchema\n>;\n","import type { SpeechModelV4, SharedV4Warning } from '@ai-sdk/provider';\nimport {\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createStatusCodeErrorResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n serializeModelOptions,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falFailedResponseHandler } from './fal-error';\nimport { falSpeechModelOptionsSchema } from './fal-speech-model-options';\nimport type { FalSpeechModelId } from './fal-speech-settings';\n\ninterface FalSpeechModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalSpeechModel implements SpeechModelV4 {\n readonly specificationVersion = 'v4';\n\n get provider(): string {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: FalSpeechModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: FalSpeechModelId;\n config: FalSpeechModelConfig;\n }) {\n return new FalSpeechModel(options.modelId, options.config);\n }\n\n constructor(\n readonly modelId: FalSpeechModelId,\n private readonly config: FalSpeechModelConfig,\n ) {}\n\n private async getArgs({\n text,\n voice,\n outputFormat,\n speed,\n language,\n providerOptions,\n }: Parameters<SpeechModelV4['doGenerate']>[0]) {\n const warnings: SharedV4Warning[] = [];\n\n const falOptions = await parseProviderOptions({\n provider: 'fal',\n providerOptions,\n schema: falSpeechModelOptionsSchema,\n });\n\n const requestBody = {\n text,\n output_format: outputFormat === 'hex' ? 'hex' : 'url',\n voice,\n speed,\n ...falOptions,\n };\n\n // Language is not directly supported; warn and ignore\n if (language) {\n warnings.push({\n type: 'unsupported',\n feature: 'language',\n details:\n \"fal speech models don't support 'language' directly; consider providerOptions.fal.language_boost\",\n });\n }\n\n // warn on invalid values (and on hex until we support hex response handling)\n if (outputFormat && outputFormat !== 'url' && outputFormat !== 'hex') {\n warnings.push({\n type: 'unsupported',\n feature: 'outputFormat',\n details: `Unsupported outputFormat: ${outputFormat}. Using 'url' instead.`,\n });\n }\n\n return { requestBody, warnings } as const;\n }\n\n async doGenerate(\n options: Parameters<SpeechModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<SpeechModelV4['doGenerate']>>> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { requestBody, warnings } = await this.getArgs(options);\n\n const requestUrl = this.config.url({\n path: `https://fal.run/${this.modelId}`,\n modelId: this.modelId,\n });\n\n const {\n value: json,\n responseHeaders,\n rawValue,\n } = await postJsonToApi({\n url: requestUrl,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body: requestBody,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n falSpeechResponseSchema,\n ),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const audioUrl = json.audio.url;\n const { value: audio } = await getFromApi({\n url: audioUrl,\n // audioUrl comes from the provider response body; validate it.\n validateUrl: true,\n trustedOrigin: requestUrl,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n audio,\n warnings,\n request: {\n body: JSON.stringify(requestBody),\n },\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n body: rawValue,\n },\n };\n }\n}\n\nconst falSpeechResponseSchema = z.object({\n audio: z.object({ url: z.string() }),\n duration_ms: z.number().optional(),\n request_id: z.string().optional(),\n});\n","import { z } from 'zod/v4';\nimport { FAL_EMOTIONS, FAL_LANGUAGE_BOOSTS } from './fal-api-types';\n\nexport const falSpeechModelOptionsSchema = z.looseObject({\n voice_setting: z\n .object({\n speed: z.number().nullish(),\n vol: z.number().nullish(),\n voice_id: z.string().nullish(),\n pitch: z.number().nullish(),\n english_normalization: z.boolean().nullish(),\n emotion: z.enum(FAL_EMOTIONS).nullish(),\n })\n .partial()\n .nullish(),\n audio_setting: z.record(z.string(), z.unknown()).nullish(),\n language_boost: z.enum(FAL_LANGUAGE_BOOSTS).nullish(),\n pronunciation_dict: z.record(z.string(), z.string()).nullish(),\n});\n\nexport type FalSpeechModelOptions = z.infer<typeof falSpeechModelOptionsSchema>;\n","export type FalTranscriptionAPITypes = {\n /**\n * URL of the audio file to transcribe. Supported formats: mp3, mp4, mpeg, mpga, m4a, wav or webm.\n */\n audio_url: string;\n\n /**\n * Task to perform on the audio file. Either transcribe or translate. Default value: \"transcribe\"\n */\n task?: 'transcribe' | 'translate';\n\n /**\n * Language of the audio file. If set to null, the language will be automatically detected. Defaults to null.\n *\n * If translate is selected as the task, the audio will be translated to English, regardless of the language selected.\n */\n language?:\n | 'af'\n | 'am'\n | 'ar'\n | 'as'\n | 'az'\n | 'ba'\n | 'be'\n | 'bg'\n | 'bn'\n | 'bo'\n | 'br'\n | 'bs'\n | 'ca'\n | 'cs'\n | 'cy'\n | 'da'\n | 'de'\n | 'el'\n | 'en'\n | 'es'\n | 'et'\n | 'eu'\n | 'fa'\n | 'fi'\n | 'fo'\n | 'fr'\n | 'gl'\n | 'gu'\n | 'ha'\n | 'haw'\n | 'he'\n | 'hi'\n | 'hr'\n | 'ht'\n | 'hu'\n | 'hy'\n | 'id'\n | 'is'\n | 'it'\n | 'ja'\n | 'jw'\n | 'ka'\n | 'kk'\n | 'km'\n | 'kn'\n | 'ko'\n | 'la'\n | 'lb'\n | 'ln'\n | 'lo'\n | 'lt'\n | 'lv'\n | 'mg'\n | 'mi'\n | 'mk'\n | 'ml'\n | 'mn'\n | 'mr'\n | 'ms'\n | 'mt'\n | 'my'\n | 'ne'\n | 'nl'\n | 'nn'\n | 'no'\n | 'oc'\n | 'pa'\n | 'pl'\n | 'ps'\n | 'pt'\n | 'ro'\n | 'ru'\n | 'sa'\n | 'sd'\n | 'si'\n | 'sk'\n | 'sl'\n | 'sn'\n | 'so'\n | 'sq'\n | 'sr'\n | 'su'\n | 'sv'\n | 'sw'\n | 'ta'\n | 'te'\n | 'tg'\n | 'th'\n | 'tk'\n | 'tl'\n | 'tr'\n | 'tt'\n | 'uk'\n | 'ur'\n | 'uz'\n | 'vi'\n | 'yi'\n | 'yo'\n | 'yue'\n | 'zh'\n | null;\n\n /**\n * Whether to diarize the audio file. Defaults to true.\n */\n diarize?: boolean;\n\n /**\n * Level of the chunks to return. Either segment or word. Default value: \"segment\"\n */\n chunk_level?: 'segment' | 'word';\n\n /**\n * Version of the model to use. All of the models are the Whisper large variant. Default value: \"3\"\n */\n version?: '3';\n\n /**\n * Default value: 64\n */\n batch_size?: number;\n\n /**\n * Prompt to use for generation. Defaults to an empty string. Default value: \"\"\n */\n prompt?: string;\n\n /**\n * Number of speakers in the audio file. Defaults to null. If not provided, the number of speakers will be automatically detected.\n */\n num_speakers?: number | null;\n};\n\nexport const FAL_LANGUAGE_BOOSTS = [\n 'Chinese',\n 'Chinese,Yue',\n 'English',\n 'Arabic',\n 'Russian',\n 'Spanish',\n 'French',\n 'Portuguese',\n 'German',\n 'Turkish',\n 'Dutch',\n 'Ukrainian',\n 'Vietnamese',\n 'Indonesian',\n 'Japanese',\n 'Italian',\n 'Korean',\n 'Thai',\n 'Polish',\n 'Romanian',\n 'Greek',\n 'Czech',\n 'Finnish',\n 'Hindi',\n 'auto',\n] as const;\nexport type FalLanguageBoost = (typeof FAL_LANGUAGE_BOOSTS)[number];\n\nexport const FAL_EMOTIONS = [\n 'happy',\n 'sad',\n 'angry',\n 'fearful',\n 'disgusted',\n 'surprised',\n 'neutral',\n] as const;\nexport type FalEmotion = (typeof FAL_EMOTIONS)[number];\n","import {\n AISDKError,\n APICallError,\n type Experimental_VideoModelV4 as VideoModelV4,\n type Experimental_VideoModelV4OperationStartResult as VideoModelV4OperationStartResult,\n type Experimental_VideoModelV4OperationStatusResult as VideoModelV4OperationStatusResult,\n type SharedV4ProviderMetadata,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertImageModelFileToDataUri,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n getFromApi,\n parseProviderOptions,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport type { FalConfig } from './fal-config';\nimport { falErrorDataSchema, falFailedResponseHandler } from './fal-error';\nimport {\n falVideoModelOptionsSchema,\n type FalVideoModelOptions,\n} from './fal-video-model-options';\nimport type { FalVideoModelId } from './fal-video-settings';\n\ninterface FalVideoModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalVideoModel implements VideoModelV4 {\n readonly specificationVersion = 'v4';\n readonly maxVideosPerCall = 1; // FAL video models support 1 video at a time\n\n get provider(): string {\n return this.config.provider;\n }\n\n private get normalizedModelId(): string {\n return this.modelId.replace(/^fal-ai\\//, '').replace(/^fal\\//, '');\n }\n\n constructor(\n readonly modelId: FalVideoModelId,\n private readonly config: FalVideoModelConfig,\n ) {}\n\n async handleWebhookOption(\n options: Parameters<NonNullable<VideoModelV4['handleWebhookOption']>>[0],\n ) {\n const { url, received } = await options.webhook();\n return { webhookUrl: url, received };\n }\n\n async doStart(\n options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],\n ): Promise<VideoModelV4OperationStartResult> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const warnings: SharedV4Warning[] = [];\n\n const { body } = await this.buildRequestBody(options);\n\n const { responseUrl, submitUrl } = await this.submitToQueue(\n {\n headers: options.headers,\n abortSignal: options.abortSignal,\n webhookUrl: options.webhookUrl,\n },\n body,\n );\n\n return {\n operation: { responseUrl, submitUrl },\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: undefined,\n },\n };\n }\n\n async doStatus(\n options: Parameters<NonNullable<VideoModelV4['doStatus']>>[0],\n ): Promise<VideoModelV4OperationStatusResult> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const { responseUrl, submitUrl } = options.operation as {\n responseUrl: string;\n submitUrl: string;\n };\n\n try {\n const { value: response, responseHeaders } = await this.fetchStatus({\n responseUrl,\n submitUrl,\n headers: options.headers,\n abortSignal: options.abortSignal,\n });\n\n return this.buildResult({\n response,\n responseHeaders,\n warnings: [],\n currentDate,\n });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message === 'Request is still in progress'\n ) {\n return {\n status: 'pending' as const,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: undefined,\n },\n };\n }\n\n if (APICallError.isInstance(error)) {\n return {\n status: 'error' as const,\n error: error.message,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: error.responseHeaders,\n },\n };\n }\n\n throw error;\n }\n }\n\n private async buildRequestBody(\n options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],\n ): Promise<{\n body: Record<string, unknown>;\n falOptions: FalVideoModelOptions | undefined;\n }> {\n const falOptions = (await parseProviderOptions({\n provider: 'fal',\n providerOptions: options.providerOptions,\n schema: falVideoModelOptionsSchema,\n })) as FalVideoModelOptions | undefined;\n\n const body: Record<string, unknown> = {};\n\n if (options.prompt != null) {\n body.prompt = options.prompt;\n }\n\n if (options.image != null) {\n if (options.image.type === 'url') {\n body.image_url = options.image.url;\n } else {\n body.image_url = convertImageModelFileToDataUri(options.image);\n }\n }\n\n if (options.aspectRatio) {\n body.aspect_ratio = options.aspectRatio;\n }\n\n if (options.duration) {\n body.duration = `${options.duration}s`;\n }\n\n if (options.seed) {\n body.seed = options.seed;\n }\n\n if (falOptions != null) {\n const opts = falOptions;\n if (opts.loop !== undefined && opts.loop !== null) {\n body.loop = opts.loop;\n }\n if (opts.motionStrength !== undefined && opts.motionStrength !== null) {\n body.motion_strength = opts.motionStrength;\n }\n if (opts.resolution !== undefined && opts.resolution !== null) {\n body.resolution = opts.resolution;\n }\n if (opts.negativePrompt !== undefined && opts.negativePrompt !== null) {\n body.negative_prompt = opts.negativePrompt;\n }\n if (opts.promptOptimizer !== undefined && opts.promptOptimizer !== null) {\n body.prompt_optimizer = opts.promptOptimizer;\n }\n\n for (const [key, value] of Object.entries(opts)) {\n if (\n ![\n 'loop',\n 'motionStrength',\n 'resolution',\n 'negativePrompt',\n 'promptOptimizer',\n ].includes(key)\n ) {\n body[key] = value;\n }\n }\n }\n\n return { body, falOptions };\n }\n\n private async submitToQueue(\n options: {\n headers?: Record<string, string | undefined>;\n abortSignal?: AbortSignal;\n webhookUrl?: string;\n },\n body: Record<string, unknown>,\n ): Promise<{ responseUrl: string; submitUrl: string }> {\n let queuePath = `https://queue.fal.run/fal-ai/${this.normalizedModelId}`;\n if (options.webhookUrl) {\n queuePath += `?fal_webhook=${encodeURIComponent(options.webhookUrl)}`;\n }\n\n const submitUrl = this.config.url({\n path: queuePath,\n modelId: this.modelId,\n });\n const { value: queueResponse } = await postJsonToApi({\n url: submitUrl,\n headers: combineHeaders(this.config.headers?.(), options.headers),\n body,\n failedResponseHandler: falFailedResponseHandler,\n successfulResponseHandler:\n createJsonResponseHandler(falJobResponseSchema),\n abortSignal: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n const responseUrl = queueResponse.response_url;\n if (!responseUrl) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_ERROR',\n message: 'No response URL returned from queue endpoint',\n });\n }\n\n return { responseUrl, submitUrl };\n }\n\n private async fetchStatus({\n responseUrl,\n submitUrl,\n headers,\n abortSignal,\n }: {\n responseUrl: string;\n submitUrl: string;\n headers?: Record<string, string | undefined>;\n abortSignal?: AbortSignal;\n }): Promise<{\n value: FalVideoResponse;\n responseHeaders?: Record<string, string>;\n }> {\n const statusUrl = this.config.url({\n path: responseUrl,\n modelId: this.modelId,\n });\n\n return getFromApi({\n url: statusUrl,\n // statusUrl comes from the queue response body.\n validateUrl: true,\n credentialedOrigin: submitUrl,\n trustedOrigin: submitUrl,\n headers: combineHeaders(this.config.headers?.(), headers),\n failedResponseHandler: async ({ response, url, requestBodyValues }) => {\n const body = await response.clone().json();\n\n if (body.detail === 'Request is still in progress') {\n return {\n value: new Error('Request is still in progress'),\n rawValue: body,\n responseHeaders: {},\n };\n }\n\n return createJsonErrorResponseHandler({\n errorSchema: falErrorDataSchema,\n errorToMessage: data => data.error.message,\n })({ response, url, requestBodyValues });\n },\n successfulResponseHandler: createJsonResponseHandler(\n falVideoResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n }\n\n private buildResult({\n response,\n responseHeaders,\n warnings,\n currentDate,\n }: {\n response: FalVideoResponse;\n responseHeaders?: Record<string, string>;\n warnings: SharedV4Warning[];\n currentDate: Date;\n }): {\n status: 'completed';\n videos: Array<{ type: 'url'; url: string; mediaType: string }>;\n warnings: SharedV4Warning[];\n providerMetadata: SharedV4ProviderMetadata;\n response: {\n timestamp: Date;\n modelId: string;\n headers: Record<string, string> | undefined;\n };\n } {\n const videoUrl = response.video?.url;\n\n if (!videoUrl || !response.video) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_ERROR',\n message: 'No video URL in response',\n });\n }\n\n return {\n status: 'completed',\n videos: [\n {\n type: 'url',\n url: videoUrl,\n mediaType: response.video.content_type || 'video/mp4',\n },\n ],\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n providerMetadata: {\n fal: {\n videos: [\n {\n url: videoUrl,\n width: response.video.width,\n height: response.video.height,\n duration: response.video.duration,\n fps: response.video.fps,\n contentType: response.video.content_type,\n },\n ],\n ...(response.seed !== undefined ? { seed: response.seed } : {}),\n ...(response.timings ? { timings: response.timings } : {}),\n ...(response.has_nsfw_concepts !== undefined\n ? { has_nsfw_concepts: response.has_nsfw_concepts }\n : {}),\n ...(response.prompt ? { prompt: response.prompt } : {}),\n },\n },\n };\n }\n}\n\nconst falJobResponseSchema = z.object({\n request_id: z.string().nullish(),\n response_url: z.string().nullish(),\n});\n\nconst falVideoResponseSchema = z.object({\n video: z\n .object({\n url: z.string(),\n width: z.number().nullish(),\n height: z.number().nullish(),\n duration: z.number().nullish(),\n fps: z.number().nullish(),\n content_type: z.string().nullish(),\n })\n .nullish(),\n seed: z.number().nullish(),\n timings: z\n .object({\n inference: z.number().nullish(),\n })\n .nullish(),\n has_nsfw_concepts: z.array(z.boolean()).nullish(),\n prompt: z.string().nullish(),\n});\n\ntype FalVideoResponse = z.infer<typeof falVideoResponseSchema>;\n","import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\nexport type FalVideoModelOptions = {\n loop?: boolean | null;\n motionStrength?: number | null;\n resolution?: string | null;\n negativePrompt?: string | null;\n promptOptimizer?: boolean | null;\n [key: string]: unknown; // For passthrough\n};\n\n// Provider options schema for FAL video generation\nexport const falVideoModelOptionsSchema = lazySchema(() =>\n zodSchema(\n z.looseObject({\n // Video loop - only for Luma models\n loop: z.boolean().nullish(),\n\n // Motion strength (provider-specific)\n motionStrength: z.number().min(0).max(1).nullish(),\n\n // Resolution (model-specific, e.g., '480p', '720p', '1080p')\n resolution: z.string().nullish(),\n\n // Model-specific parameters\n negativePrompt: z.string().nullish(),\n promptOptimizer: z.boolean().nullish(),\n }),\n ),\n);\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["z","z","combineHeaders","createJsonErrorResponseHandler","createJsonResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","serializeModelOptions","WORKFLOW_SERIALIZE","WORKFLOW_DESERIALIZE","z","z","createJsonErrorResponseHandler","falFailedResponseHandler","z","WORKFLOW_SERIALIZE","serializeModelOptions","WORKFLOW_DESERIALIZE","parseProviderOptions","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","getFromApi","response","body","createJsonErrorResponseHandler","z","combineHeaders","createBinaryResponseHandler","createJsonResponseHandler","createStatusCodeErrorResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","serializeModelOptions","WORKFLOW_SERIALIZE","WORKFLOW_DESERIALIZE","z","z","z","WORKFLOW_SERIALIZE","serializeModelOptions","WORKFLOW_DESERIALIZE","parseProviderOptions","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","getFromApi","createStatusCodeErrorResponseHandler","createBinaryResponseHandler","z","AISDKError","combineHeaders","convertImageModelFileToDataUri","createJsonErrorResponseHandler","createJsonResponseHandler","getFromApi","parseProviderOptions","postJsonToApi","z","lazySchema","zodSchema","z","parseProviderOptions","convertImageModelFileToDataUri","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","falJobResponseSchema","AISDKError","getFromApi","createJsonErrorResponseHandler","z"]}
package/docs/10-fal.mdx CHANGED
@@ -148,7 +148,7 @@ A mask can be passed as well
148
148
 
149
149
  ```ts
150
150
  await generateImage({
151
- model: fal.image('fal-ai/flux-pro/kontext/max'),
151
+ model: fal.image('fal-ai/flux-general/inpainting'),
152
152
  prompt: {
153
153
  text: 'Put a donut next to the flour.',
154
154
  images: [imageBuffer],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/fal",
3
- "version": "3.0.48",
3
+ "version": "3.0.51",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,11 +29,11 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.18",
33
- "@ai-sdk/provider-utils": "5.0.47"
32
+ "@ai-sdk/provider": "4.0.19",
33
+ "@ai-sdk/provider-utils": "5.0.50"
34
34
  },
35
35
  "devDependencies": {
36
- "@ai-sdk/test-server": "2.0.1",
36
+ "@ai-sdk/test-server": "2.0.2",
37
37
  "@types/node": "22.19.19",
38
38
  "@vercel/ai-tsconfig": "0.0.0",
39
39
  "tsup": "^8.5.1",
@@ -34,6 +34,50 @@ export class FalImageModel implements ImageModelV4 {
34
34
  readonly specificationVersion = 'v4';
35
35
  readonly maxImagesPerCall = 1;
36
36
 
37
+ get supportsFileInputs(): boolean | undefined {
38
+ if (
39
+ [
40
+ 'fal-ai/flux-2/edit',
41
+ 'fal-ai/flux-pro/kontext',
42
+ 'fal-ai/flux-pro/kontext/max',
43
+ 'fal-ai/flux-general/image-to-image',
44
+ 'fal-ai/flux-general/inpainting',
45
+ 'fal-ai/flux-lora/image-to-image',
46
+ 'fal-ai/flux-lora/inpainting',
47
+ 'fal-ai/flux/dev/image-to-image',
48
+ 'fal-ai/flux/krea/image-to-image',
49
+ 'fal-ai/recraft/v3/image-to-image',
50
+ ].includes(this.modelId)
51
+ ) {
52
+ return true;
53
+ }
54
+
55
+ return [
56
+ 'bria/text-to-image/3.2',
57
+ 'fal-ai/bria/text-to-image/base',
58
+ 'fal-ai/bria/text-to-image/fast',
59
+ 'fal-ai/bria/text-to-image/hd',
60
+ 'fal-ai/bytedance/dreamina/v3.1/text-to-image',
61
+ 'fal-ai/flux-kontext-lora/text-to-image',
62
+ 'fal-ai/recraft/v3/text-to-image',
63
+ 'fal-ai/wan/v2.2-5b/text-to-image',
64
+ 'fal-ai/wan/v2.2-a14b/text-to-image',
65
+ ].includes(this.modelId)
66
+ ? false
67
+ : undefined;
68
+ }
69
+
70
+ get supportsMaskInputs(): boolean | undefined {
71
+ if (
72
+ this.modelId === 'fal-ai/flux-general/inpainting' ||
73
+ this.modelId === 'fal-ai/flux-lora/inpainting'
74
+ ) {
75
+ return true;
76
+ }
77
+
78
+ return this.supportsFileInputs == null ? undefined : false;
79
+ }
80
+
37
81
  get provider(): string {
38
82
  return this.config.provider;
39
83
  }