@ai-sdk/fal 3.0.18 → 3.0.20
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 +25 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +130 -77
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/fal-video-model-options.ts +0 -6
- package/src/fal-video-model.ts +186 -81
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @ai-sdk/fal
|
|
2
2
|
|
|
3
|
+
## 3.0.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 79e133c: async APIs for generateVideo (poll, webhook)
|
|
8
|
+
|
|
9
|
+
Adds an asynchronous start/status flow to the experimental video model
|
|
10
|
+
interface (`VideoModelV4`): models may now implement `doStart`, `doStatus`,
|
|
11
|
+
and `handleWebhookOption` instead of (or in addition to) `doGenerate`, and
|
|
12
|
+
`experimental_generateVideo` accepts `poll` and `webhook` options to
|
|
13
|
+
orchestrate completion via polling or webhooks. Polling configuration can use
|
|
14
|
+
a custom delay implementation for durable workflow compatibility.
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [79e133c]
|
|
17
|
+
- @ai-sdk/provider@4.0.5
|
|
18
|
+
- @ai-sdk/provider-utils@5.0.19
|
|
19
|
+
|
|
20
|
+
## 3.0.19
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [5fc7da5]
|
|
25
|
+
- Updated dependencies [93b2acd]
|
|
26
|
+
- @ai-sdk/provider-utils@5.0.18
|
|
27
|
+
|
|
3
28
|
## 3.0.18
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -143,8 +143,6 @@ type FalTranscriptionModelOptions = z.infer<typeof falTranscriptionModelOptionsS
|
|
|
143
143
|
type FalVideoModelOptions = {
|
|
144
144
|
loop?: boolean | null;
|
|
145
145
|
motionStrength?: number | null;
|
|
146
|
-
pollIntervalMs?: number | null;
|
|
147
|
-
pollTimeoutMs?: number | null;
|
|
148
146
|
resolution?: string | null;
|
|
149
147
|
negativePrompt?: string | null;
|
|
150
148
|
promptOptimizer?: boolean | null;
|
package/dist/index.js
CHANGED
|
@@ -827,14 +827,14 @@ var falSpeechResponseSchema = z7.object({
|
|
|
827
827
|
|
|
828
828
|
// src/fal-video-model.ts
|
|
829
829
|
import {
|
|
830
|
-
AISDKError as AISDKError2
|
|
830
|
+
AISDKError as AISDKError2,
|
|
831
|
+
APICallError
|
|
831
832
|
} from "@ai-sdk/provider";
|
|
832
833
|
import {
|
|
833
834
|
combineHeaders as combineHeaders4,
|
|
834
835
|
convertImageModelFileToDataUri as convertImageModelFileToDataUri2,
|
|
835
836
|
createJsonErrorResponseHandler as createJsonErrorResponseHandler4,
|
|
836
837
|
createJsonResponseHandler as createJsonResponseHandler4,
|
|
837
|
-
delay as delay2,
|
|
838
838
|
getFromApi as getFromApi4,
|
|
839
839
|
parseProviderOptions as parseProviderOptions4,
|
|
840
840
|
postJsonToApi as postJsonToApi4
|
|
@@ -851,9 +851,6 @@ var falVideoModelOptionsSchema = lazySchema2(
|
|
|
851
851
|
loop: z8.boolean().nullish(),
|
|
852
852
|
// Motion strength (provider-specific)
|
|
853
853
|
motionStrength: z8.number().min(0).max(1).nullish(),
|
|
854
|
-
// Polling configuration
|
|
855
|
-
pollIntervalMs: z8.number().positive().nullish(),
|
|
856
|
-
pollTimeoutMs: z8.number().positive().nullish(),
|
|
857
854
|
// Resolution (model-specific, e.g., '480p', '720p', '1080p')
|
|
858
855
|
resolution: z8.string().nullish(),
|
|
859
856
|
// Model-specific parameters
|
|
@@ -878,10 +875,76 @@ var FalVideoModel = class {
|
|
|
878
875
|
get normalizedModelId() {
|
|
879
876
|
return this.modelId.replace(/^fal-ai\//, "").replace(/^fal\//, "");
|
|
880
877
|
}
|
|
881
|
-
async
|
|
882
|
-
|
|
878
|
+
async handleWebhookOption(options) {
|
|
879
|
+
const { url, received } = await options.webhook();
|
|
880
|
+
return { webhookUrl: url, received };
|
|
881
|
+
}
|
|
882
|
+
async doStart(options) {
|
|
883
|
+
var _a, _b, _c;
|
|
883
884
|
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
884
885
|
const warnings = [];
|
|
886
|
+
const { body } = await this.buildRequestBody(options);
|
|
887
|
+
const { responseUrl, submitUrl } = await this.submitToQueue(
|
|
888
|
+
{
|
|
889
|
+
headers: options.headers,
|
|
890
|
+
abortSignal: options.abortSignal,
|
|
891
|
+
webhookUrl: options.webhookUrl
|
|
892
|
+
},
|
|
893
|
+
body
|
|
894
|
+
);
|
|
895
|
+
return {
|
|
896
|
+
operation: { responseUrl, submitUrl },
|
|
897
|
+
warnings,
|
|
898
|
+
response: {
|
|
899
|
+
timestamp: currentDate,
|
|
900
|
+
modelId: this.modelId,
|
|
901
|
+
headers: void 0
|
|
902
|
+
}
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
async doStatus(options) {
|
|
906
|
+
var _a, _b, _c;
|
|
907
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
908
|
+
const { responseUrl, submitUrl } = options.operation;
|
|
909
|
+
try {
|
|
910
|
+
const { value: response, responseHeaders } = await this.fetchStatus({
|
|
911
|
+
responseUrl,
|
|
912
|
+
submitUrl,
|
|
913
|
+
headers: options.headers,
|
|
914
|
+
abortSignal: options.abortSignal
|
|
915
|
+
});
|
|
916
|
+
return this.buildResult({
|
|
917
|
+
response,
|
|
918
|
+
responseHeaders,
|
|
919
|
+
warnings: [],
|
|
920
|
+
currentDate
|
|
921
|
+
});
|
|
922
|
+
} catch (error) {
|
|
923
|
+
if (error instanceof Error && error.message === "Request is still in progress") {
|
|
924
|
+
return {
|
|
925
|
+
status: "pending",
|
|
926
|
+
response: {
|
|
927
|
+
timestamp: currentDate,
|
|
928
|
+
modelId: this.modelId,
|
|
929
|
+
headers: void 0
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
if (APICallError.isInstance(error)) {
|
|
934
|
+
return {
|
|
935
|
+
status: "error",
|
|
936
|
+
error: error.message,
|
|
937
|
+
response: {
|
|
938
|
+
timestamp: currentDate,
|
|
939
|
+
modelId: this.modelId,
|
|
940
|
+
headers: error.responseHeaders
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
throw error;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
async buildRequestBody(options) {
|
|
885
948
|
const falOptions = await parseProviderOptions4({
|
|
886
949
|
provider: "fal",
|
|
887
950
|
providerOptions: options.providerOptions,
|
|
@@ -928,8 +991,6 @@ var FalVideoModel = class {
|
|
|
928
991
|
if (![
|
|
929
992
|
"loop",
|
|
930
993
|
"motionStrength",
|
|
931
|
-
"pollIntervalMs",
|
|
932
|
-
"pollTimeoutMs",
|
|
933
994
|
"resolution",
|
|
934
995
|
"negativePrompt",
|
|
935
996
|
"promptOptimizer"
|
|
@@ -938,13 +999,21 @@ var FalVideoModel = class {
|
|
|
938
999
|
}
|
|
939
1000
|
}
|
|
940
1001
|
}
|
|
1002
|
+
return { body, falOptions };
|
|
1003
|
+
}
|
|
1004
|
+
async submitToQueue(options, body) {
|
|
1005
|
+
var _a, _b;
|
|
1006
|
+
let queuePath = `https://queue.fal.run/fal-ai/${this.normalizedModelId}`;
|
|
1007
|
+
if (options.webhookUrl) {
|
|
1008
|
+
queuePath += `?fal_webhook=${encodeURIComponent(options.webhookUrl)}`;
|
|
1009
|
+
}
|
|
941
1010
|
const submitUrl = this.config.url({
|
|
942
|
-
path:
|
|
1011
|
+
path: queuePath,
|
|
943
1012
|
modelId: this.modelId
|
|
944
1013
|
});
|
|
945
1014
|
const { value: queueResponse } = await postJsonToApi4({
|
|
946
1015
|
url: submitUrl,
|
|
947
|
-
headers: combineHeaders4((
|
|
1016
|
+
headers: combineHeaders4((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
|
|
948
1017
|
body,
|
|
949
1018
|
failedResponseHandler: falFailedResponseHandler2,
|
|
950
1019
|
successfulResponseHandler: createJsonResponseHandler4(falJobResponseSchema2),
|
|
@@ -958,72 +1027,55 @@ var FalVideoModel = class {
|
|
|
958
1027
|
message: "No response URL returned from queue endpoint"
|
|
959
1028
|
});
|
|
960
1029
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
responseHeaders: {}
|
|
990
|
-
};
|
|
991
|
-
}
|
|
992
|
-
return createJsonErrorResponseHandler4({
|
|
993
|
-
errorSchema: falErrorDataSchema,
|
|
994
|
-
errorToMessage: (data) => data.error.message
|
|
995
|
-
})({ response: response2, url, requestBodyValues });
|
|
996
|
-
},
|
|
997
|
-
successfulResponseHandler: createJsonResponseHandler4(
|
|
998
|
-
falVideoResponseSchema
|
|
999
|
-
),
|
|
1000
|
-
abortSignal: options.abortSignal,
|
|
1001
|
-
fetch: this.config.fetch
|
|
1002
|
-
});
|
|
1003
|
-
response = statusResponse;
|
|
1004
|
-
responseHeaders = statusHeaders;
|
|
1005
|
-
break;
|
|
1006
|
-
} catch (error) {
|
|
1007
|
-
if (error instanceof Error && error.message === "Request is still in progress") {
|
|
1008
|
-
} else {
|
|
1009
|
-
throw error;
|
|
1030
|
+
return { responseUrl, submitUrl };
|
|
1031
|
+
}
|
|
1032
|
+
async fetchStatus({
|
|
1033
|
+
responseUrl,
|
|
1034
|
+
submitUrl,
|
|
1035
|
+
headers,
|
|
1036
|
+
abortSignal
|
|
1037
|
+
}) {
|
|
1038
|
+
var _a, _b;
|
|
1039
|
+
const statusUrl = this.config.url({
|
|
1040
|
+
path: responseUrl,
|
|
1041
|
+
modelId: this.modelId
|
|
1042
|
+
});
|
|
1043
|
+
return getFromApi4({
|
|
1044
|
+
url: statusUrl,
|
|
1045
|
+
// statusUrl comes from the queue response body.
|
|
1046
|
+
validateUrl: true,
|
|
1047
|
+
credentialedOrigin: submitUrl,
|
|
1048
|
+
trustedOrigin: submitUrl,
|
|
1049
|
+
headers: combineHeaders4((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), headers),
|
|
1050
|
+
failedResponseHandler: async ({ response, url, requestBodyValues }) => {
|
|
1051
|
+
const body = await response.clone().json();
|
|
1052
|
+
if (body.detail === "Request is still in progress") {
|
|
1053
|
+
return {
|
|
1054
|
+
value: new Error("Request is still in progress"),
|
|
1055
|
+
rawValue: body,
|
|
1056
|
+
responseHeaders: {}
|
|
1057
|
+
};
|
|
1010
1058
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1059
|
+
return createJsonErrorResponseHandler4({
|
|
1060
|
+
errorSchema: falErrorDataSchema,
|
|
1061
|
+
errorToMessage: (data) => data.error.message
|
|
1062
|
+
})({ response, url, requestBodyValues });
|
|
1063
|
+
},
|
|
1064
|
+
successfulResponseHandler: createJsonResponseHandler4(
|
|
1065
|
+
falVideoResponseSchema
|
|
1066
|
+
),
|
|
1067
|
+
abortSignal,
|
|
1068
|
+
fetch: this.config.fetch
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
buildResult({
|
|
1072
|
+
response,
|
|
1073
|
+
responseHeaders,
|
|
1074
|
+
warnings,
|
|
1075
|
+
currentDate
|
|
1076
|
+
}) {
|
|
1077
|
+
var _a;
|
|
1078
|
+
const videoUrl = (_a = response.video) == null ? void 0 : _a.url;
|
|
1027
1079
|
if (!videoUrl || !response.video) {
|
|
1028
1080
|
throw new AISDKError2({
|
|
1029
1081
|
name: "FAL_VIDEO_GENERATION_ERROR",
|
|
@@ -1031,6 +1083,7 @@ var FalVideoModel = class {
|
|
|
1031
1083
|
});
|
|
1032
1084
|
}
|
|
1033
1085
|
return {
|
|
1086
|
+
status: "completed",
|
|
1034
1087
|
videos: [
|
|
1035
1088
|
{
|
|
1036
1089
|
type: "url",
|
|
@@ -1087,7 +1140,7 @@ var falVideoResponseSchema = z9.object({
|
|
|
1087
1140
|
});
|
|
1088
1141
|
|
|
1089
1142
|
// src/version.ts
|
|
1090
|
-
var VERSION = true ? "3.0.
|
|
1143
|
+
var VERSION = true ? "3.0.20" : "0.0.0-test";
|
|
1091
1144
|
|
|
1092
1145
|
// src/fal-provider.ts
|
|
1093
1146
|
var defaultBaseURL = "https://fal.run";
|
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 return undefined;\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 type Experimental_VideoModelV4,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertImageModelFileToDataUri,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n delay,\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 Experimental_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 doGenerate(\n options: Parameters<Experimental_VideoModelV4['doGenerate']>[0],\n ): Promise<Awaited<ReturnType<Experimental_VideoModelV4['doGenerate']>>> {\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const warnings: SharedV4Warning[] = [];\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 'pollIntervalMs',\n 'pollTimeoutMs',\n 'resolution',\n 'negativePrompt',\n 'promptOptimizer',\n ].includes(key)\n ) {\n body[key] = value;\n }\n }\n }\n\n const submitUrl = this.config.url({\n path: `https://queue.fal.run/fal-ai/${this.normalizedModelId}`,\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 const pollIntervalMs = falOptions?.pollIntervalMs ?? 2000; // 2 seconds\n const pollTimeoutMs = falOptions?.pollTimeoutMs ?? 300000; // 5 minutes\n const startTime = Date.now();\n let response: FalVideoResponse;\n let responseHeaders: Record<string, string> | undefined;\n\n while (true) {\n try {\n const statusUrl = this.config.url({\n path: responseUrl,\n modelId: this.modelId,\n });\n const { value: statusResponse, responseHeaders: statusHeaders } =\n await 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?.(), options.headers),\n failedResponseHandler: async ({\n response,\n url,\n requestBodyValues,\n }) => {\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: options.abortSignal,\n fetch: this.config.fetch,\n });\n\n response = statusResponse;\n responseHeaders = statusHeaders;\n break;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message === 'Request is still in progress'\n ) {\n // Continue polling\n } else {\n throw error;\n }\n }\n\n if (Date.now() - startTime > pollTimeoutMs) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_TIMEOUT',\n message: `Video generation request timed out after ${pollTimeoutMs}ms`,\n });\n }\n\n await delay(pollIntervalMs);\n\n if (options.abortSignal?.aborted) {\n throw new AISDKError({\n name: 'FAL_VIDEO_GENERATION_ABORTED',\n message: 'Video generation request was aborted',\n });\n }\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 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 pollIntervalMs?: number | null;\n pollTimeoutMs?: 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 // Polling configuration\n pollIntervalMs: z.number().positive().nullish(),\n pollTimeoutMs: z.number().positive().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","delay","getFromApi","parseProviderOptions","postJsonToApi","z","lazySchema","zodSchema","z","parseProviderOptions","convertImageModelFileToDataUri","postJsonToApi","combineHeaders","falFailedResponseHandler","createJsonResponseHandler","falJobResponseSchema","AISDKError","getFromApi","response","body","createJsonErrorResponseHandler","delay","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 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 return undefined;\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,\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\ntype VideoModelV4 = Experimental_VideoModelV4;\n\ninterface FalVideoModelConfig extends FalConfig {\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class FalVideoModel implements Experimental_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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/fal",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ai-sdk/provider
|
|
33
|
-
"@ai-sdk/provider": "
|
|
32
|
+
"@ai-sdk/provider": "4.0.5",
|
|
33
|
+
"@ai-sdk/provider-utils": "5.0.19"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "22.19.19",
|
|
@@ -4,8 +4,6 @@ import { z } from 'zod/v4';
|
|
|
4
4
|
export type FalVideoModelOptions = {
|
|
5
5
|
loop?: boolean | null;
|
|
6
6
|
motionStrength?: number | null;
|
|
7
|
-
pollIntervalMs?: number | null;
|
|
8
|
-
pollTimeoutMs?: number | null;
|
|
9
7
|
resolution?: string | null;
|
|
10
8
|
negativePrompt?: string | null;
|
|
11
9
|
promptOptimizer?: boolean | null;
|
|
@@ -22,10 +20,6 @@ export const falVideoModelOptionsSchema = lazySchema(() =>
|
|
|
22
20
|
// Motion strength (provider-specific)
|
|
23
21
|
motionStrength: z.number().min(0).max(1).nullish(),
|
|
24
22
|
|
|
25
|
-
// Polling configuration
|
|
26
|
-
pollIntervalMs: z.number().positive().nullish(),
|
|
27
|
-
pollTimeoutMs: z.number().positive().nullish(),
|
|
28
|
-
|
|
29
23
|
// Resolution (model-specific, e.g., '480p', '720p', '1080p')
|
|
30
24
|
resolution: z.string().nullish(),
|
|
31
25
|
|
package/src/fal-video-model.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AISDKError,
|
|
3
|
+
APICallError,
|
|
3
4
|
type Experimental_VideoModelV4,
|
|
5
|
+
type Experimental_VideoModelV4OperationStartResult as VideoModelV4OperationStartResult,
|
|
6
|
+
type Experimental_VideoModelV4OperationStatusResult as VideoModelV4OperationStatusResult,
|
|
7
|
+
type SharedV4ProviderMetadata,
|
|
4
8
|
type SharedV4Warning,
|
|
5
9
|
} from '@ai-sdk/provider';
|
|
6
10
|
import {
|
|
@@ -8,7 +12,6 @@ import {
|
|
|
8
12
|
convertImageModelFileToDataUri,
|
|
9
13
|
createJsonErrorResponseHandler,
|
|
10
14
|
createJsonResponseHandler,
|
|
11
|
-
delay,
|
|
12
15
|
getFromApi,
|
|
13
16
|
parseProviderOptions,
|
|
14
17
|
postJsonToApi,
|
|
@@ -22,6 +25,8 @@ import {
|
|
|
22
25
|
} from './fal-video-model-options';
|
|
23
26
|
import type { FalVideoModelId } from './fal-video-settings';
|
|
24
27
|
|
|
28
|
+
type VideoModelV4 = Experimental_VideoModelV4;
|
|
29
|
+
|
|
25
30
|
interface FalVideoModelConfig extends FalConfig {
|
|
26
31
|
_internal?: {
|
|
27
32
|
currentDate?: () => Date;
|
|
@@ -45,12 +50,101 @@ export class FalVideoModel implements Experimental_VideoModelV4 {
|
|
|
45
50
|
private readonly config: FalVideoModelConfig,
|
|
46
51
|
) {}
|
|
47
52
|
|
|
48
|
-
async
|
|
49
|
-
options: Parameters<
|
|
50
|
-
)
|
|
53
|
+
async handleWebhookOption(
|
|
54
|
+
options: Parameters<NonNullable<VideoModelV4['handleWebhookOption']>>[0],
|
|
55
|
+
) {
|
|
56
|
+
const { url, received } = await options.webhook();
|
|
57
|
+
return { webhookUrl: url, received };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async doStart(
|
|
61
|
+
options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],
|
|
62
|
+
): Promise<VideoModelV4OperationStartResult> {
|
|
51
63
|
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
52
64
|
const warnings: SharedV4Warning[] = [];
|
|
53
65
|
|
|
66
|
+
const { body } = await this.buildRequestBody(options);
|
|
67
|
+
|
|
68
|
+
const { responseUrl, submitUrl } = await this.submitToQueue(
|
|
69
|
+
{
|
|
70
|
+
headers: options.headers,
|
|
71
|
+
abortSignal: options.abortSignal,
|
|
72
|
+
webhookUrl: options.webhookUrl,
|
|
73
|
+
},
|
|
74
|
+
body,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
operation: { responseUrl, submitUrl },
|
|
79
|
+
warnings,
|
|
80
|
+
response: {
|
|
81
|
+
timestamp: currentDate,
|
|
82
|
+
modelId: this.modelId,
|
|
83
|
+
headers: undefined,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async doStatus(
|
|
89
|
+
options: Parameters<NonNullable<VideoModelV4['doStatus']>>[0],
|
|
90
|
+
): Promise<VideoModelV4OperationStatusResult> {
|
|
91
|
+
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
92
|
+
const { responseUrl, submitUrl } = options.operation as {
|
|
93
|
+
responseUrl: string;
|
|
94
|
+
submitUrl: string;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const { value: response, responseHeaders } = await this.fetchStatus({
|
|
99
|
+
responseUrl,
|
|
100
|
+
submitUrl,
|
|
101
|
+
headers: options.headers,
|
|
102
|
+
abortSignal: options.abortSignal,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return this.buildResult({
|
|
106
|
+
response,
|
|
107
|
+
responseHeaders,
|
|
108
|
+
warnings: [],
|
|
109
|
+
currentDate,
|
|
110
|
+
});
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (
|
|
113
|
+
error instanceof Error &&
|
|
114
|
+
error.message === 'Request is still in progress'
|
|
115
|
+
) {
|
|
116
|
+
return {
|
|
117
|
+
status: 'pending' as const,
|
|
118
|
+
response: {
|
|
119
|
+
timestamp: currentDate,
|
|
120
|
+
modelId: this.modelId,
|
|
121
|
+
headers: undefined,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (APICallError.isInstance(error)) {
|
|
127
|
+
return {
|
|
128
|
+
status: 'error' as const,
|
|
129
|
+
error: error.message,
|
|
130
|
+
response: {
|
|
131
|
+
timestamp: currentDate,
|
|
132
|
+
modelId: this.modelId,
|
|
133
|
+
headers: error.responseHeaders,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private async buildRequestBody(
|
|
143
|
+
options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],
|
|
144
|
+
): Promise<{
|
|
145
|
+
body: Record<string, unknown>;
|
|
146
|
+
falOptions: FalVideoModelOptions | undefined;
|
|
147
|
+
}> {
|
|
54
148
|
const falOptions = (await parseProviderOptions({
|
|
55
149
|
provider: 'fal',
|
|
56
150
|
providerOptions: options.providerOptions,
|
|
@@ -106,8 +200,6 @@ export class FalVideoModel implements Experimental_VideoModelV4 {
|
|
|
106
200
|
![
|
|
107
201
|
'loop',
|
|
108
202
|
'motionStrength',
|
|
109
|
-
'pollIntervalMs',
|
|
110
|
-
'pollTimeoutMs',
|
|
111
203
|
'resolution',
|
|
112
204
|
'negativePrompt',
|
|
113
205
|
'promptOptimizer',
|
|
@@ -118,8 +210,24 @@ export class FalVideoModel implements Experimental_VideoModelV4 {
|
|
|
118
210
|
}
|
|
119
211
|
}
|
|
120
212
|
|
|
213
|
+
return { body, falOptions };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private async submitToQueue(
|
|
217
|
+
options: {
|
|
218
|
+
headers?: Record<string, string | undefined>;
|
|
219
|
+
abortSignal?: AbortSignal;
|
|
220
|
+
webhookUrl?: string;
|
|
221
|
+
},
|
|
222
|
+
body: Record<string, unknown>,
|
|
223
|
+
): Promise<{ responseUrl: string; submitUrl: string }> {
|
|
224
|
+
let queuePath = `https://queue.fal.run/fal-ai/${this.normalizedModelId}`;
|
|
225
|
+
if (options.webhookUrl) {
|
|
226
|
+
queuePath += `?fal_webhook=${encodeURIComponent(options.webhookUrl)}`;
|
|
227
|
+
}
|
|
228
|
+
|
|
121
229
|
const submitUrl = this.config.url({
|
|
122
|
-
path:
|
|
230
|
+
path: queuePath,
|
|
123
231
|
modelId: this.modelId,
|
|
124
232
|
});
|
|
125
233
|
const { value: queueResponse } = await postJsonToApi({
|
|
@@ -141,84 +249,80 @@ export class FalVideoModel implements Experimental_VideoModelV4 {
|
|
|
141
249
|
});
|
|
142
250
|
}
|
|
143
251
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const startTime = Date.now();
|
|
147
|
-
let response: FalVideoResponse;
|
|
148
|
-
let responseHeaders: Record<string, string> | undefined;
|
|
149
|
-
|
|
150
|
-
while (true) {
|
|
151
|
-
try {
|
|
152
|
-
const statusUrl = this.config.url({
|
|
153
|
-
path: responseUrl,
|
|
154
|
-
modelId: this.modelId,
|
|
155
|
-
});
|
|
156
|
-
const { value: statusResponse, responseHeaders: statusHeaders } =
|
|
157
|
-
await getFromApi({
|
|
158
|
-
url: statusUrl,
|
|
159
|
-
// statusUrl comes from the queue response body.
|
|
160
|
-
validateUrl: true,
|
|
161
|
-
credentialedOrigin: submitUrl,
|
|
162
|
-
trustedOrigin: submitUrl,
|
|
163
|
-
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
164
|
-
failedResponseHandler: async ({
|
|
165
|
-
response,
|
|
166
|
-
url,
|
|
167
|
-
requestBodyValues,
|
|
168
|
-
}) => {
|
|
169
|
-
const body = await response.clone().json();
|
|
170
|
-
|
|
171
|
-
if (body.detail === 'Request is still in progress') {
|
|
172
|
-
return {
|
|
173
|
-
value: new Error('Request is still in progress'),
|
|
174
|
-
rawValue: body,
|
|
175
|
-
responseHeaders: {},
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return createJsonErrorResponseHandler({
|
|
180
|
-
errorSchema: falErrorDataSchema,
|
|
181
|
-
errorToMessage: data => data.error.message,
|
|
182
|
-
})({ response, url, requestBodyValues });
|
|
183
|
-
},
|
|
184
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
185
|
-
falVideoResponseSchema,
|
|
186
|
-
),
|
|
187
|
-
abortSignal: options.abortSignal,
|
|
188
|
-
fetch: this.config.fetch,
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
response = statusResponse;
|
|
192
|
-
responseHeaders = statusHeaders;
|
|
193
|
-
break;
|
|
194
|
-
} catch (error) {
|
|
195
|
-
if (
|
|
196
|
-
error instanceof Error &&
|
|
197
|
-
error.message === 'Request is still in progress'
|
|
198
|
-
) {
|
|
199
|
-
// Continue polling
|
|
200
|
-
} else {
|
|
201
|
-
throw error;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
252
|
+
return { responseUrl, submitUrl };
|
|
253
|
+
}
|
|
204
254
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
255
|
+
private async fetchStatus({
|
|
256
|
+
responseUrl,
|
|
257
|
+
submitUrl,
|
|
258
|
+
headers,
|
|
259
|
+
abortSignal,
|
|
260
|
+
}: {
|
|
261
|
+
responseUrl: string;
|
|
262
|
+
submitUrl: string;
|
|
263
|
+
headers?: Record<string, string | undefined>;
|
|
264
|
+
abortSignal?: AbortSignal;
|
|
265
|
+
}): Promise<{
|
|
266
|
+
value: FalVideoResponse;
|
|
267
|
+
responseHeaders?: Record<string, string>;
|
|
268
|
+
}> {
|
|
269
|
+
const statusUrl = this.config.url({
|
|
270
|
+
path: responseUrl,
|
|
271
|
+
modelId: this.modelId,
|
|
272
|
+
});
|
|
211
273
|
|
|
212
|
-
|
|
274
|
+
return getFromApi({
|
|
275
|
+
url: statusUrl,
|
|
276
|
+
// statusUrl comes from the queue response body.
|
|
277
|
+
validateUrl: true,
|
|
278
|
+
credentialedOrigin: submitUrl,
|
|
279
|
+
trustedOrigin: submitUrl,
|
|
280
|
+
headers: combineHeaders(this.config.headers?.(), headers),
|
|
281
|
+
failedResponseHandler: async ({ response, url, requestBodyValues }) => {
|
|
282
|
+
const body = await response.clone().json();
|
|
213
283
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
284
|
+
if (body.detail === 'Request is still in progress') {
|
|
285
|
+
return {
|
|
286
|
+
value: new Error('Request is still in progress'),
|
|
287
|
+
rawValue: body,
|
|
288
|
+
responseHeaders: {},
|
|
289
|
+
};
|
|
290
|
+
}
|
|
221
291
|
|
|
292
|
+
return createJsonErrorResponseHandler({
|
|
293
|
+
errorSchema: falErrorDataSchema,
|
|
294
|
+
errorToMessage: data => data.error.message,
|
|
295
|
+
})({ response, url, requestBodyValues });
|
|
296
|
+
},
|
|
297
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
298
|
+
falVideoResponseSchema,
|
|
299
|
+
),
|
|
300
|
+
abortSignal,
|
|
301
|
+
fetch: this.config.fetch,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private buildResult({
|
|
306
|
+
response,
|
|
307
|
+
responseHeaders,
|
|
308
|
+
warnings,
|
|
309
|
+
currentDate,
|
|
310
|
+
}: {
|
|
311
|
+
response: FalVideoResponse;
|
|
312
|
+
responseHeaders?: Record<string, string>;
|
|
313
|
+
warnings: SharedV4Warning[];
|
|
314
|
+
currentDate: Date;
|
|
315
|
+
}): {
|
|
316
|
+
status: 'completed';
|
|
317
|
+
videos: Array<{ type: 'url'; url: string; mediaType: string }>;
|
|
318
|
+
warnings: SharedV4Warning[];
|
|
319
|
+
providerMetadata: SharedV4ProviderMetadata;
|
|
320
|
+
response: {
|
|
321
|
+
timestamp: Date;
|
|
322
|
+
modelId: string;
|
|
323
|
+
headers: Record<string, string> | undefined;
|
|
324
|
+
};
|
|
325
|
+
} {
|
|
222
326
|
const videoUrl = response.video?.url;
|
|
223
327
|
|
|
224
328
|
if (!videoUrl || !response.video) {
|
|
@@ -229,6 +333,7 @@ export class FalVideoModel implements Experimental_VideoModelV4 {
|
|
|
229
333
|
}
|
|
230
334
|
|
|
231
335
|
return {
|
|
336
|
+
status: 'completed',
|
|
232
337
|
videos: [
|
|
233
338
|
{
|
|
234
339
|
type: 'url',
|