@howells/motif-sdk 0.4.0 → 0.5.1
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/README.md +8 -2
- package/dist/index.cjs +1430 -1108
- package/dist/index.d.cts +505 -505
- package/dist/index.d.ts +505 -505
- package/dist/index.js +1430 -1108
- package/package.json +21 -21
package/dist/index.cjs
CHANGED
|
@@ -81,62 +81,80 @@ var ASPECT_RATIOS = [
|
|
|
81
81
|
var RESOLUTIONS = ["0.5K", "1K", "2K", "4K"];
|
|
82
82
|
function aspectToGptSize(aspect) {
|
|
83
83
|
switch (aspect) {
|
|
84
|
-
case "auto":
|
|
84
|
+
case "auto": {
|
|
85
85
|
return "auto";
|
|
86
|
+
}
|
|
86
87
|
case "9:16":
|
|
87
88
|
case "1:8":
|
|
88
89
|
case "1:4":
|
|
89
90
|
case "2:3":
|
|
90
91
|
case "4:5":
|
|
91
|
-
case "3:4":
|
|
92
|
+
case "3:4": {
|
|
92
93
|
return "1024x1536";
|
|
94
|
+
}
|
|
93
95
|
case "16:9":
|
|
94
96
|
case "8:1":
|
|
95
97
|
case "4:1":
|
|
96
98
|
case "3:2":
|
|
97
99
|
case "5:4":
|
|
98
100
|
case "4:3":
|
|
99
|
-
case "21:9":
|
|
101
|
+
case "21:9": {
|
|
100
102
|
return "1536x1024";
|
|
101
|
-
|
|
103
|
+
}
|
|
104
|
+
case "1:1": {
|
|
102
105
|
return "1024x1024";
|
|
106
|
+
}
|
|
107
|
+
default: {
|
|
108
|
+
return "1024x1024";
|
|
109
|
+
}
|
|
103
110
|
}
|
|
104
111
|
}
|
|
105
112
|
function aspectToFalImageSize(aspect) {
|
|
106
113
|
switch (aspect) {
|
|
107
|
-
case "auto":
|
|
114
|
+
case "auto": {
|
|
108
115
|
return "auto";
|
|
116
|
+
}
|
|
109
117
|
case "16:9":
|
|
110
118
|
case "21:9":
|
|
111
119
|
case "4:1":
|
|
112
|
-
case "8:1":
|
|
120
|
+
case "8:1": {
|
|
113
121
|
return "landscape_16_9";
|
|
122
|
+
}
|
|
114
123
|
case "3:2":
|
|
115
|
-
case "5:4":
|
|
124
|
+
case "5:4": {
|
|
116
125
|
return "landscape_4_3";
|
|
117
|
-
|
|
126
|
+
}
|
|
127
|
+
case "4:3": {
|
|
118
128
|
return "landscape_4_3";
|
|
129
|
+
}
|
|
119
130
|
case "9:16":
|
|
120
131
|
case "1:4":
|
|
121
|
-
case "1:8":
|
|
132
|
+
case "1:8": {
|
|
122
133
|
return "portrait_16_9";
|
|
134
|
+
}
|
|
123
135
|
case "2:3":
|
|
124
|
-
case "4:5":
|
|
136
|
+
case "4:5": {
|
|
125
137
|
return "portrait_4_3";
|
|
126
|
-
|
|
138
|
+
}
|
|
139
|
+
case "3:4": {
|
|
127
140
|
return "portrait_4_3";
|
|
128
|
-
|
|
141
|
+
}
|
|
142
|
+
case "1:1": {
|
|
143
|
+
return "square_hd";
|
|
144
|
+
}
|
|
145
|
+
default: {
|
|
129
146
|
return "square_hd";
|
|
147
|
+
}
|
|
130
148
|
}
|
|
131
149
|
}
|
|
132
150
|
var FORMAT_PRESETS = {
|
|
133
|
-
cover: {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
portrait: {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
wide: {
|
|
151
|
+
cover: { aspect: "2:3", label: "Cover", resolution: "2K" },
|
|
152
|
+
landscape: { aspect: "16:9", label: "Landscape" },
|
|
153
|
+
og: { aspect: "16:9", label: "OG Image" },
|
|
154
|
+
portrait: { aspect: "2:3", label: "Portrait" },
|
|
155
|
+
square: { aspect: "1:1", label: "Square" },
|
|
156
|
+
story: { aspect: "9:16", label: "Story" },
|
|
157
|
+
wide: { aspect: "21:9", label: "Wide" }
|
|
140
158
|
};
|
|
141
159
|
|
|
142
160
|
// src/models.ts
|
|
@@ -146,305 +164,332 @@ var AA_IMAGE_SOURCES = [
|
|
|
146
164
|
"https://artificialanalysis.ai/image/leaderboard/editing"
|
|
147
165
|
];
|
|
148
166
|
var FAL_PRICING_CHECKED_AT = "2026-05-12";
|
|
167
|
+
var FAL_PRICING_CHECKED_JUL_2026 = "2026-07-11";
|
|
149
168
|
var MODELS = {
|
|
150
169
|
// ─── Generation Models ────────────────────────────────────────
|
|
151
170
|
gpt2: {
|
|
152
|
-
name: "GPT Image 2",
|
|
153
|
-
endpoint: "openai/gpt-image-2",
|
|
154
|
-
editEndpoint: "openai/gpt-image-2/image-to-image",
|
|
155
|
-
type: "generation",
|
|
156
|
-
pricing: "$0.211",
|
|
157
|
-
pricePerImageUsd: 0.211,
|
|
158
|
-
falPricing: {
|
|
159
|
-
endpointId: "openai/gpt-image-2",
|
|
160
|
-
unitPrice: 1,
|
|
161
|
-
unit: "units",
|
|
162
|
-
currency: "USD",
|
|
163
|
-
estimatedCostPerImageUsd: 0.211,
|
|
164
|
-
source: "fal-pricing-api",
|
|
165
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
166
|
-
},
|
|
167
171
|
benchmark: {
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
artificialAnalysis: {
|
|
173
|
+
editing: { elo: 1249, pricePer1k: 211, rank: 3, winRate: 0.66 },
|
|
174
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
175
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
176
|
+
textToImage: { elo: 1337, pricePer1k: 211, rank: 1, winRate: 0.8 }
|
|
177
|
+
},
|
|
170
178
|
speed: {
|
|
171
179
|
medianSeconds: 200.7,
|
|
172
180
|
p95Seconds: 232.6,
|
|
173
181
|
source: "artificial-analysis-models"
|
|
174
182
|
},
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
183
|
+
tiers: { price: "ultra", quality: "frontier", speed: "very_slow" },
|
|
184
|
+
useCase: "Highest-ranked text-to-image quality and transparent PNGs"
|
|
185
|
+
},
|
|
186
|
+
editEndpoint: "openai/gpt-image-2/image-to-image",
|
|
187
|
+
endpoint: "openai/gpt-image-2",
|
|
188
|
+
falPricing: {
|
|
189
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
190
|
+
currency: "USD",
|
|
191
|
+
endpointId: "openai/gpt-image-2",
|
|
192
|
+
estimatedCostPerImageUsd: 0.211,
|
|
193
|
+
source: "fal-pricing-api",
|
|
194
|
+
unit: "units",
|
|
195
|
+
unitPrice: 1
|
|
181
196
|
},
|
|
197
|
+
maxReferenceImages: 4,
|
|
198
|
+
name: "GPT Image 2",
|
|
199
|
+
pricePerImageUsd: 0.211,
|
|
200
|
+
pricing: "$0.211",
|
|
182
201
|
sizeMode: "image_size_enum",
|
|
183
202
|
supportsAspect: true,
|
|
184
|
-
supportsResolution: false,
|
|
185
203
|
supportsEdit: true,
|
|
204
|
+
supportsMaskImage: true,
|
|
186
205
|
supportsNumImages: true,
|
|
187
206
|
supportsOutputFormat: true,
|
|
188
207
|
supportsQuality: true,
|
|
189
|
-
|
|
208
|
+
supportsResolution: false,
|
|
190
209
|
supportsSyncMode: true,
|
|
191
|
-
|
|
210
|
+
type: "generation",
|
|
192
211
|
useQueue: true
|
|
193
212
|
},
|
|
194
213
|
gpt: {
|
|
195
|
-
name: "GPT Image 1.5",
|
|
196
|
-
endpoint: "fal-ai/gpt-image-1.5",
|
|
197
|
-
editEndpoint: "fal-ai/gpt-image-1.5/edit",
|
|
198
|
-
type: "generation",
|
|
199
|
-
pricing: "$0.133",
|
|
200
|
-
pricePerImageUsd: 0.133,
|
|
201
|
-
falPricing: {
|
|
202
|
-
endpointId: "fal-ai/gpt-image-1.5",
|
|
203
|
-
unitPrice: 1,
|
|
204
|
-
unit: "units",
|
|
205
|
-
currency: "USD",
|
|
206
|
-
estimatedCostPerImageUsd: 0.133,
|
|
207
|
-
source: "fal-pricing-api",
|
|
208
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
209
|
-
},
|
|
210
214
|
benchmark: {
|
|
211
|
-
|
|
212
|
-
|
|
215
|
+
artificialAnalysis: {
|
|
216
|
+
editing: { elo: 1262, pricePer1k: 133, rank: 2, winRate: 0.69 },
|
|
217
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
218
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
219
|
+
textToImage: { elo: 1268, pricePer1k: 133, rank: 2, winRate: 0.73 }
|
|
220
|
+
},
|
|
213
221
|
speed: {
|
|
214
222
|
medianSeconds: 34.6,
|
|
215
223
|
p95Seconds: 38.3,
|
|
216
224
|
source: "artificial-analysis-models"
|
|
217
225
|
},
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
226
|
+
tiers: { price: "ultra", quality: "frontier", speed: "slow" },
|
|
227
|
+
useCase: "Best OpenAI edit quality with transparent PNG support"
|
|
228
|
+
},
|
|
229
|
+
editEndpoint: "fal-ai/gpt-image-1.5/edit",
|
|
230
|
+
endpoint: "fal-ai/gpt-image-1.5",
|
|
231
|
+
falPricing: {
|
|
232
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
233
|
+
currency: "USD",
|
|
234
|
+
endpointId: "fal-ai/gpt-image-1.5",
|
|
235
|
+
estimatedCostPerImageUsd: 0.133,
|
|
236
|
+
source: "fal-pricing-api",
|
|
237
|
+
unit: "units",
|
|
238
|
+
unitPrice: 1
|
|
224
239
|
},
|
|
240
|
+
maxReferenceImages: 4,
|
|
241
|
+
name: "GPT Image 1.5",
|
|
242
|
+
pricePerImageUsd: 0.133,
|
|
243
|
+
pricing: "$0.133",
|
|
225
244
|
sizeMode: "gpt_size",
|
|
226
245
|
supportsAspect: false,
|
|
227
246
|
supportsBackground: true,
|
|
228
|
-
supportsResolution: false,
|
|
229
247
|
supportsEdit: true,
|
|
248
|
+
supportsMaskImage: true,
|
|
230
249
|
supportsNumImages: true,
|
|
231
250
|
supportsOutputFormat: true,
|
|
232
251
|
supportsQuality: true,
|
|
233
|
-
|
|
252
|
+
supportsResolution: false,
|
|
234
253
|
supportsSyncMode: true,
|
|
235
|
-
|
|
254
|
+
type: "generation"
|
|
236
255
|
},
|
|
237
256
|
banana2: {
|
|
238
|
-
|
|
239
|
-
|
|
257
|
+
benchmark: {
|
|
258
|
+
artificialAnalysis: {
|
|
259
|
+
editing: { elo: 1231, pricePer1k: 67, rank: 5, winRate: 0.63 },
|
|
260
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
261
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
262
|
+
textToImage: { elo: 1263, pricePer1k: 67, rank: 3, winRate: 0.71 }
|
|
263
|
+
},
|
|
264
|
+
tiers: { price: "premium", quality: "frontier", speed: "unknown" },
|
|
265
|
+
useCase: "Best balance of quality, edit support, web search, and cost"
|
|
266
|
+
},
|
|
240
267
|
editEndpoint: "fal-ai/nano-banana-2/edit",
|
|
241
|
-
|
|
242
|
-
pricing: "$0.08",
|
|
243
|
-
pricePerImageUsd: 0.08,
|
|
268
|
+
endpoint: "fal-ai/nano-banana-2",
|
|
244
269
|
falPricing: {
|
|
245
|
-
|
|
246
|
-
unitPrice: 0.08,
|
|
247
|
-
unit: "images",
|
|
270
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
248
271
|
currency: "USD",
|
|
272
|
+
endpointId: "fal-ai/nano-banana-2",
|
|
249
273
|
estimatedCostPerImageUsd: 0.08,
|
|
250
274
|
source: "fal-pricing-api",
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
benchmark: {
|
|
254
|
-
useCase: "Best balance of quality, edit support, web search, and cost",
|
|
255
|
-
tiers: { quality: "frontier", speed: "unknown", price: "premium" },
|
|
256
|
-
artificialAnalysis: {
|
|
257
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
258
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
259
|
-
textToImage: { rank: 3, elo: 1263, winRate: 0.71, pricePer1k: 67 },
|
|
260
|
-
editing: { rank: 5, elo: 1231, winRate: 0.63, pricePer1k: 67 }
|
|
261
|
-
}
|
|
275
|
+
unit: "images",
|
|
276
|
+
unitPrice: 0.08
|
|
262
277
|
},
|
|
278
|
+
maxReferenceImages: 4,
|
|
279
|
+
name: "Nano Banana 2",
|
|
280
|
+
pricePerImageUsd: 0.08,
|
|
281
|
+
pricing: "$0.08",
|
|
263
282
|
sizeMode: "aspect_ratio",
|
|
264
283
|
supportsAspect: true,
|
|
265
|
-
supportsResolution: true,
|
|
266
284
|
supportsEdit: true,
|
|
285
|
+
supportsGoogleSearch: true,
|
|
286
|
+
supportsLimitGenerations: true,
|
|
267
287
|
supportsNumImages: true,
|
|
268
288
|
supportsOutputFormat: true,
|
|
289
|
+
supportsResolution: true,
|
|
269
290
|
supportsSafetyTolerance: true,
|
|
270
291
|
supportsSeed: true,
|
|
271
|
-
supportsWebSearch: true,
|
|
272
|
-
supportsGoogleSearch: true,
|
|
273
|
-
supportsLimitGenerations: true,
|
|
274
292
|
supportsSyncMode: true,
|
|
275
293
|
supportsThinkingLevel: true,
|
|
276
|
-
|
|
294
|
+
supportsWebSearch: true,
|
|
295
|
+
type: "generation"
|
|
277
296
|
},
|
|
278
297
|
banana: {
|
|
279
|
-
name: "Nano Banana Pro",
|
|
280
|
-
endpoint: "fal-ai/nano-banana-pro",
|
|
281
|
-
editEndpoint: "fal-ai/nano-banana-pro/edit",
|
|
282
|
-
type: "generation",
|
|
283
|
-
pricing: "$0.15",
|
|
284
|
-
pricePerImageUsd: 0.15,
|
|
285
|
-
falPricing: {
|
|
286
|
-
endpointId: "fal-ai/nano-banana-pro",
|
|
287
|
-
unitPrice: 0.15,
|
|
288
|
-
unit: "images",
|
|
289
|
-
currency: "USD",
|
|
290
|
-
estimatedCostPerImageUsd: 0.15,
|
|
291
|
-
source: "fal-pricing-api",
|
|
292
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
293
|
-
},
|
|
294
298
|
benchmark: {
|
|
295
|
-
|
|
296
|
-
|
|
299
|
+
artificialAnalysis: {
|
|
300
|
+
editing: { elo: 1241, pricePer1k: 134, rank: 4, winRate: 0.65 },
|
|
301
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
302
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
303
|
+
textToImage: { elo: 1220, pricePer1k: 134, rank: 5, winRate: 0.66 }
|
|
304
|
+
},
|
|
297
305
|
speed: {
|
|
298
306
|
medianSeconds: 19.2,
|
|
299
307
|
p95Seconds: 30.3,
|
|
300
308
|
source: "artificial-analysis-models"
|
|
301
309
|
},
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
310
|
+
tiers: { price: "ultra", quality: "frontier", speed: "balanced" },
|
|
311
|
+
useCase: "Premium Gemini image generation and multi-reference edits"
|
|
312
|
+
},
|
|
313
|
+
editEndpoint: "fal-ai/nano-banana-pro/edit",
|
|
314
|
+
endpoint: "fal-ai/nano-banana-pro",
|
|
315
|
+
falPricing: {
|
|
316
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
317
|
+
currency: "USD",
|
|
318
|
+
endpointId: "fal-ai/nano-banana-pro",
|
|
319
|
+
estimatedCostPerImageUsd: 0.15,
|
|
320
|
+
source: "fal-pricing-api",
|
|
321
|
+
unit: "images",
|
|
322
|
+
unitPrice: 0.15
|
|
308
323
|
},
|
|
324
|
+
maxReferenceImages: 14,
|
|
325
|
+
name: "Nano Banana Pro",
|
|
326
|
+
pricePerImageUsd: 0.15,
|
|
327
|
+
pricing: "$0.15",
|
|
309
328
|
sizeMode: "aspect_ratio",
|
|
310
329
|
supportsAspect: true,
|
|
311
|
-
supportsResolution: true,
|
|
312
330
|
supportsEdit: true,
|
|
331
|
+
supportsGoogleSearch: true,
|
|
332
|
+
supportsLimitGenerations: true,
|
|
313
333
|
supportsNumImages: true,
|
|
314
334
|
supportsOutputFormat: true,
|
|
335
|
+
supportsResolution: true,
|
|
315
336
|
supportsSafetyTolerance: true,
|
|
316
337
|
supportsSeed: true,
|
|
317
|
-
supportsWebSearch: true,
|
|
318
|
-
supportsGoogleSearch: true,
|
|
319
|
-
supportsLimitGenerations: true,
|
|
320
338
|
supportsSyncMode: true,
|
|
321
|
-
|
|
339
|
+
supportsWebSearch: true,
|
|
340
|
+
type: "generation"
|
|
322
341
|
},
|
|
323
342
|
gemini: {
|
|
324
|
-
name: "Gemini 2.5 Flash",
|
|
325
|
-
endpoint: "fal-ai/gemini-25-flash-image",
|
|
326
343
|
editEndpoint: "fal-ai/gemini-25-flash-image/edit",
|
|
327
|
-
|
|
328
|
-
pricing: "$0.04",
|
|
329
|
-
pricePerImageUsd: 0.0398,
|
|
344
|
+
endpoint: "fal-ai/gemini-25-flash-image",
|
|
330
345
|
falPricing: {
|
|
331
|
-
|
|
332
|
-
unitPrice: 0.0398,
|
|
333
|
-
unit: "images",
|
|
346
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
334
347
|
currency: "USD",
|
|
348
|
+
endpointId: "fal-ai/gemini-25-flash-image",
|
|
335
349
|
estimatedCostPerImageUsd: 0.0398,
|
|
336
350
|
source: "fal-pricing-api",
|
|
337
|
-
|
|
351
|
+
unit: "images",
|
|
352
|
+
unitPrice: 0.0398
|
|
338
353
|
},
|
|
354
|
+
maxReferenceImages: 4,
|
|
355
|
+
name: "Gemini 2.5 Flash",
|
|
356
|
+
pricePerImageUsd: 0.0398,
|
|
357
|
+
pricing: "$0.04",
|
|
339
358
|
sizeMode: "aspect_ratio",
|
|
340
359
|
supportsAspect: true,
|
|
341
|
-
supportsResolution: false,
|
|
342
360
|
supportsEdit: true,
|
|
343
361
|
supportsNumImages: true,
|
|
344
362
|
supportsOutputFormat: true,
|
|
363
|
+
supportsResolution: false,
|
|
345
364
|
supportsSafetyTolerance: true,
|
|
346
365
|
supportsSeed: true,
|
|
347
366
|
supportsSyncMode: true,
|
|
348
|
-
|
|
367
|
+
type: "generation"
|
|
349
368
|
},
|
|
350
369
|
gemini3: {
|
|
351
|
-
name: "Gemini 3 Pro",
|
|
352
|
-
endpoint: "fal-ai/gemini-3-pro-image-preview",
|
|
353
370
|
editEndpoint: "fal-ai/gemini-3-pro-image-preview/edit",
|
|
354
|
-
|
|
355
|
-
pricing: "$0.15",
|
|
356
|
-
pricePerImageUsd: 0.15,
|
|
371
|
+
endpoint: "fal-ai/gemini-3-pro-image-preview",
|
|
357
372
|
falPricing: {
|
|
358
|
-
|
|
359
|
-
unitPrice: 0.15,
|
|
360
|
-
unit: "images",
|
|
373
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
361
374
|
currency: "USD",
|
|
375
|
+
endpointId: "fal-ai/gemini-3-pro-image-preview",
|
|
362
376
|
estimatedCostPerImageUsd: 0.15,
|
|
363
377
|
source: "fal-pricing-api",
|
|
364
|
-
|
|
378
|
+
unit: "images",
|
|
379
|
+
unitPrice: 0.15
|
|
365
380
|
},
|
|
381
|
+
maxReferenceImages: 4,
|
|
382
|
+
name: "Gemini 3 Pro",
|
|
383
|
+
pricePerImageUsd: 0.15,
|
|
384
|
+
pricing: "$0.15",
|
|
366
385
|
sizeMode: "aspect_ratio",
|
|
367
386
|
supportsAspect: true,
|
|
368
|
-
supportsResolution: true,
|
|
369
387
|
supportsEdit: true,
|
|
370
388
|
supportsNumImages: true,
|
|
371
389
|
supportsOutputFormat: true,
|
|
390
|
+
supportsResolution: true,
|
|
372
391
|
supportsSafetyTolerance: true,
|
|
373
392
|
supportsSeed: true,
|
|
374
|
-
supportsWebSearch: true,
|
|
375
393
|
supportsSyncMode: true,
|
|
376
|
-
|
|
394
|
+
supportsWebSearch: true,
|
|
395
|
+
type: "generation"
|
|
377
396
|
},
|
|
378
397
|
seedream4: {
|
|
379
|
-
name: "Seedream 4.0",
|
|
380
|
-
endpoint: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
381
|
-
editEndpoint: "fal-ai/bytedance/seedream/v4/edit",
|
|
382
|
-
type: "generation",
|
|
383
|
-
pricing: "$0.03",
|
|
384
|
-
pricePerImageUsd: 0.03,
|
|
385
|
-
falPricing: {
|
|
386
|
-
endpointId: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
387
|
-
unitPrice: 0.03,
|
|
388
|
-
unit: "images",
|
|
389
|
-
currency: "USD",
|
|
390
|
-
estimatedCostPerImageUsd: 0.03,
|
|
391
|
-
source: "fal-pricing-api",
|
|
392
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
393
|
-
},
|
|
394
398
|
benchmark: {
|
|
395
|
-
|
|
396
|
-
|
|
399
|
+
artificialAnalysis: {
|
|
400
|
+
editing: { elo: 1184, pricePer1k: 30, rank: 16, winRate: 0.61 },
|
|
401
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
402
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
403
|
+
textToImage: { elo: 1198, pricePer1k: 30, rank: 6, winRate: 0.59 }
|
|
404
|
+
},
|
|
397
405
|
speed: {
|
|
398
406
|
medianSeconds: 14.3,
|
|
399
407
|
p95Seconds: 21,
|
|
400
408
|
source: "artificial-analysis-models"
|
|
401
409
|
},
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
410
|
+
tiers: { price: "budget", quality: "best", speed: "balanced" },
|
|
411
|
+
useCase: "High-ranked budget generation and large multi-reference edits"
|
|
412
|
+
},
|
|
413
|
+
editEndpoint: "fal-ai/bytedance/seedream/v4/edit",
|
|
414
|
+
endpoint: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
415
|
+
falPricing: {
|
|
416
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
417
|
+
currency: "USD",
|
|
418
|
+
endpointId: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
419
|
+
estimatedCostPerImageUsd: 0.03,
|
|
420
|
+
source: "fal-pricing-api",
|
|
421
|
+
unit: "images",
|
|
422
|
+
unitPrice: 0.03
|
|
408
423
|
},
|
|
424
|
+
maxReferenceImages: 10,
|
|
425
|
+
name: "Seedream 4.0",
|
|
426
|
+
pricePerImageUsd: 0.03,
|
|
427
|
+
pricing: "$0.03",
|
|
409
428
|
sizeMode: "image_size_enum",
|
|
410
429
|
supportsAspect: true,
|
|
411
|
-
supportsResolution: false,
|
|
412
430
|
supportsEdit: true,
|
|
413
431
|
supportsNumImages: true,
|
|
432
|
+
supportsResolution: false,
|
|
414
433
|
supportsSeed: true,
|
|
415
434
|
supportsSyncMode: true,
|
|
416
|
-
|
|
435
|
+
type: "generation"
|
|
417
436
|
},
|
|
418
437
|
seedream45: {
|
|
419
|
-
name: "Seedream 4.5",
|
|
420
|
-
endpoint: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
421
|
-
editEndpoint: "fal-ai/bytedance/seedream/v4.5/edit",
|
|
422
|
-
type: "generation",
|
|
423
|
-
pricing: "$0.04",
|
|
424
|
-
pricePerImageUsd: 0.04,
|
|
425
|
-
falPricing: {
|
|
426
|
-
endpointId: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
427
|
-
unitPrice: 0.04,
|
|
428
|
-
unit: "images",
|
|
429
|
-
currency: "USD",
|
|
430
|
-
estimatedCostPerImageUsd: 0.04,
|
|
431
|
-
source: "fal-pricing-api",
|
|
432
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
433
|
-
},
|
|
434
438
|
benchmark: {
|
|
435
|
-
|
|
436
|
-
|
|
439
|
+
artificialAnalysis: {
|
|
440
|
+
editing: { elo: 1184, pricePer1k: 40, rank: 17, winRate: 0.58 },
|
|
441
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
442
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
443
|
+
textToImage: { elo: 1167, pricePer1k: 40, rank: 17, winRate: 0.63 }
|
|
444
|
+
},
|
|
437
445
|
speed: {
|
|
438
446
|
medianSeconds: 18.2,
|
|
439
447
|
p95Seconds: 43.3,
|
|
440
448
|
source: "artificial-analysis-models"
|
|
441
449
|
},
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
450
|
+
tiers: { price: "standard", quality: "better", speed: "balanced" },
|
|
451
|
+
useCase: "Cheap current Seedream model with good animation/art scores"
|
|
452
|
+
},
|
|
453
|
+
editEndpoint: "fal-ai/bytedance/seedream/v4.5/edit",
|
|
454
|
+
endpoint: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
455
|
+
falPricing: {
|
|
456
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
457
|
+
currency: "USD",
|
|
458
|
+
endpointId: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
459
|
+
estimatedCostPerImageUsd: 0.04,
|
|
460
|
+
source: "fal-pricing-api",
|
|
461
|
+
unit: "images",
|
|
462
|
+
unitPrice: 0.04
|
|
463
|
+
},
|
|
464
|
+
maxReferenceImages: 10,
|
|
465
|
+
name: "Seedream 4.5",
|
|
466
|
+
pricePerImageUsd: 0.04,
|
|
467
|
+
pricing: "$0.04",
|
|
468
|
+
sizeMode: "image_size_enum",
|
|
469
|
+
supportsAspect: true,
|
|
470
|
+
supportsEdit: true,
|
|
471
|
+
supportsNumImages: true,
|
|
472
|
+
supportsResolution: false,
|
|
473
|
+
supportsSeed: true,
|
|
474
|
+
supportsSyncMode: true,
|
|
475
|
+
type: "generation"
|
|
476
|
+
},
|
|
477
|
+
seedream5: {
|
|
478
|
+
name: "Seedream 5.0 Pro",
|
|
479
|
+
endpoint: "bytedance/seedream/v5/pro/text-to-image",
|
|
480
|
+
editEndpoint: "bytedance/seedream/v5/pro/edit",
|
|
481
|
+
type: "generation",
|
|
482
|
+
// fal tiers Seedream v5 Pro by output size: $0.0675 up to 1536², $0.135 up to 2048².
|
|
483
|
+
pricing: "$0.0675 (\u22641536\xB2) / $0.135 (\u22642048\xB2)",
|
|
484
|
+
pricePerImageUsd: 0.0675,
|
|
485
|
+
falPricing: {
|
|
486
|
+
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
487
|
+
currency: "USD",
|
|
488
|
+
endpointId: "bytedance/seedream/v5/pro/text-to-image",
|
|
489
|
+
estimatedCostPerImageUsd: 0.0675,
|
|
490
|
+
source: "fal-pricing-api",
|
|
491
|
+
unit: "images",
|
|
492
|
+
unitPrice: 0.0675
|
|
448
493
|
},
|
|
449
494
|
sizeMode: "image_size_enum",
|
|
450
495
|
supportsAspect: true,
|
|
@@ -455,417 +500,522 @@ var MODELS = {
|
|
|
455
500
|
supportsSyncMode: true,
|
|
456
501
|
maxReferenceImages: 10
|
|
457
502
|
},
|
|
458
|
-
"
|
|
459
|
-
name: "
|
|
460
|
-
endpoint: "fal-ai/
|
|
461
|
-
editEndpoint: "fal-ai/
|
|
503
|
+
"seedream5-lite": {
|
|
504
|
+
name: "Seedream 5.0 Lite",
|
|
505
|
+
endpoint: "fal-ai/bytedance/seedream/v5/lite/text-to-image",
|
|
506
|
+
editEndpoint: "fal-ai/bytedance/seedream/v5/lite/edit",
|
|
462
507
|
type: "generation",
|
|
463
|
-
|
|
464
|
-
|
|
508
|
+
// Flat price regardless of resolution; native up to Auto 3K (~9.4MP).
|
|
509
|
+
pricing: "$0.035",
|
|
510
|
+
pricePerImageUsd: 0.035,
|
|
465
511
|
falPricing: {
|
|
466
|
-
|
|
467
|
-
unitPrice: 0.07,
|
|
468
|
-
unit: "megapixels",
|
|
512
|
+
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
469
513
|
currency: "USD",
|
|
470
|
-
|
|
514
|
+
endpointId: "fal-ai/bytedance/seedream/v5/lite/text-to-image",
|
|
515
|
+
estimatedCostPerImageUsd: 0.035,
|
|
471
516
|
source: "fal-pricing-api",
|
|
472
|
-
|
|
517
|
+
unit: "images",
|
|
518
|
+
unitPrice: 0.035
|
|
473
519
|
},
|
|
520
|
+
sizeMode: "image_size_enum",
|
|
521
|
+
supportsAspect: true,
|
|
522
|
+
supportsResolution: false,
|
|
523
|
+
supportsEdit: true,
|
|
524
|
+
supportsNumImages: true,
|
|
525
|
+
supportsSeed: true,
|
|
526
|
+
supportsSyncMode: true,
|
|
527
|
+
maxReferenceImages: 10
|
|
528
|
+
},
|
|
529
|
+
"flux2-max": {
|
|
474
530
|
benchmark: {
|
|
475
|
-
|
|
476
|
-
|
|
531
|
+
artificialAnalysis: {
|
|
532
|
+
editing: { elo: 1206, pricePer1k: 140, rank: 10, winRate: 0.6 },
|
|
533
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
534
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
535
|
+
textToImage: { elo: 1197, pricePer1k: 70, rank: 8, winRate: 0.67 }
|
|
536
|
+
},
|
|
477
537
|
speed: {
|
|
478
538
|
medianSeconds: 31.6,
|
|
479
539
|
p95Seconds: 41,
|
|
480
540
|
source: "artificial-analysis-models"
|
|
481
541
|
},
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
485
|
-
textToImage: { rank: 8, elo: 1197, winRate: 0.67, pricePer1k: 70 },
|
|
486
|
-
editing: { rank: 10, elo: 1206, winRate: 0.6, pricePer1k: 140 }
|
|
487
|
-
}
|
|
542
|
+
tiers: { price: "premium", quality: "best", speed: "slow" },
|
|
543
|
+
useCase: "Best FLUX quality and high-end editing"
|
|
488
544
|
},
|
|
545
|
+
editEndpoint: "fal-ai/flux-2-max/edit",
|
|
546
|
+
endpoint: "fal-ai/flux-2-max",
|
|
547
|
+
falPricing: {
|
|
548
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
549
|
+
currency: "USD",
|
|
550
|
+
endpointId: "fal-ai/flux-2-max",
|
|
551
|
+
estimatedCostPerImageUsd: 0.07,
|
|
552
|
+
source: "fal-pricing-api",
|
|
553
|
+
unit: "megapixels",
|
|
554
|
+
unitPrice: 0.07
|
|
555
|
+
},
|
|
556
|
+
maxReferenceImages: 10,
|
|
557
|
+
name: "FLUX.2 Max",
|
|
558
|
+
pricePerImageUsd: 0.07,
|
|
559
|
+
pricing: "$0.07/MP",
|
|
489
560
|
sizeMode: "image_size_enum",
|
|
490
561
|
supportsAspect: true,
|
|
491
|
-
supportsResolution: false,
|
|
492
562
|
supportsEdit: true,
|
|
493
563
|
supportsNumImages: false,
|
|
494
564
|
supportsOutputFormat: true,
|
|
495
|
-
|
|
565
|
+
supportsResolution: false,
|
|
496
566
|
supportsSafetyChecker: true,
|
|
567
|
+
supportsSafetyTolerance: true,
|
|
497
568
|
supportsSeed: true,
|
|
498
569
|
supportsSyncMode: true,
|
|
499
|
-
|
|
570
|
+
type: "generation"
|
|
500
571
|
},
|
|
501
572
|
"flux2-pro": {
|
|
502
|
-
name: "FLUX.2 Pro",
|
|
503
|
-
endpoint: "fal-ai/flux-2-pro",
|
|
504
|
-
editEndpoint: "fal-ai/flux-2-pro/edit",
|
|
505
|
-
type: "generation",
|
|
506
|
-
pricing: "$0.03/MP",
|
|
507
|
-
pricePerImageUsd: 0.03,
|
|
508
|
-
falPricing: {
|
|
509
|
-
endpointId: "fal-ai/flux-2-pro",
|
|
510
|
-
unitPrice: 0.03,
|
|
511
|
-
unit: "processed megapixels",
|
|
512
|
-
currency: "USD",
|
|
513
|
-
estimatedCostPerImageUsd: 0.03,
|
|
514
|
-
source: "fal-pricing-api",
|
|
515
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
516
|
-
},
|
|
517
573
|
benchmark: {
|
|
518
|
-
|
|
519
|
-
|
|
574
|
+
artificialAnalysis: {
|
|
575
|
+
editing: { elo: 1170, pricePer1k: 30, rank: 21 },
|
|
576
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
577
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
578
|
+
textToImage: { elo: 1186, pricePer1k: 30, rank: 10, winRate: 0.62 }
|
|
579
|
+
},
|
|
520
580
|
speed: {
|
|
521
581
|
medianSeconds: 16.1,
|
|
522
582
|
p95Seconds: 23.9,
|
|
523
583
|
source: "artificial-analysis-models"
|
|
524
584
|
},
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
585
|
+
tiers: { price: "budget", quality: "best", speed: "balanced" },
|
|
586
|
+
useCase: "Production FLUX quality at a low per-megapixel price"
|
|
587
|
+
},
|
|
588
|
+
editEndpoint: "fal-ai/flux-2-pro/edit",
|
|
589
|
+
endpoint: "fal-ai/flux-2-pro",
|
|
590
|
+
falPricing: {
|
|
591
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
592
|
+
currency: "USD",
|
|
593
|
+
endpointId: "fal-ai/flux-2-pro",
|
|
594
|
+
estimatedCostPerImageUsd: 0.03,
|
|
595
|
+
source: "fal-pricing-api",
|
|
596
|
+
unit: "processed megapixels",
|
|
597
|
+
unitPrice: 0.03
|
|
531
598
|
},
|
|
599
|
+
maxReferenceImages: 10,
|
|
600
|
+
name: "FLUX.2 Pro",
|
|
601
|
+
pricePerImageUsd: 0.03,
|
|
602
|
+
pricing: "$0.03/MP",
|
|
532
603
|
sizeMode: "image_size_enum",
|
|
533
604
|
supportsAspect: true,
|
|
534
|
-
supportsResolution: false,
|
|
535
605
|
supportsEdit: true,
|
|
536
606
|
supportsNumImages: false,
|
|
537
607
|
supportsOutputFormat: true,
|
|
538
|
-
|
|
608
|
+
supportsResolution: false,
|
|
539
609
|
supportsSafetyChecker: true,
|
|
610
|
+
supportsSafetyTolerance: true,
|
|
540
611
|
supportsSeed: true,
|
|
541
612
|
supportsSyncMode: true,
|
|
542
|
-
|
|
613
|
+
type: "generation"
|
|
543
614
|
},
|
|
544
615
|
"flux2-flex": {
|
|
545
|
-
name: "FLUX.2 Flex",
|
|
546
|
-
endpoint: "fal-ai/flux-2-flex",
|
|
547
|
-
editEndpoint: "fal-ai/flux-2-flex/edit",
|
|
548
|
-
type: "generation",
|
|
549
|
-
pricing: "$0.05/MP",
|
|
550
|
-
pricePerImageUsd: 0.05,
|
|
551
|
-
falPricing: {
|
|
552
|
-
endpointId: "fal-ai/flux-2-flex",
|
|
553
|
-
unitPrice: 0.05,
|
|
554
|
-
unit: "processed megapixels",
|
|
555
|
-
currency: "USD",
|
|
556
|
-
estimatedCostPerImageUsd: 0.05,
|
|
557
|
-
source: "fal-pricing-api",
|
|
558
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
559
|
-
},
|
|
560
616
|
benchmark: {
|
|
561
|
-
|
|
562
|
-
|
|
617
|
+
artificialAnalysis: {
|
|
618
|
+
editing: { elo: 1161, pricePer1k: 60, rank: 22 },
|
|
619
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
620
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
621
|
+
textToImage: { elo: 1182, pricePer1k: 60, rank: 13, winRate: 0.61 }
|
|
622
|
+
},
|
|
563
623
|
speed: {
|
|
564
624
|
medianSeconds: 15.3,
|
|
565
625
|
p95Seconds: 22.2,
|
|
566
626
|
source: "artificial-analysis-models"
|
|
567
627
|
},
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
628
|
+
tiers: { price: "standard", quality: "best", speed: "balanced" },
|
|
629
|
+
useCase: "FLUX quality with guidance and step controls"
|
|
630
|
+
},
|
|
631
|
+
editEndpoint: "fal-ai/flux-2-flex/edit",
|
|
632
|
+
endpoint: "fal-ai/flux-2-flex",
|
|
633
|
+
falPricing: {
|
|
634
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
635
|
+
currency: "USD",
|
|
636
|
+
endpointId: "fal-ai/flux-2-flex",
|
|
637
|
+
estimatedCostPerImageUsd: 0.05,
|
|
638
|
+
source: "fal-pricing-api",
|
|
639
|
+
unit: "processed megapixels",
|
|
640
|
+
unitPrice: 0.05
|
|
574
641
|
},
|
|
642
|
+
maxReferenceImages: 10,
|
|
643
|
+
name: "FLUX.2 Flex",
|
|
644
|
+
pricePerImageUsd: 0.05,
|
|
645
|
+
pricing: "$0.05/MP",
|
|
575
646
|
sizeMode: "image_size_enum",
|
|
647
|
+
supportedOutputFormats: ["jpeg", "png"],
|
|
576
648
|
supportsAspect: true,
|
|
577
|
-
supportsResolution: false,
|
|
578
649
|
supportsEdit: true,
|
|
650
|
+
supportsGuidanceScale: true,
|
|
651
|
+
supportsInferenceSteps: true,
|
|
579
652
|
supportsNumImages: false,
|
|
580
653
|
supportsOutputFormat: true,
|
|
581
|
-
|
|
582
|
-
supportsSafetyTolerance: true,
|
|
654
|
+
supportsResolution: false,
|
|
583
655
|
supportsSafetyChecker: true,
|
|
656
|
+
supportsSafetyTolerance: true,
|
|
584
657
|
supportsSeed: true,
|
|
585
|
-
supportsGuidanceScale: true,
|
|
586
|
-
supportsInferenceSteps: true,
|
|
587
658
|
supportsSyncMode: true,
|
|
588
|
-
|
|
659
|
+
type: "generation"
|
|
589
660
|
},
|
|
590
661
|
"flux2-dev": {
|
|
591
|
-
name: "FLUX.2 Dev",
|
|
592
|
-
endpoint: "fal-ai/flux-2",
|
|
593
|
-
editEndpoint: "fal-ai/flux-2/edit",
|
|
594
|
-
type: "generation",
|
|
595
|
-
pricing: "$0.00167/sec",
|
|
596
|
-
pricePerImageUsd: 0.012,
|
|
597
|
-
falPricing: {
|
|
598
|
-
endpointId: "fal-ai/flux-2",
|
|
599
|
-
unitPrice: 167e-5,
|
|
600
|
-
unit: "compute seconds",
|
|
601
|
-
currency: "USD",
|
|
602
|
-
estimatedCostPerImageUsd: 0.012,
|
|
603
|
-
source: "fal-pricing-api",
|
|
604
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
605
|
-
},
|
|
606
662
|
benchmark: {
|
|
607
|
-
|
|
608
|
-
|
|
663
|
+
artificialAnalysis: {
|
|
664
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
665
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
666
|
+
textToImage: { elo: 1160, pricePer1k: 12, rank: 19, winRate: 0.57 }
|
|
667
|
+
},
|
|
609
668
|
speed: {
|
|
610
669
|
medianSeconds: 4.6,
|
|
611
670
|
p95Seconds: 69.6,
|
|
612
671
|
source: "artificial-analysis-models"
|
|
613
672
|
},
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
673
|
+
tiers: { price: "variable", quality: "better", speed: "fast" },
|
|
674
|
+
useCase: "Open FLUX.2 quality with low average cost"
|
|
675
|
+
},
|
|
676
|
+
editEndpoint: "fal-ai/flux-2/edit",
|
|
677
|
+
endpoint: "fal-ai/flux-2",
|
|
678
|
+
falPricing: {
|
|
679
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
680
|
+
currency: "USD",
|
|
681
|
+
endpointId: "fal-ai/flux-2",
|
|
682
|
+
estimatedCostPerImageUsd: 0.012,
|
|
683
|
+
source: "fal-pricing-api",
|
|
684
|
+
unit: "compute seconds",
|
|
685
|
+
unitPrice: 167e-5
|
|
619
686
|
},
|
|
687
|
+
maxReferenceImages: 10,
|
|
688
|
+
name: "FLUX.2 [dev]",
|
|
689
|
+
pricePerImageUsd: 0.012,
|
|
690
|
+
pricing: "$0.00167/sec",
|
|
620
691
|
sizeMode: "image_size_enum",
|
|
621
692
|
supportsAspect: true,
|
|
622
|
-
supportsResolution: false,
|
|
623
693
|
supportsEdit: true,
|
|
694
|
+
supportsGuidanceScale: true,
|
|
695
|
+
supportsInferenceSteps: true,
|
|
624
696
|
supportsNumImages: true,
|
|
625
697
|
supportsOutputFormat: true,
|
|
626
|
-
|
|
698
|
+
supportsResolution: false,
|
|
627
699
|
supportsSafetyChecker: true,
|
|
700
|
+
supportsSafetyTolerance: true,
|
|
628
701
|
supportsSeed: true,
|
|
702
|
+
supportsSyncMode: true,
|
|
703
|
+
type: "generation"
|
|
704
|
+
},
|
|
705
|
+
"flux2-turbo": {
|
|
706
|
+
endpoint: "fal-ai/flux-2/turbo",
|
|
707
|
+
falPricing: {
|
|
708
|
+
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
709
|
+
currency: "USD",
|
|
710
|
+
endpointId: "fal-ai/flux-2/turbo",
|
|
711
|
+
estimatedCostPerImageUsd: 8e-3,
|
|
712
|
+
source: "fal-pricing-api",
|
|
713
|
+
unit: "megapixels",
|
|
714
|
+
unitPrice: 8e-3
|
|
715
|
+
},
|
|
716
|
+
name: "FLUX.2 Turbo",
|
|
717
|
+
pricePerImageUsd: 8e-3,
|
|
718
|
+
pricing: "$0.008/MP",
|
|
719
|
+
sizeMode: "image_size_enum",
|
|
720
|
+
supportsAspect: true,
|
|
721
|
+
supportsEdit: false,
|
|
629
722
|
supportsGuidanceScale: true,
|
|
630
|
-
|
|
723
|
+
supportsNumImages: true,
|
|
724
|
+
supportsOutputFormat: true,
|
|
725
|
+
supportsResolution: false,
|
|
726
|
+
supportsSafetyChecker: true,
|
|
727
|
+
supportsSeed: true,
|
|
631
728
|
supportsSyncMode: true,
|
|
632
|
-
|
|
729
|
+
type: "generation"
|
|
633
730
|
},
|
|
634
731
|
flux: {
|
|
635
|
-
name: "FLUX Pro Ultra",
|
|
636
732
|
endpoint: "fal-ai/flux-pro/v1.1-ultra",
|
|
637
|
-
type: "generation",
|
|
638
|
-
pricing: "$0.06",
|
|
639
|
-
pricePerImageUsd: 0.06,
|
|
640
733
|
falPricing: {
|
|
641
|
-
|
|
642
|
-
unitPrice: 0.06,
|
|
643
|
-
unit: "images",
|
|
734
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
644
735
|
currency: "USD",
|
|
736
|
+
endpointId: "fal-ai/flux-pro/v1.1-ultra",
|
|
645
737
|
estimatedCostPerImageUsd: 0.06,
|
|
646
738
|
source: "fal-pricing-api",
|
|
647
|
-
|
|
739
|
+
unit: "images",
|
|
740
|
+
unitPrice: 0.06
|
|
648
741
|
},
|
|
742
|
+
maxReferenceImages: 1,
|
|
743
|
+
name: "FLUX Pro Ultra",
|
|
744
|
+
pricePerImageUsd: 0.06,
|
|
745
|
+
pricing: "$0.06",
|
|
649
746
|
sizeMode: "aspect_ratio",
|
|
650
747
|
supportsAspect: true,
|
|
651
|
-
supportsResolution: false,
|
|
652
748
|
supportsEdit: true,
|
|
749
|
+
supportsEnhancePrompt: true,
|
|
750
|
+
supportsImagePromptStrength: true,
|
|
653
751
|
supportsNumImages: true,
|
|
654
752
|
supportsOutputFormat: true,
|
|
655
753
|
supportsRaw: true,
|
|
656
|
-
|
|
754
|
+
supportsResolution: false,
|
|
657
755
|
supportsSafetyTolerance: true,
|
|
658
756
|
supportsSeed: true,
|
|
659
|
-
supportsImagePromptStrength: true,
|
|
660
757
|
supportsSyncMode: true,
|
|
661
|
-
|
|
758
|
+
type: "generation"
|
|
662
759
|
},
|
|
663
760
|
"flux-fast": {
|
|
664
|
-
name: "FLUX Schnell",
|
|
665
761
|
endpoint: "fal-ai/flux/schnell",
|
|
666
|
-
type: "generation",
|
|
667
|
-
pricing: "$0.003",
|
|
668
|
-
pricePerImageUsd: 3e-3,
|
|
669
762
|
falPricing: {
|
|
670
|
-
|
|
671
|
-
unitPrice: 3e-3,
|
|
672
|
-
unit: "megapixels",
|
|
763
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
673
764
|
currency: "USD",
|
|
765
|
+
endpointId: "fal-ai/flux/schnell",
|
|
674
766
|
estimatedCostPerImageUsd: 3e-3,
|
|
675
767
|
source: "fal-pricing-api",
|
|
676
|
-
|
|
768
|
+
unit: "megapixels",
|
|
769
|
+
unitPrice: 3e-3
|
|
677
770
|
},
|
|
771
|
+
name: "FLUX Schnell",
|
|
772
|
+
pricePerImageUsd: 3e-3,
|
|
773
|
+
pricing: "$0.003",
|
|
678
774
|
sizeMode: "image_size_enum",
|
|
679
775
|
supportsAspect: true,
|
|
680
|
-
supportsResolution: false,
|
|
681
776
|
supportsEdit: false,
|
|
682
|
-
supportsNumImages: true,
|
|
683
|
-
supportsOutputFormat: true,
|
|
684
777
|
supportsGuidanceScale: true,
|
|
685
778
|
supportsInferenceSteps: true,
|
|
779
|
+
supportsNumImages: true,
|
|
780
|
+
supportsOutputFormat: true,
|
|
781
|
+
supportsResolution: false,
|
|
686
782
|
supportsSeed: true,
|
|
687
|
-
supportsSyncMode: true
|
|
783
|
+
supportsSyncMode: true,
|
|
784
|
+
type: "generation"
|
|
688
785
|
},
|
|
689
786
|
recraft: {
|
|
690
|
-
name: "Recraft V3",
|
|
691
787
|
endpoint: "fal-ai/recraft-v3",
|
|
692
|
-
type: "generation",
|
|
693
|
-
pricing: "$0.04",
|
|
694
|
-
pricePerImageUsd: 0.04,
|
|
695
788
|
falPricing: {
|
|
789
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
790
|
+
currency: "USD",
|
|
696
791
|
endpointId: "fal-ai/recraft-v3",
|
|
697
|
-
|
|
792
|
+
estimatedCostPerImageUsd: 0.04,
|
|
793
|
+
source: "fal-pricing-api",
|
|
698
794
|
unit: "images",
|
|
795
|
+
unitPrice: 0.04
|
|
796
|
+
},
|
|
797
|
+
name: "Recraft V3",
|
|
798
|
+
pricePerImageUsd: 0.04,
|
|
799
|
+
pricing: "$0.04",
|
|
800
|
+
sizeMode: "image_size_enum",
|
|
801
|
+
supportsAspect: true,
|
|
802
|
+
supportsEdit: false,
|
|
803
|
+
supportsNumImages: false,
|
|
804
|
+
supportsResolution: false,
|
|
805
|
+
supportsStyle: true,
|
|
806
|
+
supportsSyncMode: true,
|
|
807
|
+
type: "generation"
|
|
808
|
+
},
|
|
809
|
+
recraft4: {
|
|
810
|
+
endpoint: "fal-ai/recraft/v4/text-to-image",
|
|
811
|
+
falPricing: {
|
|
812
|
+
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
699
813
|
currency: "USD",
|
|
814
|
+
endpointId: "fal-ai/recraft/v4/text-to-image",
|
|
700
815
|
estimatedCostPerImageUsd: 0.04,
|
|
701
816
|
source: "fal-pricing-api",
|
|
702
|
-
|
|
817
|
+
unit: "images",
|
|
818
|
+
unitPrice: 0.04
|
|
703
819
|
},
|
|
820
|
+
name: "Recraft V4",
|
|
821
|
+
pricePerImageUsd: 0.04,
|
|
822
|
+
pricing: "$0.04",
|
|
704
823
|
sizeMode: "image_size_enum",
|
|
705
824
|
supportsAspect: true,
|
|
706
|
-
supportsResolution: false,
|
|
707
825
|
supportsEdit: false,
|
|
708
826
|
supportsNumImages: false,
|
|
827
|
+
supportsResolution: false,
|
|
709
828
|
supportsStyle: true,
|
|
710
|
-
supportsSyncMode: true
|
|
829
|
+
supportsSyncMode: true,
|
|
830
|
+
type: "generation"
|
|
711
831
|
},
|
|
712
832
|
ideogram: {
|
|
713
|
-
name: "Ideogram V3",
|
|
714
833
|
endpoint: "fal-ai/ideogram/v3",
|
|
715
|
-
type: "generation",
|
|
716
|
-
pricing: "$0.03",
|
|
717
|
-
pricePerImageUsd: 0.03,
|
|
718
834
|
falPricing: {
|
|
719
|
-
|
|
720
|
-
unitPrice: 0.03,
|
|
721
|
-
unit: "images",
|
|
835
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
722
836
|
currency: "USD",
|
|
837
|
+
endpointId: "fal-ai/ideogram/v3",
|
|
723
838
|
estimatedCostPerImageUsd: 0.03,
|
|
724
839
|
source: "fal-pricing-api",
|
|
725
|
-
|
|
840
|
+
unit: "images",
|
|
841
|
+
unitPrice: 0.03
|
|
726
842
|
},
|
|
843
|
+
name: "Ideogram V3",
|
|
844
|
+
pricePerImageUsd: 0.03,
|
|
845
|
+
pricing: "$0.03",
|
|
727
846
|
sizeMode: "image_size_enum",
|
|
728
847
|
supportsAspect: true,
|
|
729
|
-
supportsResolution: false,
|
|
730
848
|
supportsEdit: false,
|
|
731
|
-
supportsNumImages: true,
|
|
732
849
|
supportsExpandPrompt: true,
|
|
733
850
|
supportsNegativePrompt: true,
|
|
851
|
+
supportsNumImages: true,
|
|
734
852
|
supportsRenderingSpeed: true,
|
|
853
|
+
supportsResolution: false,
|
|
735
854
|
supportsSeed: true,
|
|
736
855
|
supportsStyle: true,
|
|
737
|
-
supportsSyncMode: true
|
|
856
|
+
supportsSyncMode: true,
|
|
857
|
+
type: "generation"
|
|
738
858
|
},
|
|
739
|
-
|
|
740
|
-
name: "
|
|
741
|
-
endpoint: "
|
|
742
|
-
editEndpoint: "xai/grok-imagine-image/edit",
|
|
859
|
+
ideogram4: {
|
|
860
|
+
name: "Ideogram V4",
|
|
861
|
+
endpoint: "ideogram/v4",
|
|
743
862
|
type: "generation",
|
|
744
|
-
|
|
745
|
-
|
|
863
|
+
// fal bills v4 per output megapixel by rendering speed: TURBO $0.03, BALANCED
|
|
864
|
+
// $0.06, QUALITY $0.10 (plus a flat $0.03 when prompt expansion is used).
|
|
865
|
+
// Headline uses the TURBO 1MP rate, matching how ideogram v3 is modeled.
|
|
866
|
+
pricing: "$0.03",
|
|
867
|
+
pricePerImageUsd: 0.03,
|
|
746
868
|
falPricing: {
|
|
747
|
-
|
|
748
|
-
unitPrice: 0.02,
|
|
749
|
-
unit: "images",
|
|
869
|
+
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
750
870
|
currency: "USD",
|
|
751
|
-
|
|
871
|
+
endpointId: "ideogram/v4",
|
|
872
|
+
estimatedCostPerImageUsd: 0.03,
|
|
752
873
|
source: "fal-pricing-api",
|
|
753
|
-
|
|
874
|
+
unit: "megapixels",
|
|
875
|
+
unitPrice: 0.03
|
|
754
876
|
},
|
|
877
|
+
sizeMode: "image_size_enum",
|
|
878
|
+
supportsAspect: true,
|
|
879
|
+
supportsResolution: false,
|
|
880
|
+
supportsEdit: false,
|
|
881
|
+
supportsNumImages: true,
|
|
882
|
+
supportsRenderingSpeed: true,
|
|
883
|
+
supportsSeed: true,
|
|
884
|
+
supportsOutputFormat: true,
|
|
885
|
+
supportedOutputFormats: ["jpeg", "png"],
|
|
886
|
+
supportsSafetyChecker: true,
|
|
887
|
+
supportsSyncMode: true
|
|
888
|
+
},
|
|
889
|
+
"grok-image": {
|
|
755
890
|
benchmark: {
|
|
756
|
-
|
|
757
|
-
|
|
891
|
+
artificialAnalysis: {
|
|
892
|
+
editing: { elo: 1213, pricePer1k: 20, rank: 7, winRate: 0.6 },
|
|
893
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
894
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
895
|
+
textToImage: { elo: 1182, pricePer1k: 20, rank: 12, winRate: 0.6 }
|
|
896
|
+
},
|
|
758
897
|
speed: {
|
|
759
898
|
medianSeconds: 5.1,
|
|
760
899
|
p95Seconds: 6.5,
|
|
761
900
|
source: "artificial-analysis-models"
|
|
762
901
|
},
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
902
|
+
tiers: { price: "budget", quality: "best", speed: "fast" },
|
|
903
|
+
useCase: "Very fast, cheap generation and edits"
|
|
904
|
+
},
|
|
905
|
+
editEndpoint: "xai/grok-imagine-image/edit",
|
|
906
|
+
endpoint: "xai/grok-imagine-image",
|
|
907
|
+
falPricing: {
|
|
908
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
909
|
+
currency: "USD",
|
|
910
|
+
endpointId: "xai/grok-imagine-image",
|
|
911
|
+
estimatedCostPerImageUsd: 0.02,
|
|
912
|
+
source: "fal-pricing-api",
|
|
913
|
+
unit: "images",
|
|
914
|
+
unitPrice: 0.02
|
|
769
915
|
},
|
|
916
|
+
maxReferenceImages: 4,
|
|
917
|
+
name: "Grok Imagine Image",
|
|
918
|
+
pricePerImageUsd: 0.02,
|
|
919
|
+
pricing: "$0.02",
|
|
770
920
|
sizeMode: "aspect_ratio",
|
|
771
921
|
supportsAspect: true,
|
|
772
|
-
supportsResolution: true,
|
|
773
922
|
supportsEdit: true,
|
|
774
923
|
supportsNumImages: true,
|
|
775
924
|
supportsOutputFormat: true,
|
|
925
|
+
supportsResolution: true,
|
|
776
926
|
supportsSyncMode: true,
|
|
777
|
-
|
|
927
|
+
type: "generation"
|
|
778
928
|
},
|
|
779
929
|
qwen: {
|
|
780
|
-
name: "Qwen Image",
|
|
781
|
-
endpoint: "fal-ai/qwen-image",
|
|
782
|
-
type: "generation",
|
|
783
|
-
pricing: "$0.02/MP",
|
|
784
|
-
pricePerImageUsd: 0.02,
|
|
785
|
-
falPricing: {
|
|
786
|
-
endpointId: "fal-ai/qwen-image",
|
|
787
|
-
unitPrice: 0.02,
|
|
788
|
-
unit: "megapixels",
|
|
789
|
-
currency: "USD",
|
|
790
|
-
estimatedCostPerImageUsd: 0.02,
|
|
791
|
-
source: "fal-pricing-api",
|
|
792
|
-
checkedAt: FAL_PRICING_CHECKED_AT
|
|
793
|
-
},
|
|
794
930
|
benchmark: {
|
|
795
|
-
|
|
796
|
-
|
|
931
|
+
artificialAnalysis: {
|
|
932
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
933
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
934
|
+
textToImage: { elo: 1158, pricePer1k: 20, rank: 20, winRate: 0.6 }
|
|
935
|
+
},
|
|
797
936
|
speed: {
|
|
798
937
|
medianSeconds: 23.3,
|
|
799
938
|
p95Seconds: 491,
|
|
800
939
|
source: "artificial-analysis-models"
|
|
801
940
|
},
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
941
|
+
tiers: { price: "budget", quality: "better", speed: "slow" },
|
|
942
|
+
useCase: "Low-cost open-weight text and design generation"
|
|
943
|
+
},
|
|
944
|
+
endpoint: "fal-ai/qwen-image",
|
|
945
|
+
falPricing: {
|
|
946
|
+
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
947
|
+
currency: "USD",
|
|
948
|
+
endpointId: "fal-ai/qwen-image",
|
|
949
|
+
estimatedCostPerImageUsd: 0.02,
|
|
950
|
+
source: "fal-pricing-api",
|
|
951
|
+
unit: "megapixels",
|
|
952
|
+
unitPrice: 0.02
|
|
807
953
|
},
|
|
954
|
+
name: "Qwen Image",
|
|
955
|
+
pricePerImageUsd: 0.02,
|
|
956
|
+
pricing: "$0.02/MP",
|
|
808
957
|
sizeMode: "image_size_enum",
|
|
809
958
|
supportsAspect: true,
|
|
810
|
-
supportsResolution: false,
|
|
811
959
|
supportsEdit: false,
|
|
812
960
|
supportsNumImages: true,
|
|
813
961
|
supportsOutputFormat: true,
|
|
962
|
+
supportsResolution: false,
|
|
814
963
|
supportsSeed: true,
|
|
815
|
-
supportsSyncMode: true
|
|
964
|
+
supportsSyncMode: true,
|
|
965
|
+
type: "generation"
|
|
816
966
|
},
|
|
817
967
|
// ─── Video Models ─────────────────────────────────────────────
|
|
818
968
|
kling: {
|
|
819
|
-
name: "Kling v3 Pro",
|
|
820
969
|
endpoint: "fal-ai/kling-video/v3/pro/image-to-video",
|
|
821
|
-
|
|
970
|
+
name: "Kling v3 Pro",
|
|
822
971
|
pricing: "$0.11/sec",
|
|
823
972
|
sizeMode: "none",
|
|
824
973
|
supportsAspect: false,
|
|
825
|
-
supportsResolution: false,
|
|
826
974
|
supportsEdit: false,
|
|
827
|
-
supportsNumImages: false
|
|
975
|
+
supportsNumImages: false,
|
|
976
|
+
supportsResolution: false,
|
|
977
|
+
type: "video"
|
|
828
978
|
},
|
|
829
979
|
// ─── Utility Models ───────────────────────────────────────────
|
|
830
980
|
clarity: {
|
|
831
|
-
name: "Clarity Upscaler",
|
|
832
981
|
endpoint: "fal-ai/clarity-upscaler",
|
|
833
|
-
|
|
834
|
-
pricing: "$0.
|
|
982
|
+
name: "Clarity Upscaler",
|
|
983
|
+
pricing: "$0.03/MP",
|
|
835
984
|
supportsAspect: false,
|
|
836
|
-
supportsResolution: false,
|
|
837
985
|
supportsEdit: false,
|
|
838
|
-
supportsNumImages: false
|
|
986
|
+
supportsNumImages: false,
|
|
987
|
+
supportsResolution: false,
|
|
988
|
+
type: "utility"
|
|
839
989
|
},
|
|
840
990
|
crystal: {
|
|
841
|
-
name: "Crystal Upscaler",
|
|
842
991
|
endpoint: "clarityai/crystal-upscaler",
|
|
843
|
-
|
|
992
|
+
name: "Crystal Upscaler",
|
|
844
993
|
pricing: "$0.02",
|
|
845
994
|
supportsAspect: false,
|
|
846
|
-
supportsResolution: false,
|
|
847
995
|
supportsEdit: false,
|
|
848
|
-
supportsNumImages: false
|
|
996
|
+
supportsNumImages: false,
|
|
997
|
+
supportsResolution: false,
|
|
998
|
+
type: "utility"
|
|
849
999
|
},
|
|
850
1000
|
rmbg: {
|
|
851
|
-
name: "BiRefNet (Background Removal)",
|
|
852
1001
|
endpoint: "fal-ai/birefnet",
|
|
853
|
-
|
|
1002
|
+
name: "BiRefNet (Background Removal)",
|
|
854
1003
|
pricing: "$0.02",
|
|
855
1004
|
supportsAspect: false,
|
|
856
|
-
supportsResolution: false,
|
|
857
1005
|
supportsEdit: false,
|
|
858
|
-
supportsNumImages: false
|
|
1006
|
+
supportsNumImages: false,
|
|
1007
|
+
supportsResolution: false,
|
|
1008
|
+
type: "utility"
|
|
859
1009
|
},
|
|
860
1010
|
bria: {
|
|
861
|
-
name: "Bria RMBG 2.0",
|
|
862
1011
|
endpoint: "fal-ai/bria/background/remove",
|
|
863
|
-
|
|
1012
|
+
name: "Bria RMBG 2.0",
|
|
864
1013
|
pricing: "$0.02",
|
|
865
1014
|
supportsAspect: false,
|
|
866
|
-
supportsResolution: false,
|
|
867
1015
|
supportsEdit: false,
|
|
868
|
-
supportsNumImages: false
|
|
1016
|
+
supportsNumImages: false,
|
|
1017
|
+
supportsResolution: false,
|
|
1018
|
+
type: "utility"
|
|
869
1019
|
}
|
|
870
1020
|
};
|
|
871
1021
|
var GENERATION_MODELS = [
|
|
@@ -877,19 +1027,24 @@ var GENERATION_MODELS = [
|
|
|
877
1027
|
"gemini3",
|
|
878
1028
|
"seedream4",
|
|
879
1029
|
"seedream45",
|
|
1030
|
+
"seedream5",
|
|
1031
|
+
"seedream5-lite",
|
|
880
1032
|
"flux2-max",
|
|
881
1033
|
"flux2-pro",
|
|
882
1034
|
"flux2-flex",
|
|
883
1035
|
"flux2-dev",
|
|
1036
|
+
"flux2-turbo",
|
|
884
1037
|
"flux",
|
|
885
1038
|
"flux-fast",
|
|
886
1039
|
"recraft",
|
|
1040
|
+
"recraft4",
|
|
887
1041
|
"ideogram",
|
|
1042
|
+
"ideogram4",
|
|
888
1043
|
"grok-image",
|
|
889
1044
|
"qwen"
|
|
890
1045
|
];
|
|
891
1046
|
var EDIT_CAPABLE_MODELS = GENERATION_MODELS.filter(
|
|
892
|
-
(id) => MODELS[id]?.supportsEdit
|
|
1047
|
+
(id) => MODELS[id]?.supportsEdit === true
|
|
893
1048
|
);
|
|
894
1049
|
var UTILITY_MODELS = ["clarity", "crystal", "rmbg", "bria"];
|
|
895
1050
|
var VIDEO_MODELS = ["kling"];
|
|
@@ -945,6 +1100,9 @@ function estimateCost(model, resolution, numImages = 1) {
|
|
|
945
1100
|
if ((model === "banana" || model === "gemini3") && resolution === "4K") {
|
|
946
1101
|
return configuredPrice * 2 * numImages;
|
|
947
1102
|
}
|
|
1103
|
+
if (model === "seedream5" && (resolution === "2K" || resolution === "4K")) {
|
|
1104
|
+
return configuredPrice * 2 * numImages;
|
|
1105
|
+
}
|
|
948
1106
|
if (model === "banana2") {
|
|
949
1107
|
const multiplier = resolution === "4K" ? 2 : resolution === "2K" ? 1.5 : resolution === "0.5K" ? 0.75 : 1;
|
|
950
1108
|
return configuredPrice * multiplier * numImages;
|
|
@@ -952,29 +1110,40 @@ function estimateCost(model, resolution, numImages = 1) {
|
|
|
952
1110
|
return configuredPrice * numImages;
|
|
953
1111
|
}
|
|
954
1112
|
switch (model) {
|
|
955
|
-
case "gpt2":
|
|
1113
|
+
case "gpt2": {
|
|
956
1114
|
return 0.211 * numImages;
|
|
957
|
-
|
|
1115
|
+
}
|
|
1116
|
+
case "gpt": {
|
|
958
1117
|
return 0.133 * numImages;
|
|
1118
|
+
}
|
|
959
1119
|
case "banana":
|
|
960
|
-
case "gemini3":
|
|
1120
|
+
case "gemini3": {
|
|
961
1121
|
return (resolution === "4K" ? 0.3 : 0.15) * numImages;
|
|
962
|
-
|
|
1122
|
+
}
|
|
1123
|
+
case "gemini": {
|
|
963
1124
|
return 0.039 * numImages;
|
|
1125
|
+
}
|
|
964
1126
|
case "flux":
|
|
965
|
-
case "ideogram":
|
|
1127
|
+
case "ideogram": {
|
|
966
1128
|
return 0.06 * numImages;
|
|
967
|
-
|
|
1129
|
+
}
|
|
1130
|
+
case "recraft": {
|
|
968
1131
|
return 0.04 * numImages;
|
|
969
|
-
|
|
1132
|
+
}
|
|
1133
|
+
case "flux-fast": {
|
|
970
1134
|
return 3e-3 * numImages;
|
|
971
|
-
|
|
1135
|
+
}
|
|
1136
|
+
case "clarity": {
|
|
1137
|
+
return 0.03 * numImages;
|
|
1138
|
+
}
|
|
972
1139
|
case "crystal":
|
|
973
1140
|
case "rmbg":
|
|
974
|
-
case "bria":
|
|
1141
|
+
case "bria": {
|
|
975
1142
|
return 0.02 * numImages;
|
|
976
|
-
|
|
1143
|
+
}
|
|
1144
|
+
default: {
|
|
977
1145
|
return 0.1 * numImages;
|
|
1146
|
+
}
|
|
978
1147
|
}
|
|
979
1148
|
}
|
|
980
1149
|
function estimateVideoCost(durationSeconds = 5, generateAudio = true) {
|
|
@@ -983,7 +1152,7 @@ function estimateVideoCost(durationSeconds = 5, generateAudio = true) {
|
|
|
983
1152
|
}
|
|
984
1153
|
|
|
985
1154
|
// src/creative.ts
|
|
986
|
-
var CONTROL_CHAR_REGEX = /[\
|
|
1155
|
+
var CONTROL_CHAR_REGEX = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
|
|
987
1156
|
var CreativeOptionError = class extends Error {
|
|
988
1157
|
availableIds;
|
|
989
1158
|
code = "INVALID_OPTION";
|
|
@@ -1010,28 +1179,20 @@ var CREATIVE_FIELDS = [
|
|
|
1010
1179
|
"motion"
|
|
1011
1180
|
];
|
|
1012
1181
|
var CREATIVE_TAXONOMY = {
|
|
1013
|
-
|
|
1014
|
-
{
|
|
1015
|
-
clause: "cinematic scene",
|
|
1016
|
-
description: "Frames the prompt as a cinematic still or scene.",
|
|
1017
|
-
id: "cinematic",
|
|
1018
|
-
label: "Cinematic"
|
|
1019
|
-
}
|
|
1020
|
-
],
|
|
1021
|
-
shot: [
|
|
1182
|
+
camera: [
|
|
1022
1183
|
{
|
|
1023
|
-
clause: "
|
|
1024
|
-
description: "
|
|
1025
|
-
id: "
|
|
1026
|
-
label: "
|
|
1184
|
+
clause: "macro product photography with crisp surface detail",
|
|
1185
|
+
description: "Product-oriented macro camera language for close detail.",
|
|
1186
|
+
id: "macro-product",
|
|
1187
|
+
label: "Macro product"
|
|
1027
1188
|
}
|
|
1028
1189
|
],
|
|
1029
|
-
|
|
1190
|
+
color: [
|
|
1030
1191
|
{
|
|
1031
|
-
clause: "
|
|
1032
|
-
description: "
|
|
1033
|
-
id: "
|
|
1034
|
-
label: "
|
|
1192
|
+
clause: "monochrome palette with tonal contrast",
|
|
1193
|
+
description: "Black-and-white or single-channel tonal treatment.",
|
|
1194
|
+
id: "monochrome",
|
|
1195
|
+
label: "Monochrome"
|
|
1035
1196
|
}
|
|
1036
1197
|
],
|
|
1037
1198
|
genre: [
|
|
@@ -1042,20 +1203,12 @@ var CREATIVE_TAXONOMY = {
|
|
|
1042
1203
|
label: "Film noir"
|
|
1043
1204
|
}
|
|
1044
1205
|
],
|
|
1045
|
-
|
|
1046
|
-
{
|
|
1047
|
-
clause: "macro product photography with crisp surface detail",
|
|
1048
|
-
description: "Product-oriented macro camera language for close detail.",
|
|
1049
|
-
id: "macro-product",
|
|
1050
|
-
label: "Macro product"
|
|
1051
|
-
}
|
|
1052
|
-
],
|
|
1053
|
-
color: [
|
|
1206
|
+
lighting: [
|
|
1054
1207
|
{
|
|
1055
|
-
clause: "
|
|
1056
|
-
description: "
|
|
1057
|
-
id: "
|
|
1058
|
-
label: "
|
|
1208
|
+
clause: "rim lighting with defined edge highlights",
|
|
1209
|
+
description: "Back or side light that separates the subject edge.",
|
|
1210
|
+
id: "rim",
|
|
1211
|
+
label: "Rim"
|
|
1059
1212
|
}
|
|
1060
1213
|
],
|
|
1061
1214
|
material: [
|
|
@@ -1073,10 +1226,26 @@ var CREATIVE_TAXONOMY = {
|
|
|
1073
1226
|
id: "still",
|
|
1074
1227
|
label: "Still"
|
|
1075
1228
|
}
|
|
1229
|
+
],
|
|
1230
|
+
recipe: [
|
|
1231
|
+
{
|
|
1232
|
+
clause: "cinematic scene",
|
|
1233
|
+
description: "Frames the prompt as a cinematic still or scene.",
|
|
1234
|
+
id: "cinematic",
|
|
1235
|
+
label: "Cinematic"
|
|
1236
|
+
}
|
|
1237
|
+
],
|
|
1238
|
+
shot: [
|
|
1239
|
+
{
|
|
1240
|
+
clause: "close-up composition with controlled depth of field",
|
|
1241
|
+
description: "Tight framing that emphasizes subject detail.",
|
|
1242
|
+
id: "close-up",
|
|
1243
|
+
label: "Close-up"
|
|
1244
|
+
}
|
|
1076
1245
|
]
|
|
1077
1246
|
};
|
|
1078
1247
|
function sanitizePrompt(prompt) {
|
|
1079
|
-
return prompt.replace(CONTROL_CHAR_REGEX, "").
|
|
1248
|
+
return prompt.replace(CONTROL_CHAR_REGEX, "").replaceAll("\r\n", "\n").trim();
|
|
1080
1249
|
}
|
|
1081
1250
|
function enrichPrompt(options) {
|
|
1082
1251
|
const basePrompt = sanitizePrompt(options.prompt);
|
|
@@ -1084,7 +1253,7 @@ function enrichPrompt(options) {
|
|
|
1084
1253
|
const selected = {};
|
|
1085
1254
|
for (const field of CREATIVE_FIELDS) {
|
|
1086
1255
|
const optionId = options.creative?.[field];
|
|
1087
|
-
if (
|
|
1256
|
+
if (optionId === void 0 || optionId === "") {
|
|
1088
1257
|
continue;
|
|
1089
1258
|
}
|
|
1090
1259
|
const option = CREATIVE_TAXONOMY[field].find(
|
|
@@ -1159,11 +1328,11 @@ function normalizeImageSize(imageSize, sizeMode) {
|
|
|
1159
1328
|
if (FAL_IMAGE_SIZE_PRESETS.includes(imageSize)) {
|
|
1160
1329
|
return imageSize;
|
|
1161
1330
|
}
|
|
1162
|
-
const match =
|
|
1331
|
+
const match = /^(\d+)x(\d+)$/.exec(imageSize);
|
|
1163
1332
|
if (match) {
|
|
1164
1333
|
const width = Number(match[1]);
|
|
1165
1334
|
const height = Number(match[2]);
|
|
1166
|
-
return {
|
|
1335
|
+
return { height, width };
|
|
1167
1336
|
}
|
|
1168
1337
|
throw new Error(
|
|
1169
1338
|
`fal image_size must be one of ${FAL_IMAGE_SIZE_PRESETS.join(", ")} or WIDTHxHEIGHT`
|
|
@@ -1173,12 +1342,12 @@ function unsupported(config, option) {
|
|
|
1173
1342
|
throw new Error(`${config.name} does not support ${option}`);
|
|
1174
1343
|
}
|
|
1175
1344
|
function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
1176
|
-
if (options.editImageUrls
|
|
1345
|
+
if (options.editImageUrls !== void 0 && options.editImageUrls.length > 0 && config.maxReferenceImages !== void 0 && options.editImageUrls.length > config.maxReferenceImages) {
|
|
1177
1346
|
throw new Error(
|
|
1178
1347
|
`${config.name} supports at most ${config.maxReferenceImages} reference images`
|
|
1179
1348
|
);
|
|
1180
1349
|
}
|
|
1181
|
-
if (options.editImageUrls
|
|
1350
|
+
if (options.editImageUrls !== void 0 && options.editImageUrls.length > 0 && !config.supportsEdit) {
|
|
1182
1351
|
unsupported(config, "image editing");
|
|
1183
1352
|
}
|
|
1184
1353
|
if (options.aspect !== void 0 && sizeMode === "none") {
|
|
@@ -1190,10 +1359,10 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
1190
1359
|
if (options.numImages !== void 0 && options.numImages !== 1 && !config.supportsNumImages) {
|
|
1191
1360
|
unsupported(config, "numImages");
|
|
1192
1361
|
}
|
|
1193
|
-
if (options.background !== void 0 &&
|
|
1362
|
+
if (options.background !== void 0 && config.supportsBackground !== true) {
|
|
1194
1363
|
unsupported(config, "background");
|
|
1195
1364
|
}
|
|
1196
|
-
if (options.transparent && !(config.supportsBackground || config.supportsOutputFormat)) {
|
|
1365
|
+
if (options.transparent === true && !(config.supportsBackground === true || config.supportsOutputFormat === true)) {
|
|
1197
1366
|
unsupported(config, "transparent output");
|
|
1198
1367
|
}
|
|
1199
1368
|
if (options.inputFidelity !== void 0) {
|
|
@@ -1207,70 +1376,70 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
1207
1376
|
if (options.imageSize !== void 0 && sizeMode !== "gpt_size" && sizeMode !== "image_size_enum") {
|
|
1208
1377
|
unsupported(config, "imageSize");
|
|
1209
1378
|
}
|
|
1210
|
-
if (options.imagePromptStrength !== void 0 &&
|
|
1379
|
+
if (options.imagePromptStrength !== void 0 && config.supportsImagePromptStrength !== true) {
|
|
1211
1380
|
unsupported(config, "imagePromptStrength");
|
|
1212
1381
|
}
|
|
1213
1382
|
if (options.imagePromptStrength !== void 0 && !hasEditImages) {
|
|
1214
1383
|
throw new Error("imagePromptStrength requires editImageUrls");
|
|
1215
1384
|
}
|
|
1216
|
-
if (options.maskImageUrl !== void 0 &&
|
|
1385
|
+
if (options.maskImageUrl !== void 0 && config.supportsMaskImage !== true) {
|
|
1217
1386
|
unsupported(config, "maskImageUrl");
|
|
1218
1387
|
}
|
|
1219
1388
|
if (options.maskImageUrl !== void 0 && !hasEditImages) {
|
|
1220
1389
|
throw new Error("maskImageUrl requires editImageUrls");
|
|
1221
1390
|
}
|
|
1222
|
-
if (options.seed !== void 0 &&
|
|
1391
|
+
if (options.seed !== void 0 && config.supportsSeed !== true) {
|
|
1223
1392
|
unsupported(config, "seed");
|
|
1224
1393
|
}
|
|
1225
|
-
if (options.outputFormat !== void 0 &&
|
|
1394
|
+
if (options.outputFormat !== void 0 && config.supportsOutputFormat !== true) {
|
|
1226
1395
|
unsupported(config, "outputFormat");
|
|
1227
1396
|
}
|
|
1228
|
-
if (options.quality !== void 0 &&
|
|
1397
|
+
if (options.quality !== void 0 && config.supportsQuality !== true) {
|
|
1229
1398
|
unsupported(config, "quality");
|
|
1230
1399
|
}
|
|
1231
|
-
if (options.negativePrompt !== void 0 &&
|
|
1400
|
+
if (options.negativePrompt !== void 0 && config.supportsNegativePrompt !== true) {
|
|
1232
1401
|
unsupported(config, "negativePrompt");
|
|
1233
1402
|
}
|
|
1234
|
-
if (options.style !== void 0 &&
|
|
1403
|
+
if (options.style !== void 0 && config.supportsStyle !== true) {
|
|
1235
1404
|
unsupported(config, "style");
|
|
1236
1405
|
}
|
|
1237
|
-
if (options.syncMode !== void 0 &&
|
|
1406
|
+
if (options.syncMode !== void 0 && config.supportsSyncMode !== true) {
|
|
1238
1407
|
unsupported(config, "syncMode");
|
|
1239
1408
|
}
|
|
1240
|
-
if (options.renderingSpeed !== void 0 &&
|
|
1409
|
+
if (options.renderingSpeed !== void 0 && config.supportsRenderingSpeed !== true) {
|
|
1241
1410
|
unsupported(config, "renderingSpeed");
|
|
1242
1411
|
}
|
|
1243
|
-
if (options.guidanceScale !== void 0 &&
|
|
1412
|
+
if (options.guidanceScale !== void 0 && config.supportsGuidanceScale !== true) {
|
|
1244
1413
|
unsupported(config, "guidanceScale");
|
|
1245
1414
|
}
|
|
1246
|
-
if (options.numInferenceSteps !== void 0 &&
|
|
1415
|
+
if (options.numInferenceSteps !== void 0 && config.supportsInferenceSteps !== true) {
|
|
1247
1416
|
unsupported(config, "numInferenceSteps");
|
|
1248
1417
|
}
|
|
1249
|
-
if (options.raw !== void 0 &&
|
|
1418
|
+
if (options.raw !== void 0 && config.supportsRaw !== true) {
|
|
1250
1419
|
unsupported(config, "raw");
|
|
1251
1420
|
}
|
|
1252
|
-
if (options.enhancePrompt !== void 0 &&
|
|
1421
|
+
if (options.enhancePrompt !== void 0 && config.supportsEnhancePrompt !== true) {
|
|
1253
1422
|
unsupported(config, "enhancePrompt");
|
|
1254
1423
|
}
|
|
1255
|
-
if (options.safetyTolerance !== void 0 &&
|
|
1424
|
+
if (options.safetyTolerance !== void 0 && config.supportsSafetyTolerance !== true) {
|
|
1256
1425
|
unsupported(config, "safetyTolerance");
|
|
1257
1426
|
}
|
|
1258
|
-
if (options.enableWebSearch !== void 0 &&
|
|
1427
|
+
if (options.enableWebSearch !== void 0 && config.supportsWebSearch !== true) {
|
|
1259
1428
|
unsupported(config, "enableWebSearch");
|
|
1260
1429
|
}
|
|
1261
|
-
if (options.enableGoogleSearch !== void 0 &&
|
|
1430
|
+
if (options.enableGoogleSearch !== void 0 && config.supportsGoogleSearch !== true) {
|
|
1262
1431
|
unsupported(config, "enableGoogleSearch");
|
|
1263
1432
|
}
|
|
1264
|
-
if (options.enableSafetyChecker !== void 0 &&
|
|
1433
|
+
if (options.enableSafetyChecker !== void 0 && config.supportsSafetyChecker !== true) {
|
|
1265
1434
|
unsupported(config, "enableSafetyChecker");
|
|
1266
1435
|
}
|
|
1267
|
-
if (options.limitGenerations !== void 0 &&
|
|
1436
|
+
if (options.limitGenerations !== void 0 && config.supportsLimitGenerations !== true) {
|
|
1268
1437
|
unsupported(config, "limitGenerations");
|
|
1269
1438
|
}
|
|
1270
|
-
if (options.thinkingLevel !== void 0 &&
|
|
1439
|
+
if (options.thinkingLevel !== void 0 && config.supportsThinkingLevel !== true) {
|
|
1271
1440
|
unsupported(config, "thinkingLevel");
|
|
1272
1441
|
}
|
|
1273
|
-
if (options.expandPrompt !== void 0 &&
|
|
1442
|
+
if (options.expandPrompt !== void 0 && config.supportsExpandPrompt !== true) {
|
|
1274
1443
|
unsupported(config, "expandPrompt");
|
|
1275
1444
|
}
|
|
1276
1445
|
}
|
|
@@ -1312,8 +1481,8 @@ function buildGenerateBody(options) {
|
|
|
1312
1481
|
if (!config) {
|
|
1313
1482
|
throw new Error(`Unknown model: ${model}`);
|
|
1314
1483
|
}
|
|
1315
|
-
let endpoint = config
|
|
1316
|
-
const enrichedPrompt = creative ? enrichPrompt({
|
|
1484
|
+
let { endpoint } = config;
|
|
1485
|
+
const enrichedPrompt = creative ? enrichPrompt({ creative, prompt }).prompt : prompt;
|
|
1317
1486
|
const body = { prompt: enrichedPrompt };
|
|
1318
1487
|
const hasEditImages = Boolean(editImageUrls?.length);
|
|
1319
1488
|
const editImages = editImageUrls ?? [];
|
|
@@ -1322,13 +1491,15 @@ function buildGenerateBody(options) {
|
|
|
1322
1491
|
validateGenerateOptions(options, config, sizeMode, hasEditImages);
|
|
1323
1492
|
const normalizedImageSize = normalizeImageSize(imageSize, sizeMode);
|
|
1324
1493
|
switch (sizeMode) {
|
|
1325
|
-
case "gpt_size":
|
|
1494
|
+
case "gpt_size": {
|
|
1326
1495
|
body.image_size = normalizedImageSize ?? (hasEditImages && !explicitAspect ? "auto" : aspectToGptSize(aspect));
|
|
1327
1496
|
break;
|
|
1328
|
-
|
|
1497
|
+
}
|
|
1498
|
+
case "image_size_enum": {
|
|
1329
1499
|
body.image_size = normalizedImageSize ?? aspectToFalImageSize(aspect);
|
|
1330
1500
|
break;
|
|
1331
|
-
|
|
1501
|
+
}
|
|
1502
|
+
case "aspect_ratio": {
|
|
1332
1503
|
if (config.supportsAspect) {
|
|
1333
1504
|
body.aspect_ratio = aspect;
|
|
1334
1505
|
}
|
|
@@ -1336,26 +1507,30 @@ function buildGenerateBody(options) {
|
|
|
1336
1507
|
body.resolution = model === "grok-image" ? resolution.toLowerCase() : resolution;
|
|
1337
1508
|
}
|
|
1338
1509
|
break;
|
|
1510
|
+
}
|
|
1511
|
+
case "none": {
|
|
1512
|
+
break;
|
|
1513
|
+
}
|
|
1339
1514
|
}
|
|
1340
|
-
if (config.supportsQuality) {
|
|
1515
|
+
if (config.supportsQuality === true) {
|
|
1341
1516
|
body.quality = quality ?? "high";
|
|
1342
1517
|
}
|
|
1343
|
-
if (config.supportsBackground && background) {
|
|
1518
|
+
if (config.supportsBackground === true && background) {
|
|
1344
1519
|
body.background = background;
|
|
1345
1520
|
}
|
|
1346
|
-
if (config.supportsBackground && transparent) {
|
|
1521
|
+
if (config.supportsBackground === true && transparent === true) {
|
|
1347
1522
|
body.background = "transparent";
|
|
1348
1523
|
}
|
|
1349
|
-
if (transparent && config.supportsOutputFormat) {
|
|
1524
|
+
if (transparent === true && config.supportsOutputFormat === true) {
|
|
1350
1525
|
body.output_format = "png";
|
|
1351
1526
|
}
|
|
1352
|
-
if (syncMode !== void 0 && config.supportsSyncMode) {
|
|
1527
|
+
if (syncMode !== void 0 && config.supportsSyncMode === true) {
|
|
1353
1528
|
body.sync_mode = syncMode;
|
|
1354
1529
|
}
|
|
1355
|
-
if (seed !== void 0 && config.supportsSeed) {
|
|
1530
|
+
if (seed !== void 0 && config.supportsSeed === true) {
|
|
1356
1531
|
body.seed = seed;
|
|
1357
1532
|
}
|
|
1358
|
-
if (outputFormat && config.supportsOutputFormat &&
|
|
1533
|
+
if (outputFormat && config.supportsOutputFormat === true && transparent !== true) {
|
|
1359
1534
|
if (config.supportedOutputFormats && !config.supportedOutputFormats.includes(outputFormat)) {
|
|
1360
1535
|
throw new Error(
|
|
1361
1536
|
`${config.name} supports output formats: ${config.supportedOutputFormats.join(", ")}`
|
|
@@ -1363,62 +1538,78 @@ function buildGenerateBody(options) {
|
|
|
1363
1538
|
}
|
|
1364
1539
|
body.output_format = outputFormat;
|
|
1365
1540
|
}
|
|
1366
|
-
if (config.supportsRaw && raw !== void 0) {
|
|
1541
|
+
if (config.supportsRaw === true && raw !== void 0) {
|
|
1367
1542
|
body.raw = raw;
|
|
1368
1543
|
}
|
|
1369
|
-
if (config.supportsEnhancePrompt && enhancePrompt !== void 0) {
|
|
1544
|
+
if (config.supportsEnhancePrompt === true && enhancePrompt !== void 0) {
|
|
1370
1545
|
body.enhance_prompt = enhancePrompt;
|
|
1371
1546
|
}
|
|
1372
|
-
if (config.supportsImagePromptStrength && imagePromptStrength !== void 0) {
|
|
1547
|
+
if (config.supportsImagePromptStrength === true && imagePromptStrength !== void 0) {
|
|
1373
1548
|
body.image_prompt_strength = imagePromptStrength;
|
|
1374
1549
|
}
|
|
1375
1550
|
if (model === "flux") {
|
|
1376
|
-
if (safetyTolerance
|
|
1551
|
+
if (safetyTolerance !== void 0 && safetyTolerance !== "") {
|
|
1552
|
+
body.safety_tolerance = safetyTolerance;
|
|
1553
|
+
}
|
|
1377
1554
|
}
|
|
1378
|
-
if (config.supportsGuidanceScale && guidanceScale !== void 0) {
|
|
1555
|
+
if (config.supportsGuidanceScale === true && guidanceScale !== void 0) {
|
|
1379
1556
|
body.guidance_scale = guidanceScale;
|
|
1380
1557
|
}
|
|
1381
|
-
if (config.supportsInferenceSteps && numInferenceSteps !== void 0) {
|
|
1558
|
+
if (config.supportsInferenceSteps === true && numInferenceSteps !== void 0) {
|
|
1382
1559
|
body.num_inference_steps = numInferenceSteps;
|
|
1383
1560
|
}
|
|
1384
|
-
if (config.supportsSafetyTolerance) {
|
|
1385
|
-
if (safetyTolerance
|
|
1561
|
+
if (config.supportsSafetyTolerance === true) {
|
|
1562
|
+
if (safetyTolerance !== void 0 && safetyTolerance !== "") {
|
|
1563
|
+
body.safety_tolerance = safetyTolerance;
|
|
1564
|
+
}
|
|
1386
1565
|
}
|
|
1387
|
-
if (config.supportsWebSearch) {
|
|
1388
|
-
if (enableWebSearch !== void 0)
|
|
1566
|
+
if (config.supportsWebSearch === true) {
|
|
1567
|
+
if (enableWebSearch !== void 0) {
|
|
1568
|
+
body.enable_web_search = enableWebSearch;
|
|
1569
|
+
}
|
|
1389
1570
|
}
|
|
1390
|
-
if (config.supportsGoogleSearch) {
|
|
1571
|
+
if (config.supportsGoogleSearch === true) {
|
|
1391
1572
|
if (enableGoogleSearch !== void 0) {
|
|
1392
1573
|
body.enable_google_search = enableGoogleSearch;
|
|
1393
1574
|
}
|
|
1394
1575
|
}
|
|
1395
|
-
if (config.supportsSafetyChecker) {
|
|
1576
|
+
if (config.supportsSafetyChecker === true) {
|
|
1396
1577
|
if (enableSafetyChecker !== void 0) {
|
|
1397
1578
|
body.enable_safety_checker = enableSafetyChecker;
|
|
1398
1579
|
}
|
|
1399
1580
|
}
|
|
1400
|
-
if (config.supportsLimitGenerations) {
|
|
1581
|
+
if (config.supportsLimitGenerations === true) {
|
|
1401
1582
|
if (limitGenerations !== void 0) {
|
|
1402
1583
|
body.limit_generations = limitGenerations;
|
|
1403
1584
|
}
|
|
1404
1585
|
}
|
|
1405
|
-
if (config.supportsThinkingLevel) {
|
|
1406
|
-
if (thinkingLevel)
|
|
1586
|
+
if (config.supportsThinkingLevel === true) {
|
|
1587
|
+
if (thinkingLevel) {
|
|
1588
|
+
body.thinking_level = thinkingLevel;
|
|
1589
|
+
}
|
|
1407
1590
|
}
|
|
1408
|
-
if (config.supportsStyle && style) {
|
|
1591
|
+
if (config.supportsStyle === true && style !== void 0 && style !== "") {
|
|
1409
1592
|
body.style = style;
|
|
1410
1593
|
}
|
|
1411
|
-
if (config.supportsNegativePrompt) {
|
|
1412
|
-
if (negativePrompt
|
|
1594
|
+
if (config.supportsNegativePrompt === true) {
|
|
1595
|
+
if (negativePrompt !== void 0 && negativePrompt !== "") {
|
|
1596
|
+
body.negative_prompt = negativePrompt;
|
|
1597
|
+
}
|
|
1413
1598
|
}
|
|
1414
1599
|
if (model === "ideogram") {
|
|
1415
|
-
if (style
|
|
1600
|
+
if (style !== void 0 && style !== "") {
|
|
1601
|
+
body.style = style;
|
|
1602
|
+
}
|
|
1416
1603
|
}
|
|
1417
|
-
if (config.supportsRenderingSpeed) {
|
|
1418
|
-
if (renderingSpeed)
|
|
1604
|
+
if (config.supportsRenderingSpeed === true) {
|
|
1605
|
+
if (renderingSpeed) {
|
|
1606
|
+
body.rendering_speed = renderingSpeed;
|
|
1607
|
+
}
|
|
1419
1608
|
}
|
|
1420
|
-
if (config.supportsExpandPrompt) {
|
|
1421
|
-
if (expandPrompt !== void 0)
|
|
1609
|
+
if (config.supportsExpandPrompt === true) {
|
|
1610
|
+
if (expandPrompt !== void 0) {
|
|
1611
|
+
body.expand_prompt = expandPrompt;
|
|
1612
|
+
}
|
|
1422
1613
|
}
|
|
1423
1614
|
if (model === "flux" && hasEditImages) {
|
|
1424
1615
|
body.image_url = editImages[0];
|
|
@@ -1445,959 +1636,1045 @@ function buildGenerateBody(options) {
|
|
|
1445
1636
|
body.input_fidelity = inputFidelity;
|
|
1446
1637
|
}
|
|
1447
1638
|
}
|
|
1448
|
-
if (maskImageUrl && config.supportsMaskImage) {
|
|
1639
|
+
if (maskImageUrl !== void 0 && maskImageUrl !== "" && config.supportsMaskImage === true) {
|
|
1449
1640
|
body.mask_image_url = maskImageUrl;
|
|
1450
1641
|
}
|
|
1451
|
-
return {
|
|
1642
|
+
return { body, endpoint };
|
|
1452
1643
|
}
|
|
1453
1644
|
|
|
1454
1645
|
// src/leaderboards.ts
|
|
1455
1646
|
var IMAGE_TEXT_TO_IMAGE_TOP_20 = {
|
|
1456
1647
|
capturedAt: "2026-05-12",
|
|
1457
|
-
source: "https://artificialanalysis.ai/image/leaderboard/text-to-image",
|
|
1458
1648
|
entries: [
|
|
1459
1649
|
{
|
|
1460
|
-
|
|
1650
|
+
apiPricing: "$211/1k images",
|
|
1461
1651
|
creator: "OpenAI",
|
|
1462
|
-
model: "GPT Image 2 (high)",
|
|
1463
1652
|
elo: 1337,
|
|
1464
|
-
apiPricing: "$211/1k images",
|
|
1465
1653
|
isCurrent: true,
|
|
1654
|
+
model: "GPT Image 2 (high)",
|
|
1655
|
+
rank: 1,
|
|
1466
1656
|
routableModelId: "gpt2"
|
|
1467
1657
|
},
|
|
1468
1658
|
{
|
|
1469
|
-
|
|
1659
|
+
apiPricing: "$133/1k images",
|
|
1470
1660
|
creator: "OpenAI",
|
|
1471
|
-
model: "GPT Image 1.5 (high)",
|
|
1472
1661
|
elo: 1268,
|
|
1473
|
-
apiPricing: "$133/1k images",
|
|
1474
1662
|
isCurrent: true,
|
|
1663
|
+
model: "GPT Image 1.5 (high)",
|
|
1664
|
+
rank: 2,
|
|
1475
1665
|
routableModelId: "gpt"
|
|
1476
1666
|
},
|
|
1477
1667
|
{
|
|
1478
|
-
|
|
1668
|
+
apiPricing: "$67/1k images",
|
|
1479
1669
|
creator: "Google",
|
|
1480
|
-
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1481
1670
|
elo: 1263,
|
|
1482
|
-
apiPricing: "$67/1k images",
|
|
1483
1671
|
isCurrent: true,
|
|
1484
|
-
|
|
1672
|
+
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1673
|
+
rank: 3,
|
|
1674
|
+
routableModelId: "banana2"
|
|
1485
1675
|
},
|
|
1486
1676
|
{
|
|
1487
|
-
|
|
1677
|
+
apiPricing: "$150/1k images",
|
|
1488
1678
|
creator: "Sourceful",
|
|
1489
|
-
model: "Riverflow 2.0",
|
|
1490
1679
|
elo: 1256,
|
|
1491
|
-
|
|
1492
|
-
|
|
1680
|
+
isCurrent: true,
|
|
1681
|
+
model: "Riverflow 2.0",
|
|
1682
|
+
rank: 4
|
|
1493
1683
|
},
|
|
1494
1684
|
{
|
|
1495
|
-
|
|
1685
|
+
apiPricing: "$134/1k images",
|
|
1496
1686
|
creator: "Google",
|
|
1497
|
-
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
1498
1687
|
elo: 1220,
|
|
1499
|
-
apiPricing: "$134/1k images",
|
|
1500
1688
|
isCurrent: true,
|
|
1689
|
+
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
1690
|
+
rank: 5,
|
|
1501
1691
|
routableModelId: "banana"
|
|
1502
1692
|
},
|
|
1503
1693
|
{
|
|
1504
|
-
|
|
1694
|
+
apiPricing: "$30/1k images",
|
|
1505
1695
|
creator: "ByteDance Seed",
|
|
1506
|
-
model: "Seedream 4.0",
|
|
1507
1696
|
elo: 1198,
|
|
1508
|
-
apiPricing: "$30/1k images",
|
|
1509
1697
|
isCurrent: true,
|
|
1698
|
+
model: "Seedream 4.0",
|
|
1699
|
+
rank: 6,
|
|
1510
1700
|
routableModelId: "seedream4"
|
|
1511
1701
|
},
|
|
1512
1702
|
{
|
|
1513
|
-
|
|
1703
|
+
apiPricing: "$50/1k images",
|
|
1514
1704
|
creator: "Microsoft",
|
|
1515
|
-
model: "MAI-Image-2",
|
|
1516
1705
|
elo: 1198,
|
|
1517
|
-
|
|
1518
|
-
|
|
1706
|
+
isCurrent: true,
|
|
1707
|
+
model: "MAI-Image-2",
|
|
1708
|
+
rank: 7
|
|
1519
1709
|
},
|
|
1520
1710
|
{
|
|
1521
|
-
|
|
1711
|
+
apiPricing: "$70/1k images",
|
|
1522
1712
|
creator: "Black Forest Labs",
|
|
1523
|
-
model: "FLUX.2 [max]",
|
|
1524
1713
|
elo: 1197,
|
|
1525
|
-
apiPricing: "$70/1k images",
|
|
1526
1714
|
isCurrent: true,
|
|
1715
|
+
model: "FLUX.2 [max]",
|
|
1716
|
+
rank: 8,
|
|
1527
1717
|
routableModelId: "flux2-max"
|
|
1528
1718
|
},
|
|
1529
1719
|
{
|
|
1530
|
-
|
|
1720
|
+
apiPricing: "Unavailable",
|
|
1531
1721
|
creator: "Peanut",
|
|
1532
|
-
model: "Peanut (Open Weights Coming Soon)",
|
|
1533
1722
|
elo: 1187,
|
|
1534
|
-
|
|
1535
|
-
|
|
1723
|
+
isCurrent: true,
|
|
1724
|
+
model: "Peanut (Open Weights Coming Soon)",
|
|
1725
|
+
rank: 9
|
|
1536
1726
|
},
|
|
1537
1727
|
{
|
|
1538
|
-
|
|
1728
|
+
apiPricing: "$30/1k images",
|
|
1539
1729
|
creator: "Black Forest Labs",
|
|
1540
|
-
model: "FLUX.2 [pro]",
|
|
1541
1730
|
elo: 1186,
|
|
1542
|
-
apiPricing: "$30/1k images",
|
|
1543
1731
|
isCurrent: true,
|
|
1732
|
+
model: "FLUX.2 [pro]",
|
|
1733
|
+
rank: 10,
|
|
1544
1734
|
routableModelId: "flux2-pro"
|
|
1545
1735
|
},
|
|
1546
1736
|
{
|
|
1547
|
-
|
|
1737
|
+
apiPricing: "$60/1k images",
|
|
1548
1738
|
creator: "Google",
|
|
1549
|
-
model: "Imagen 4 Ultra Preview 0606",
|
|
1550
1739
|
elo: 1184,
|
|
1551
|
-
|
|
1552
|
-
|
|
1740
|
+
isCurrent: false,
|
|
1741
|
+
model: "Imagen 4 Ultra Preview 0606",
|
|
1742
|
+
rank: 11
|
|
1553
1743
|
},
|
|
1554
1744
|
{
|
|
1555
|
-
|
|
1745
|
+
apiPricing: "$20/1k images",
|
|
1556
1746
|
creator: "xAI",
|
|
1557
|
-
model: "grok-imagine-image",
|
|
1558
1747
|
elo: 1182,
|
|
1559
|
-
apiPricing: "$20/1k images",
|
|
1560
1748
|
isCurrent: true,
|
|
1749
|
+
model: "grok-imagine-image",
|
|
1750
|
+
rank: 12,
|
|
1561
1751
|
routableModelId: "grok-image"
|
|
1562
1752
|
},
|
|
1563
1753
|
{
|
|
1564
|
-
|
|
1754
|
+
apiPricing: "$60/1k images",
|
|
1565
1755
|
creator: "Black Forest Labs",
|
|
1566
|
-
model: "FLUX.2 [flex]",
|
|
1567
1756
|
elo: 1182,
|
|
1568
|
-
apiPricing: "$60/1k images",
|
|
1569
1757
|
isCurrent: true,
|
|
1758
|
+
model: "FLUX.2 [flex]",
|
|
1759
|
+
rank: 13,
|
|
1570
1760
|
routableModelId: "flux2-flex"
|
|
1571
1761
|
},
|
|
1572
1762
|
{
|
|
1573
|
-
|
|
1763
|
+
apiPricing: "$30/1k images",
|
|
1574
1764
|
creator: "ImagineArt",
|
|
1575
|
-
model: "ImagineArt 2.0",
|
|
1576
1765
|
elo: 1181,
|
|
1577
|
-
|
|
1578
|
-
|
|
1766
|
+
isCurrent: true,
|
|
1767
|
+
model: "ImagineArt 2.0",
|
|
1768
|
+
rank: 14
|
|
1579
1769
|
},
|
|
1580
1770
|
{
|
|
1581
|
-
|
|
1771
|
+
apiPricing: "$60/1k images",
|
|
1582
1772
|
creator: "Google",
|
|
1583
|
-
model: "Imagen 4 Ultra",
|
|
1584
1773
|
elo: 1171,
|
|
1585
|
-
|
|
1586
|
-
|
|
1774
|
+
isCurrent: true,
|
|
1775
|
+
model: "Imagen 4 Ultra",
|
|
1776
|
+
rank: 15
|
|
1587
1777
|
},
|
|
1588
1778
|
{
|
|
1589
|
-
|
|
1779
|
+
apiPricing: "$40/1k images",
|
|
1590
1780
|
creator: "Google",
|
|
1591
|
-
model: "Imagen 4 Preview 0606",
|
|
1592
1781
|
elo: 1169,
|
|
1593
|
-
|
|
1594
|
-
|
|
1782
|
+
isCurrent: false,
|
|
1783
|
+
model: "Imagen 4 Preview 0606",
|
|
1784
|
+
rank: 16
|
|
1595
1785
|
},
|
|
1596
1786
|
{
|
|
1597
|
-
|
|
1787
|
+
apiPricing: "$40/1k images",
|
|
1598
1788
|
creator: "ByteDance Seed",
|
|
1599
|
-
model: "Seedream 4.5",
|
|
1600
1789
|
elo: 1167,
|
|
1601
|
-
apiPricing: "$40/1k images",
|
|
1602
1790
|
isCurrent: true,
|
|
1791
|
+
model: "Seedream 4.5",
|
|
1792
|
+
rank: 17,
|
|
1603
1793
|
routableModelId: "seedream45"
|
|
1604
1794
|
},
|
|
1605
1795
|
{
|
|
1606
|
-
|
|
1796
|
+
apiPricing: "$8/1k images",
|
|
1607
1797
|
creator: "Fal",
|
|
1608
|
-
model: "FLUX.2 [dev] Turbo",
|
|
1609
1798
|
elo: 1161,
|
|
1610
|
-
|
|
1611
|
-
|
|
1799
|
+
isCurrent: true,
|
|
1800
|
+
model: "FLUX.2 [dev] Turbo",
|
|
1801
|
+
rank: 18
|
|
1612
1802
|
},
|
|
1613
1803
|
{
|
|
1614
|
-
|
|
1804
|
+
apiPricing: "$12/1k images",
|
|
1615
1805
|
creator: "Black Forest Labs",
|
|
1616
|
-
model: "FLUX.2 [dev]",
|
|
1617
1806
|
elo: 1160,
|
|
1618
|
-
apiPricing: "$12/1k images",
|
|
1619
1807
|
isCurrent: true,
|
|
1808
|
+
model: "FLUX.2 [dev]",
|
|
1809
|
+
rank: 19,
|
|
1620
1810
|
routableModelId: "flux2-dev"
|
|
1621
1811
|
},
|
|
1622
1812
|
{
|
|
1623
|
-
|
|
1813
|
+
apiPricing: "$20/1k images",
|
|
1624
1814
|
creator: "Alibaba",
|
|
1625
|
-
model: "Qwen Image Max 2512",
|
|
1626
1815
|
elo: 1158,
|
|
1627
|
-
apiPricing: "$20/1k images",
|
|
1628
1816
|
isCurrent: true,
|
|
1817
|
+
model: "Qwen Image Max 2512",
|
|
1818
|
+
rank: 20,
|
|
1629
1819
|
routableModelId: "qwen"
|
|
1630
1820
|
}
|
|
1631
|
-
]
|
|
1821
|
+
],
|
|
1822
|
+
source: "https://artificialanalysis.ai/image/leaderboard/text-to-image"
|
|
1632
1823
|
};
|
|
1633
1824
|
var IMAGE_EDITING_TOP_20 = {
|
|
1634
1825
|
capturedAt: "2026-05-12",
|
|
1635
|
-
source: "https://artificialanalysis.ai/image/leaderboard/editing",
|
|
1636
1826
|
entries: [
|
|
1637
1827
|
{
|
|
1638
|
-
|
|
1828
|
+
apiPricing: "$150/1k images",
|
|
1639
1829
|
creator: "Sourceful",
|
|
1640
|
-
model: "Riverflow 2.0",
|
|
1641
1830
|
elo: 1286,
|
|
1642
|
-
|
|
1643
|
-
|
|
1831
|
+
isCurrent: true,
|
|
1832
|
+
model: "Riverflow 2.0",
|
|
1833
|
+
rank: 1
|
|
1644
1834
|
},
|
|
1645
1835
|
{
|
|
1646
|
-
|
|
1836
|
+
apiPricing: "$133/1k images",
|
|
1647
1837
|
creator: "OpenAI",
|
|
1648
|
-
model: "GPT Image 1.5 (high)",
|
|
1649
1838
|
elo: 1262,
|
|
1650
|
-
apiPricing: "$133/1k images",
|
|
1651
1839
|
isCurrent: true,
|
|
1840
|
+
model: "GPT Image 1.5 (high)",
|
|
1841
|
+
rank: 2,
|
|
1652
1842
|
routableModelId: "gpt"
|
|
1653
1843
|
},
|
|
1654
1844
|
{
|
|
1655
|
-
|
|
1845
|
+
apiPricing: "$211/1k images",
|
|
1656
1846
|
creator: "OpenAI",
|
|
1657
|
-
model: "GPT Image 2 (high)",
|
|
1658
1847
|
elo: 1249,
|
|
1659
|
-
apiPricing: "$211/1k images",
|
|
1660
1848
|
isCurrent: true,
|
|
1849
|
+
model: "GPT Image 2 (high)",
|
|
1850
|
+
rank: 3,
|
|
1661
1851
|
routableModelId: "gpt2"
|
|
1662
1852
|
},
|
|
1663
1853
|
{
|
|
1664
|
-
|
|
1854
|
+
apiPricing: "$134/1k images",
|
|
1665
1855
|
creator: "Google",
|
|
1666
|
-
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
1667
1856
|
elo: 1241,
|
|
1668
|
-
apiPricing: "$134/1k images",
|
|
1669
1857
|
isCurrent: true,
|
|
1858
|
+
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
1859
|
+
rank: 4,
|
|
1670
1860
|
routableModelId: "banana"
|
|
1671
1861
|
},
|
|
1672
1862
|
{
|
|
1673
|
-
|
|
1863
|
+
apiPricing: "$67/1k images",
|
|
1674
1864
|
creator: "Google",
|
|
1675
|
-
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1676
1865
|
elo: 1231,
|
|
1677
|
-
apiPricing: "$67/1k images",
|
|
1678
1866
|
isCurrent: true,
|
|
1867
|
+
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1868
|
+
rank: 5,
|
|
1679
1869
|
routableModelId: "banana2"
|
|
1680
1870
|
},
|
|
1681
1871
|
{
|
|
1682
|
-
|
|
1872
|
+
apiPricing: "$90/1k images",
|
|
1683
1873
|
creator: "Tencent",
|
|
1684
|
-
model: "HunyuanImage 3.0 Instruct (Fal)",
|
|
1685
1874
|
elo: 1222,
|
|
1686
|
-
|
|
1687
|
-
|
|
1875
|
+
isCurrent: true,
|
|
1876
|
+
model: "HunyuanImage 3.0 Instruct (Fal)",
|
|
1877
|
+
rank: 6
|
|
1688
1878
|
},
|
|
1689
1879
|
{
|
|
1690
|
-
|
|
1880
|
+
apiPricing: "$20/1k images",
|
|
1691
1881
|
creator: "xAI",
|
|
1692
|
-
model: "grok-imagine-image",
|
|
1693
1882
|
elo: 1213,
|
|
1694
|
-
apiPricing: "$20/1k images",
|
|
1695
1883
|
isCurrent: true,
|
|
1884
|
+
model: "grok-imagine-image",
|
|
1885
|
+
rank: 7,
|
|
1696
1886
|
routableModelId: "grok-image"
|
|
1697
1887
|
},
|
|
1698
1888
|
{
|
|
1699
|
-
|
|
1889
|
+
apiPricing: "$70/1k images",
|
|
1700
1890
|
creator: "xAI",
|
|
1701
|
-
model: "grok-imagine-image-pro",
|
|
1702
1891
|
elo: 1212,
|
|
1703
|
-
|
|
1704
|
-
|
|
1892
|
+
isCurrent: true,
|
|
1893
|
+
model: "grok-imagine-image-pro",
|
|
1894
|
+
rank: 8
|
|
1705
1895
|
},
|
|
1706
1896
|
{
|
|
1707
|
-
|
|
1897
|
+
apiPricing: "Unavailable",
|
|
1708
1898
|
creator: "KlingAI",
|
|
1709
|
-
model: "Kling Image 3.0 Omni",
|
|
1710
1899
|
elo: 1207,
|
|
1711
|
-
|
|
1712
|
-
|
|
1900
|
+
isCurrent: true,
|
|
1901
|
+
model: "Kling Image 3.0 Omni",
|
|
1902
|
+
rank: 9
|
|
1713
1903
|
},
|
|
1714
1904
|
{
|
|
1715
|
-
|
|
1905
|
+
apiPricing: "$140/1k images",
|
|
1716
1906
|
creator: "Black Forest Labs",
|
|
1717
|
-
model: "FLUX.2 [max]",
|
|
1718
1907
|
elo: 1206,
|
|
1719
|
-
apiPricing: "$140/1k images",
|
|
1720
1908
|
isCurrent: true,
|
|
1909
|
+
model: "FLUX.2 [max]",
|
|
1910
|
+
rank: 10,
|
|
1721
1911
|
routableModelId: "flux2-max"
|
|
1722
1912
|
},
|
|
1723
1913
|
{
|
|
1724
|
-
|
|
1914
|
+
apiPricing: "Unavailable",
|
|
1725
1915
|
creator: "Alibaba",
|
|
1726
|
-
model: "Wan 2.7 Pro",
|
|
1727
1916
|
elo: 1200,
|
|
1728
|
-
|
|
1729
|
-
|
|
1917
|
+
isCurrent: true,
|
|
1918
|
+
model: "Wan 2.7 Pro",
|
|
1919
|
+
rank: 11
|
|
1730
1920
|
},
|
|
1731
1921
|
{
|
|
1732
|
-
|
|
1922
|
+
apiPricing: "$28/1k images",
|
|
1733
1923
|
creator: "KlingAI",
|
|
1734
|
-
model: "Kling Image 3.0",
|
|
1735
1924
|
elo: 1196,
|
|
1736
|
-
|
|
1737
|
-
|
|
1925
|
+
isCurrent: true,
|
|
1926
|
+
model: "Kling Image 3.0",
|
|
1927
|
+
rank: 12
|
|
1738
1928
|
},
|
|
1739
1929
|
{
|
|
1740
|
-
|
|
1930
|
+
apiPricing: "$28/1k images",
|
|
1741
1931
|
creator: "KlingAI",
|
|
1742
|
-
model: "Kling Image O1",
|
|
1743
1932
|
elo: 1193,
|
|
1744
|
-
|
|
1745
|
-
|
|
1933
|
+
isCurrent: true,
|
|
1934
|
+
model: "Kling Image O1",
|
|
1935
|
+
rank: 13
|
|
1746
1936
|
},
|
|
1747
1937
|
{
|
|
1748
|
-
|
|
1938
|
+
apiPricing: "$30/1k images",
|
|
1749
1939
|
creator: "Alibaba",
|
|
1750
|
-
model: "Wan 2.6 Image",
|
|
1751
1940
|
elo: 1188,
|
|
1752
|
-
|
|
1753
|
-
|
|
1941
|
+
isCurrent: true,
|
|
1942
|
+
model: "Wan 2.6 Image",
|
|
1943
|
+
rank: 14
|
|
1754
1944
|
},
|
|
1755
1945
|
{
|
|
1756
|
-
|
|
1946
|
+
apiPricing: "$66/1k images",
|
|
1757
1947
|
creator: "Sourceful",
|
|
1758
|
-
model: "Riverflow 1",
|
|
1759
1948
|
elo: 1184,
|
|
1760
|
-
|
|
1761
|
-
|
|
1949
|
+
isCurrent: true,
|
|
1950
|
+
model: "Riverflow 1",
|
|
1951
|
+
rank: 15
|
|
1762
1952
|
},
|
|
1763
1953
|
{
|
|
1764
|
-
|
|
1954
|
+
apiPricing: "$30/1k images",
|
|
1765
1955
|
creator: "ByteDance Seed",
|
|
1766
|
-
model: "Seedream 4.0",
|
|
1767
1956
|
elo: 1184,
|
|
1768
|
-
apiPricing: "$30/1k images",
|
|
1769
1957
|
isCurrent: true,
|
|
1958
|
+
model: "Seedream 4.0",
|
|
1959
|
+
rank: 16,
|
|
1770
1960
|
routableModelId: "seedream4"
|
|
1771
1961
|
},
|
|
1772
1962
|
{
|
|
1773
|
-
|
|
1963
|
+
apiPricing: "$40/1k images",
|
|
1774
1964
|
creator: "ByteDance Seed",
|
|
1775
|
-
model: "Seedream 4.5",
|
|
1776
1965
|
elo: 1184,
|
|
1777
|
-
apiPricing: "$40/1k images",
|
|
1778
1966
|
isCurrent: true,
|
|
1967
|
+
model: "Seedream 4.5",
|
|
1968
|
+
rank: 17,
|
|
1779
1969
|
routableModelId: "seedream45"
|
|
1780
1970
|
},
|
|
1781
1971
|
{
|
|
1782
|
-
|
|
1972
|
+
apiPricing: "$26/1k images",
|
|
1783
1973
|
creator: "Alibaba",
|
|
1784
|
-
model: "Wan 2.7",
|
|
1785
1974
|
elo: 1181,
|
|
1786
|
-
|
|
1787
|
-
|
|
1975
|
+
isCurrent: true,
|
|
1976
|
+
model: "Wan 2.7",
|
|
1977
|
+
rank: 18
|
|
1788
1978
|
},
|
|
1789
1979
|
{
|
|
1790
|
-
|
|
1980
|
+
apiPricing: "$39/1k images",
|
|
1791
1981
|
creator: "Google",
|
|
1792
|
-
model: "Nano Banana (Gemini 2.5 Flash Image)",
|
|
1793
1982
|
elo: 1173,
|
|
1794
|
-
apiPricing: "$39/1k images",
|
|
1795
1983
|
isCurrent: true,
|
|
1984
|
+
model: "Nano Banana (Gemini 2.5 Flash Image)",
|
|
1985
|
+
rank: 19,
|
|
1796
1986
|
routableModelId: "gemini"
|
|
1797
1987
|
},
|
|
1798
1988
|
{
|
|
1799
|
-
|
|
1989
|
+
apiPricing: "$40/1k images",
|
|
1800
1990
|
creator: "Reve",
|
|
1801
|
-
model: "Reve V1 (December)",
|
|
1802
1991
|
elo: 1172,
|
|
1803
|
-
|
|
1804
|
-
|
|
1992
|
+
isCurrent: true,
|
|
1993
|
+
model: "Reve V1 (December)",
|
|
1994
|
+
rank: 20
|
|
1805
1995
|
}
|
|
1806
|
-
]
|
|
1996
|
+
],
|
|
1997
|
+
source: "https://artificialanalysis.ai/image/leaderboard/editing"
|
|
1807
1998
|
};
|
|
1808
1999
|
var VIDEO_TEXT_TO_VIDEO_TOP_15 = {
|
|
1809
2000
|
capturedAt: "2026-05-12",
|
|
1810
|
-
source: "https://artificialanalysis.ai/video/leaderboard/text-to-video",
|
|
1811
2001
|
entries: [
|
|
1812
2002
|
{
|
|
1813
|
-
|
|
2003
|
+
apiPricing: "$14.40/min",
|
|
1814
2004
|
creator: "Alibaba-ATH",
|
|
1815
|
-
model: "HappyHorse-1.0",
|
|
1816
2005
|
elo: 1354,
|
|
1817
|
-
|
|
2006
|
+
model: "HappyHorse-1.0",
|
|
2007
|
+
rank: 1
|
|
1818
2008
|
},
|
|
1819
2009
|
{
|
|
1820
|
-
|
|
2010
|
+
apiPricing: "No API available",
|
|
1821
2011
|
creator: "ByteDance Seed",
|
|
1822
|
-
model: "Dreamina Seedance 2.0 720p",
|
|
1823
2012
|
elo: 1273,
|
|
1824
|
-
|
|
2013
|
+
model: "Dreamina Seedance 2.0 720p",
|
|
2014
|
+
rank: 2
|
|
1825
2015
|
},
|
|
1826
2016
|
{
|
|
1827
|
-
|
|
2017
|
+
apiPricing: "$13.44/min",
|
|
1828
2018
|
creator: "KlingAI",
|
|
1829
|
-
model: "Kling 3.0 1080p (Pro)",
|
|
1830
2019
|
elo: 1249,
|
|
1831
|
-
|
|
2020
|
+
model: "Kling 3.0 1080p (Pro)",
|
|
2021
|
+
rank: 3
|
|
1832
2022
|
},
|
|
1833
2023
|
{
|
|
1834
|
-
|
|
2024
|
+
apiPricing: "$13.44/min",
|
|
1835
2025
|
creator: "KlingAI",
|
|
1836
|
-
model: "Kling 3.0 Omni 1080p (Pro)",
|
|
1837
2026
|
elo: 1233,
|
|
1838
|
-
|
|
2027
|
+
model: "Kling 3.0 Omni 1080p (Pro)",
|
|
2028
|
+
rank: 4
|
|
1839
2029
|
},
|
|
1840
2030
|
{
|
|
1841
|
-
|
|
2031
|
+
apiPricing: "$4.20/min",
|
|
1842
2032
|
creator: "xAI",
|
|
1843
|
-
model: "grok-imagine-video",
|
|
1844
2033
|
elo: 1233,
|
|
1845
|
-
|
|
2034
|
+
model: "grok-imagine-video",
|
|
2035
|
+
rank: 5
|
|
1846
2036
|
},
|
|
1847
2037
|
{
|
|
1848
|
-
|
|
2038
|
+
apiPricing: "$9.60/min",
|
|
1849
2039
|
creator: "Vidu",
|
|
1850
|
-
model: "Vidu Q3 Pro",
|
|
1851
2040
|
elo: 1225,
|
|
1852
|
-
|
|
2041
|
+
model: "Vidu Q3 Pro",
|
|
2042
|
+
rank: 6
|
|
1853
2043
|
},
|
|
1854
2044
|
{
|
|
1855
|
-
|
|
2045
|
+
apiPricing: "$3.00/min",
|
|
1856
2046
|
creator: "Video Rebirth",
|
|
1857
|
-
model: "Bach-1.0 Preview",
|
|
1858
2047
|
elo: 1224,
|
|
1859
|
-
|
|
2048
|
+
model: "Bach-1.0 Preview",
|
|
2049
|
+
rank: 7
|
|
1860
2050
|
},
|
|
1861
2051
|
{
|
|
1862
|
-
|
|
2052
|
+
apiPricing: "$10.08/min",
|
|
1863
2053
|
creator: "KlingAI",
|
|
1864
|
-
model: "Kling 3.0 Omni 720p (Standard)",
|
|
1865
2054
|
elo: 1224,
|
|
1866
|
-
|
|
2055
|
+
model: "Kling 3.0 Omni 720p (Standard)",
|
|
2056
|
+
rank: 8
|
|
1867
2057
|
},
|
|
1868
2058
|
{
|
|
1869
|
-
|
|
2059
|
+
apiPricing: "$5.40/min",
|
|
1870
2060
|
creator: "PixVerse",
|
|
1871
|
-
model: "PixVerse V6",
|
|
1872
2061
|
elo: 1222,
|
|
1873
|
-
|
|
2062
|
+
model: "PixVerse V6",
|
|
2063
|
+
rank: 9
|
|
1874
2064
|
},
|
|
1875
2065
|
{
|
|
1876
|
-
|
|
2066
|
+
apiPricing: "$9.00/min",
|
|
1877
2067
|
creator: "PixVerse",
|
|
1878
|
-
model: "PixVerse V5.6",
|
|
1879
2068
|
elo: 1221,
|
|
1880
|
-
|
|
2069
|
+
model: "PixVerse V5.6",
|
|
2070
|
+
rank: 10
|
|
1881
2071
|
},
|
|
1882
2072
|
{
|
|
1883
|
-
|
|
2073
|
+
apiPricing: "No API available",
|
|
1884
2074
|
creator: "Runway",
|
|
1885
|
-
model: "Runway Gen-4.5",
|
|
1886
2075
|
elo: 1220,
|
|
1887
|
-
|
|
2076
|
+
model: "Runway Gen-4.5",
|
|
2077
|
+
rank: 11
|
|
1888
2078
|
},
|
|
1889
2079
|
{
|
|
1890
|
-
|
|
2080
|
+
apiPricing: "$12.00/min",
|
|
1891
2081
|
creator: "Google",
|
|
1892
|
-
model: "Veo 3",
|
|
1893
2082
|
elo: 1218,
|
|
1894
|
-
|
|
2083
|
+
model: "Veo 3",
|
|
2084
|
+
rank: 12
|
|
1895
2085
|
},
|
|
1896
2086
|
{
|
|
1897
|
-
|
|
2087
|
+
apiPricing: "$10.08/min",
|
|
1898
2088
|
creator: "KlingAI",
|
|
1899
|
-
model: "Kling 3.0 720p (Standard)",
|
|
1900
2089
|
elo: 1215,
|
|
1901
|
-
|
|
2090
|
+
model: "Kling 3.0 720p (Standard)",
|
|
2091
|
+
rank: 13
|
|
1902
2092
|
},
|
|
1903
2093
|
{
|
|
1904
|
-
|
|
2094
|
+
apiPricing: "$3.00/min",
|
|
1905
2095
|
creator: "Google",
|
|
1906
|
-
model: "Veo 3.1 Lite",
|
|
1907
2096
|
elo: 1214,
|
|
1908
|
-
|
|
2097
|
+
model: "Veo 3.1 Lite",
|
|
2098
|
+
rank: 14
|
|
1909
2099
|
},
|
|
1910
2100
|
{
|
|
1911
|
-
|
|
2101
|
+
apiPricing: "$10.08/min",
|
|
1912
2102
|
creator: "KlingAI",
|
|
1913
|
-
model: "Kling O1 Pro (January)",
|
|
1914
2103
|
elo: 1209,
|
|
1915
|
-
|
|
2104
|
+
model: "Kling O1 Pro (January)",
|
|
2105
|
+
rank: 15
|
|
1916
2106
|
}
|
|
1917
|
-
]
|
|
2107
|
+
],
|
|
2108
|
+
source: "https://artificialanalysis.ai/video/leaderboard/text-to-video"
|
|
1918
2109
|
};
|
|
1919
2110
|
var VIDEO_IMAGE_TO_VIDEO_TOP_15 = {
|
|
1920
2111
|
capturedAt: "2026-05-12",
|
|
1921
|
-
source: "https://artificialanalysis.ai/video/leaderboard/image-to-video",
|
|
1922
2112
|
entries: [
|
|
1923
2113
|
{
|
|
1924
|
-
|
|
2114
|
+
apiPricing: "Coming soon",
|
|
1925
2115
|
creator: "Alibaba-ATH",
|
|
1926
|
-
model: "HappyHorse-1.0",
|
|
1927
2116
|
elo: 1395,
|
|
1928
|
-
|
|
2117
|
+
model: "HappyHorse-1.0",
|
|
2118
|
+
rank: 1
|
|
1929
2119
|
},
|
|
1930
2120
|
{
|
|
1931
|
-
|
|
2121
|
+
apiPricing: "No API available",
|
|
1932
2122
|
creator: "ByteDance Seed",
|
|
1933
|
-
model: "Dreamina Seedance 2.0 720p",
|
|
1934
2123
|
elo: 1348,
|
|
1935
|
-
|
|
2124
|
+
model: "Dreamina Seedance 2.0 720p",
|
|
2125
|
+
rank: 2
|
|
1936
2126
|
},
|
|
1937
2127
|
{
|
|
1938
|
-
|
|
2128
|
+
apiPricing: "$4.20/min",
|
|
1939
2129
|
creator: "xAI",
|
|
1940
|
-
model: "grok-imagine-video",
|
|
1941
2130
|
elo: 1326,
|
|
1942
|
-
|
|
2131
|
+
model: "grok-imagine-video",
|
|
2132
|
+
rank: 3
|
|
1943
2133
|
},
|
|
1944
2134
|
{
|
|
1945
|
-
|
|
2135
|
+
apiPricing: "$5.40/min",
|
|
1946
2136
|
creator: "PixVerse",
|
|
1947
|
-
model: "PixVerse V6",
|
|
1948
2137
|
elo: 1322,
|
|
1949
|
-
|
|
2138
|
+
model: "PixVerse V6",
|
|
2139
|
+
rank: 4
|
|
1950
2140
|
},
|
|
1951
2141
|
{
|
|
1952
|
-
|
|
2142
|
+
apiPricing: "$9.60/min",
|
|
1953
2143
|
creator: "Vidu",
|
|
1954
|
-
model: "Vidu Q3 Pro",
|
|
1955
2144
|
elo: 1287,
|
|
1956
|
-
|
|
2145
|
+
model: "Vidu Q3 Pro",
|
|
2146
|
+
rank: 5
|
|
1957
2147
|
},
|
|
1958
2148
|
{
|
|
1959
|
-
|
|
2149
|
+
apiPricing: "$4.20/min",
|
|
1960
2150
|
creator: "KlingAI",
|
|
1961
|
-
model: "Kling 2.5 Turbo 1080p",
|
|
1962
2151
|
elo: 1283,
|
|
1963
|
-
|
|
2152
|
+
model: "Kling 2.5 Turbo 1080p",
|
|
2153
|
+
rank: 6
|
|
1964
2154
|
},
|
|
1965
2155
|
{
|
|
1966
|
-
|
|
2156
|
+
apiPricing: "$13.44/min",
|
|
1967
2157
|
creator: "KlingAI",
|
|
1968
|
-
model: "Kling 3.0 1080p (Pro)",
|
|
1969
2158
|
elo: 1280,
|
|
1970
|
-
|
|
2159
|
+
model: "Kling 3.0 1080p (Pro)",
|
|
2160
|
+
rank: 7
|
|
1971
2161
|
},
|
|
1972
2162
|
{
|
|
1973
|
-
|
|
2163
|
+
apiPricing: "$9.00/min",
|
|
1974
2164
|
creator: "PixVerse",
|
|
1975
|
-
model: "PixVerse V5.6",
|
|
1976
2165
|
elo: 1279,
|
|
1977
|
-
|
|
2166
|
+
model: "PixVerse V5.6",
|
|
2167
|
+
rank: 8
|
|
1978
2168
|
},
|
|
1979
2169
|
{
|
|
1980
|
-
|
|
2170
|
+
apiPricing: "$13.44/min",
|
|
1981
2171
|
creator: "KlingAI",
|
|
1982
|
-
model: "Kling 3.0 Omni 1080p (Pro)",
|
|
1983
2172
|
elo: 1277,
|
|
1984
|
-
|
|
2173
|
+
model: "Kling 3.0 Omni 1080p (Pro)",
|
|
2174
|
+
rank: 9
|
|
1985
2175
|
},
|
|
1986
2176
|
{
|
|
1987
|
-
|
|
2177
|
+
apiPricing: "Coming soon",
|
|
1988
2178
|
creator: "KlingAI",
|
|
1989
|
-
model: "Kling 2.6 Standard (January)",
|
|
1990
2179
|
elo: 1271,
|
|
1991
|
-
|
|
2180
|
+
model: "Kling 2.6 Standard (January)",
|
|
2181
|
+
rank: 10
|
|
1992
2182
|
},
|
|
1993
2183
|
{
|
|
1994
|
-
|
|
2184
|
+
apiPricing: "$6.40/min",
|
|
1995
2185
|
creator: "PixVerse",
|
|
1996
|
-
model: "PixVerse V5.5",
|
|
1997
2186
|
elo: 1271,
|
|
1998
|
-
|
|
2187
|
+
model: "PixVerse V5.5",
|
|
2188
|
+
rank: 11
|
|
1999
2189
|
},
|
|
2000
2190
|
{
|
|
2001
|
-
|
|
2191
|
+
apiPricing: "$6.00/min",
|
|
2002
2192
|
creator: "Google",
|
|
2003
|
-
model: "Veo 3.1 Fast",
|
|
2004
2193
|
elo: 1268,
|
|
2005
|
-
|
|
2194
|
+
model: "Veo 3.1 Fast",
|
|
2195
|
+
rank: 12
|
|
2006
2196
|
},
|
|
2007
2197
|
{
|
|
2008
|
-
|
|
2198
|
+
apiPricing: "No API available",
|
|
2009
2199
|
creator: "Runway",
|
|
2010
|
-
model: "Runway Gen-4.5",
|
|
2011
2200
|
elo: 1263,
|
|
2012
|
-
|
|
2201
|
+
model: "Runway Gen-4.5",
|
|
2202
|
+
rank: 13
|
|
2013
2203
|
},
|
|
2014
2204
|
{
|
|
2015
|
-
|
|
2205
|
+
apiPricing: "$10.08/min",
|
|
2016
2206
|
creator: "KlingAI",
|
|
2017
|
-
model: "Kling 3.0 Omni 720p (Standard)",
|
|
2018
2207
|
elo: 1263,
|
|
2019
|
-
|
|
2208
|
+
model: "Kling 3.0 Omni 720p (Standard)",
|
|
2209
|
+
rank: 14
|
|
2020
2210
|
},
|
|
2021
2211
|
{
|
|
2022
|
-
|
|
2212
|
+
apiPricing: "$10.08/min",
|
|
2023
2213
|
creator: "KlingAI",
|
|
2024
|
-
model: "Kling 3.0 720p (Standard)",
|
|
2025
2214
|
elo: 1263,
|
|
2026
|
-
|
|
2215
|
+
model: "Kling 3.0 720p (Standard)",
|
|
2216
|
+
rank: 15
|
|
2027
2217
|
}
|
|
2028
|
-
]
|
|
2218
|
+
],
|
|
2219
|
+
source: "https://artificialanalysis.ai/video/leaderboard/image-to-video"
|
|
2029
2220
|
};
|
|
2030
2221
|
|
|
2031
2222
|
// src/server.ts
|
|
2032
2223
|
var import_neverthrow = require("neverthrow");
|
|
2033
2224
|
|
|
2225
|
+
// src/fal-parse.ts
|
|
2226
|
+
function isRecord(value) {
|
|
2227
|
+
return typeof value === "object" && value !== null;
|
|
2228
|
+
}
|
|
2229
|
+
function asString(value) {
|
|
2230
|
+
return typeof value === "string" ? value : void 0;
|
|
2231
|
+
}
|
|
2232
|
+
function asNumber(value) {
|
|
2233
|
+
return typeof value === "number" ? value : void 0;
|
|
2234
|
+
}
|
|
2235
|
+
function toMotifImage(value) {
|
|
2236
|
+
if (isRecord(value)) {
|
|
2237
|
+
return {
|
|
2238
|
+
content_type: asString(value.content_type),
|
|
2239
|
+
height: asNumber(value.height),
|
|
2240
|
+
url: asString(value.url) ?? "",
|
|
2241
|
+
width: asNumber(value.width)
|
|
2242
|
+
};
|
|
2243
|
+
}
|
|
2244
|
+
return { url: "" };
|
|
2245
|
+
}
|
|
2246
|
+
function parseImages(value) {
|
|
2247
|
+
if (!Array.isArray(value)) {
|
|
2248
|
+
return [];
|
|
2249
|
+
}
|
|
2250
|
+
return value.map((entry) => toMotifImage(entry));
|
|
2251
|
+
}
|
|
2252
|
+
function parseLogs(value) {
|
|
2253
|
+
if (!Array.isArray(value)) {
|
|
2254
|
+
return void 0;
|
|
2255
|
+
}
|
|
2256
|
+
const entries = [];
|
|
2257
|
+
for (const entry of value) {
|
|
2258
|
+
if (isRecord(entry)) {
|
|
2259
|
+
entries.push({
|
|
2260
|
+
message: asString(entry.message) ?? "",
|
|
2261
|
+
timestamp: asString(entry.timestamp) ?? ""
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
return entries;
|
|
2266
|
+
}
|
|
2267
|
+
function endpointFromQueueUrl(url, fallback) {
|
|
2268
|
+
if (url === void 0 || url === "") {
|
|
2269
|
+
return fallback;
|
|
2270
|
+
}
|
|
2271
|
+
try {
|
|
2272
|
+
const parsed = new URL(url);
|
|
2273
|
+
const match = /^\/(.+)\/requests\//.exec(parsed.pathname);
|
|
2274
|
+
return match?.[1] ?? fallback;
|
|
2275
|
+
} catch {
|
|
2276
|
+
return fallback;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
function parseQueueSubmission(data) {
|
|
2280
|
+
if (!isRecord(data)) {
|
|
2281
|
+
return { requestId: "" };
|
|
2282
|
+
}
|
|
2283
|
+
return {
|
|
2284
|
+
requestId: asString(data.request_id) ?? "",
|
|
2285
|
+
responseUrl: asString(data.response_url)
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
function toHeaderRecord(headers) {
|
|
2289
|
+
if (headers === void 0) {
|
|
2290
|
+
return {};
|
|
2291
|
+
}
|
|
2292
|
+
if (headers instanceof Headers) {
|
|
2293
|
+
const record = {};
|
|
2294
|
+
for (const [key, value] of headers.entries()) {
|
|
2295
|
+
record[key] = value;
|
|
2296
|
+
}
|
|
2297
|
+
return record;
|
|
2298
|
+
}
|
|
2299
|
+
if (Array.isArray(headers)) {
|
|
2300
|
+
const record = {};
|
|
2301
|
+
for (const [key, value] of headers) {
|
|
2302
|
+
record[key] = value;
|
|
2303
|
+
}
|
|
2304
|
+
return record;
|
|
2305
|
+
}
|
|
2306
|
+
return headers;
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2034
2309
|
// src/tools.ts
|
|
2035
2310
|
var FAL_EXPLORE_CHECKED_AT = "2026-05-12";
|
|
2036
2311
|
var FAL_TOOLS = {
|
|
2037
|
-
nsfw: {
|
|
2038
|
-
name: "NSFW Checker",
|
|
2039
|
-
endpoint: "fal-ai/x-ailab/nsfw",
|
|
2040
|
-
task: "vision moderation",
|
|
2041
|
-
category: "moderation",
|
|
2042
|
-
description: "Predict whether one or more images contain NSFW concepts.",
|
|
2043
|
-
inputKind: "images",
|
|
2044
|
-
inputField: "image_urls",
|
|
2045
|
-
outputKeys: ["has_nsfw_concepts"],
|
|
2046
|
-
pricing: "$0.001/image",
|
|
2047
|
-
sourceUrl: "https://fal.ai/models/fal-ai/x-ailab/nsfw"
|
|
2048
|
-
},
|
|
2049
|
-
"topaz-image": {
|
|
2050
|
-
name: "Topaz Image Upscale",
|
|
2051
|
-
endpoint: "fal-ai/topaz/upscale/image",
|
|
2052
|
-
task: "image enhancement",
|
|
2053
|
-
category: "upscale",
|
|
2054
|
-
description: "Professional Topaz image enhancement and upscaling.",
|
|
2055
|
-
inputKind: "image",
|
|
2056
|
-
inputField: "image_url",
|
|
2057
|
-
outputKeys: ["image"],
|
|
2058
|
-
pricing: "$0.08+ by output megapixels",
|
|
2059
|
-
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/image",
|
|
2060
|
-
defaultOptions: {
|
|
2061
|
-
model: "Standard V2",
|
|
2062
|
-
output_format: "jpeg",
|
|
2063
|
-
upscale_factor: 2
|
|
2064
|
-
}
|
|
2065
|
-
},
|
|
2066
|
-
"topaz-video": {
|
|
2067
|
-
name: "Topaz Video Upscale",
|
|
2068
|
-
endpoint: "fal-ai/topaz/upscale/video",
|
|
2069
|
-
task: "video enhancement",
|
|
2070
|
-
category: "upscale",
|
|
2071
|
-
description: "Professional Topaz video enhancement and upscaling.",
|
|
2072
|
-
inputKind: "video",
|
|
2073
|
-
inputField: "video_url",
|
|
2074
|
-
outputKeys: ["video"],
|
|
2075
|
-
pricing: "$0.01-$0.08/sec by output resolution",
|
|
2076
|
-
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/video",
|
|
2077
|
-
defaultOptions: {
|
|
2078
|
-
model: "Proteus",
|
|
2079
|
-
upscale_factor: 2
|
|
2080
|
-
}
|
|
2081
|
-
},
|
|
2082
|
-
"bria-rmbg": {
|
|
2083
|
-
name: "Bria RMBG 2.0",
|
|
2084
|
-
endpoint: "fal-ai/bria/background/remove",
|
|
2085
|
-
task: "image background removal",
|
|
2086
|
-
category: "background",
|
|
2087
|
-
description: "Commercial-safe background removal for images.",
|
|
2088
|
-
inputKind: "image",
|
|
2089
|
-
inputField: "image_url",
|
|
2090
|
-
outputKeys: ["image"],
|
|
2091
|
-
pricing: "$0.02/image",
|
|
2092
|
-
sourceUrl: "https://fal.ai/models/fal-ai/bria/background/remove"
|
|
2093
|
-
},
|
|
2094
2312
|
birefnet: {
|
|
2095
|
-
name: "BirefNet Background Removal",
|
|
2096
|
-
endpoint: "fal-ai/birefnet/v2",
|
|
2097
|
-
task: "image background removal",
|
|
2098
2313
|
category: "background",
|
|
2099
|
-
description: "High-resolution dichotomous image segmentation and background removal.",
|
|
2100
|
-
inputKind: "image",
|
|
2101
|
-
inputField: "image_url",
|
|
2102
|
-
outputKeys: ["image", "mask_image"],
|
|
2103
|
-
pricing: "$0/compute-second listed by fal",
|
|
2104
|
-
sourceUrl: "https://fal.ai/models/fal-ai/birefnet/v2",
|
|
2105
2314
|
defaultOptions: {
|
|
2106
2315
|
model: "General Use (Light)",
|
|
2107
2316
|
operating_resolution: "1024x1024",
|
|
2108
2317
|
output_format: "png",
|
|
2109
2318
|
refine_foreground: true
|
|
2110
|
-
}
|
|
2319
|
+
},
|
|
2320
|
+
description: "High-resolution dichotomous image segmentation and background removal.",
|
|
2321
|
+
endpoint: "fal-ai/birefnet/v2",
|
|
2322
|
+
inputField: "image_url",
|
|
2323
|
+
inputKind: "image",
|
|
2324
|
+
name: "BirefNet Background Removal",
|
|
2325
|
+
outputKeys: ["image", "mask_image"],
|
|
2326
|
+
pricing: "$0/compute-second listed by fal",
|
|
2327
|
+
sourceUrl: "https://fal.ai/models/fal-ai/birefnet/v2",
|
|
2328
|
+
task: "image background removal"
|
|
2111
2329
|
},
|
|
2112
|
-
|
|
2113
|
-
name: "Remove Background",
|
|
2114
|
-
endpoint: "fal-ai/imageutils/rembg",
|
|
2115
|
-
task: "image background removal",
|
|
2330
|
+
"bria-rmbg": {
|
|
2116
2331
|
category: "background",
|
|
2117
|
-
description: "
|
|
2118
|
-
|
|
2332
|
+
description: "Commercial-safe background removal for images.",
|
|
2333
|
+
endpoint: "fal-ai/bria/background/remove",
|
|
2119
2334
|
inputField: "image_url",
|
|
2335
|
+
inputKind: "image",
|
|
2336
|
+
name: "Bria RMBG 2.0",
|
|
2120
2337
|
outputKeys: ["image"],
|
|
2121
|
-
pricing: "$0/
|
|
2122
|
-
sourceUrl: "https://fal.ai/models/fal-ai/
|
|
2123
|
-
|
|
2124
|
-
crop_to_bbox: false
|
|
2125
|
-
}
|
|
2338
|
+
pricing: "$0.02/image",
|
|
2339
|
+
sourceUrl: "https://fal.ai/models/fal-ai/bria/background/remove",
|
|
2340
|
+
task: "image background removal"
|
|
2126
2341
|
},
|
|
2127
2342
|
"bria-video-rmbg": {
|
|
2128
|
-
name: "Bria Video Background Removal",
|
|
2129
|
-
endpoint: "bria/video/background-removal",
|
|
2130
|
-
task: "video background removal",
|
|
2131
2343
|
category: "background",
|
|
2344
|
+
defaultOptions: {
|
|
2345
|
+
background_color: "Black",
|
|
2346
|
+
output_container_and_codec: "webm_vp9",
|
|
2347
|
+
preserve_audio: true
|
|
2348
|
+
},
|
|
2132
2349
|
description: "Remove video backgrounds with configurable output container.",
|
|
2133
|
-
|
|
2350
|
+
endpoint: "bria/video/background-removal",
|
|
2134
2351
|
inputField: "video_url",
|
|
2352
|
+
inputKind: "video",
|
|
2353
|
+
name: "Bria Video Background Removal",
|
|
2135
2354
|
outputKeys: ["video"],
|
|
2136
2355
|
pricing: "$0.14/sec",
|
|
2137
2356
|
sourceUrl: "https://fal.ai/models/bria/video/background-removal",
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2357
|
+
task: "video background removal"
|
|
2358
|
+
},
|
|
2359
|
+
"depth-anything": {
|
|
2360
|
+
category: "preprocess",
|
|
2361
|
+
description: "Generate Depth Anything v2 depth maps from input images.",
|
|
2362
|
+
endpoint: "fal-ai/image-preprocessors/depth-anything/v2",
|
|
2363
|
+
inputField: "image_url",
|
|
2364
|
+
inputKind: "image",
|
|
2365
|
+
name: "Depth Anything v2 Preprocessor",
|
|
2366
|
+
outputKeys: ["image"],
|
|
2367
|
+
pricing: "$0/compute-second listed by fal",
|
|
2368
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/depth-anything/v2",
|
|
2369
|
+
task: "depth preprocessing"
|
|
2143
2370
|
},
|
|
2144
2371
|
lineart: {
|
|
2145
|
-
name: "Line Art Preprocessor",
|
|
2146
|
-
endpoint: "fal-ai/image-preprocessors/lineart",
|
|
2147
|
-
task: "image preprocessing",
|
|
2148
2372
|
category: "preprocess",
|
|
2373
|
+
defaultOptions: {
|
|
2374
|
+
coarse: false
|
|
2375
|
+
},
|
|
2149
2376
|
description: "Generate line art/control-style edges from an input image.",
|
|
2150
|
-
|
|
2377
|
+
endpoint: "fal-ai/image-preprocessors/lineart",
|
|
2151
2378
|
inputField: "image_url",
|
|
2379
|
+
inputKind: "image",
|
|
2380
|
+
name: "Line Art Preprocessor",
|
|
2152
2381
|
outputKeys: ["image"],
|
|
2153
2382
|
pricing: "$0/compute-second listed by fal",
|
|
2154
2383
|
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/lineart",
|
|
2155
|
-
|
|
2156
|
-
coarse: false
|
|
2157
|
-
}
|
|
2384
|
+
task: "image preprocessing"
|
|
2158
2385
|
},
|
|
2159
|
-
"
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2386
|
+
"marigold-depth": {
|
|
2387
|
+
category: "depth",
|
|
2388
|
+
defaultOptions: {
|
|
2389
|
+
ensemble_size: 10,
|
|
2390
|
+
num_inference_steps: 10
|
|
2391
|
+
},
|
|
2392
|
+
description: "Create depth maps using Marigold depth estimation.",
|
|
2393
|
+
endpoint: "fal-ai/imageutils/marigold-depth",
|
|
2166
2394
|
inputField: "image_url",
|
|
2395
|
+
inputKind: "image",
|
|
2396
|
+
name: "Marigold Depth Estimation",
|
|
2167
2397
|
outputKeys: ["image"],
|
|
2168
2398
|
pricing: "$0/compute-second listed by fal",
|
|
2169
|
-
sourceUrl: "https://fal.ai/models/fal-ai/
|
|
2399
|
+
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/marigold-depth",
|
|
2400
|
+
task: "depth map"
|
|
2170
2401
|
},
|
|
2171
2402
|
"midas-depth": {
|
|
2172
|
-
name: "MiDaS Depth Estimation",
|
|
2173
|
-
endpoint: "fal-ai/imageutils/depth",
|
|
2174
|
-
task: "depth map",
|
|
2175
2403
|
category: "depth",
|
|
2404
|
+
defaultOptions: {
|
|
2405
|
+
a: Math.PI * 2,
|
|
2406
|
+
bg_th: 0.1
|
|
2407
|
+
},
|
|
2176
2408
|
description: "Create MiDaS depth maps from input images.",
|
|
2177
|
-
|
|
2409
|
+
endpoint: "fal-ai/imageutils/depth",
|
|
2178
2410
|
inputField: "image_url",
|
|
2411
|
+
inputKind: "image",
|
|
2412
|
+
name: "MiDaS Depth Estimation",
|
|
2179
2413
|
outputKeys: ["image"],
|
|
2180
2414
|
pricing: "$0/compute-second listed by fal",
|
|
2181
2415
|
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/depth",
|
|
2182
|
-
|
|
2183
|
-
a: Math.PI * 2,
|
|
2184
|
-
bg_th: 0.1
|
|
2185
|
-
}
|
|
2416
|
+
task: "depth map"
|
|
2186
2417
|
},
|
|
2187
2418
|
"midas-preprocessor": {
|
|
2188
|
-
name: "MiDaS Preprocessor",
|
|
2189
|
-
endpoint: "fal-ai/image-preprocessors/midas",
|
|
2190
|
-
task: "depth and normal preprocessing",
|
|
2191
2419
|
category: "preprocess",
|
|
2192
2420
|
description: "Generate MiDaS depth and normal maps for image workflows.",
|
|
2193
|
-
|
|
2421
|
+
endpoint: "fal-ai/image-preprocessors/midas",
|
|
2194
2422
|
inputField: "image_url",
|
|
2423
|
+
inputKind: "image",
|
|
2424
|
+
name: "MiDaS Preprocessor",
|
|
2195
2425
|
outputKeys: ["depth_map", "normal_map"],
|
|
2196
2426
|
pricing: "$0/compute-second listed by fal",
|
|
2197
|
-
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/midas"
|
|
2427
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/midas",
|
|
2428
|
+
task: "depth and normal preprocessing"
|
|
2198
2429
|
},
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2430
|
+
nsfw: {
|
|
2431
|
+
category: "moderation",
|
|
2432
|
+
description: "Predict whether one or more images contain NSFW concepts.",
|
|
2433
|
+
endpoint: "fal-ai/x-ailab/nsfw",
|
|
2434
|
+
inputField: "image_urls",
|
|
2435
|
+
inputKind: "images",
|
|
2436
|
+
name: "NSFW Checker",
|
|
2437
|
+
outputKeys: ["has_nsfw_concepts"],
|
|
2438
|
+
pricing: "$0.001/image",
|
|
2439
|
+
sourceUrl: "https://fal.ai/models/fal-ai/x-ailab/nsfw",
|
|
2440
|
+
task: "vision moderation"
|
|
2441
|
+
},
|
|
2442
|
+
rembg: {
|
|
2443
|
+
category: "background",
|
|
2444
|
+
defaultOptions: {
|
|
2445
|
+
crop_to_bbox: false
|
|
2446
|
+
},
|
|
2447
|
+
description: "Generic image background removal utility.",
|
|
2448
|
+
endpoint: "fal-ai/imageutils/rembg",
|
|
2206
2449
|
inputField: "image_url",
|
|
2450
|
+
inputKind: "image",
|
|
2451
|
+
name: "Remove Background",
|
|
2207
2452
|
outputKeys: ["image"],
|
|
2208
2453
|
pricing: "$0/compute-second listed by fal",
|
|
2209
|
-
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/
|
|
2210
|
-
|
|
2211
|
-
ensemble_size: 10,
|
|
2212
|
-
num_inference_steps: 10
|
|
2213
|
-
}
|
|
2454
|
+
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/rembg",
|
|
2455
|
+
task: "image background removal"
|
|
2214
2456
|
},
|
|
2215
|
-
"
|
|
2216
|
-
name: "Depth Anything v2 Preprocessor",
|
|
2217
|
-
endpoint: "fal-ai/image-preprocessors/depth-anything/v2",
|
|
2218
|
-
task: "depth preprocessing",
|
|
2457
|
+
"sam-preprocessor": {
|
|
2219
2458
|
category: "preprocess",
|
|
2220
|
-
description: "Generate
|
|
2221
|
-
|
|
2459
|
+
description: "Generate a SAM segmentation map for ControlNet-style workflows.",
|
|
2460
|
+
endpoint: "fal-ai/image-preprocessors/sam",
|
|
2222
2461
|
inputField: "image_url",
|
|
2462
|
+
inputKind: "image",
|
|
2463
|
+
name: "SAM Preprocessor",
|
|
2223
2464
|
outputKeys: ["image"],
|
|
2224
2465
|
pricing: "$0/compute-second listed by fal",
|
|
2225
|
-
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/
|
|
2466
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/sam",
|
|
2467
|
+
task: "segmentation preprocessing"
|
|
2468
|
+
},
|
|
2469
|
+
"sam2-auto": {
|
|
2470
|
+
category: "segmentation",
|
|
2471
|
+
defaultOptions: {
|
|
2472
|
+
min_mask_region_area: 100,
|
|
2473
|
+
output_format: "png",
|
|
2474
|
+
points_per_side: 32,
|
|
2475
|
+
pred_iou_thresh: 0.88,
|
|
2476
|
+
stability_score_thresh: 0.95
|
|
2477
|
+
},
|
|
2478
|
+
description: "Automatically segment an image into combined and individual masks.",
|
|
2479
|
+
endpoint: "fal-ai/sam2/auto-segment",
|
|
2480
|
+
inputField: "image_url",
|
|
2481
|
+
inputKind: "image",
|
|
2482
|
+
name: "SAM 2 Auto Segment",
|
|
2483
|
+
outputKeys: ["combined_mask", "individual_masks"],
|
|
2484
|
+
pricing: "$0/compute-second listed by fal",
|
|
2485
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam2/auto-segment",
|
|
2486
|
+
task: "automatic image segmentation"
|
|
2487
|
+
},
|
|
2488
|
+
"sam3-1-image": {
|
|
2489
|
+
category: "segmentation",
|
|
2490
|
+
defaultOptions: {
|
|
2491
|
+
apply_mask: true,
|
|
2492
|
+
max_masks: 3,
|
|
2493
|
+
output_format: "png"
|
|
2494
|
+
},
|
|
2495
|
+
description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.",
|
|
2496
|
+
endpoint: "fal-ai/sam-3-1/image",
|
|
2497
|
+
inputField: "image_url",
|
|
2498
|
+
inputKind: "image",
|
|
2499
|
+
name: "SAM 3.1 Image",
|
|
2500
|
+
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2501
|
+
pricing: "$0.005/request",
|
|
2502
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image",
|
|
2503
|
+
task: "promptable image segmentation"
|
|
2504
|
+
},
|
|
2505
|
+
"sam3-1-video": {
|
|
2506
|
+
category: "segmentation",
|
|
2507
|
+
defaultOptions: {
|
|
2508
|
+
apply_mask: true,
|
|
2509
|
+
prompt: "person"
|
|
2510
|
+
},
|
|
2511
|
+
description: "SAM 3.1 video segmentation with Object Multiplex tracking for multiple objects.",
|
|
2512
|
+
endpoint: "fal-ai/sam-3-1/video",
|
|
2513
|
+
inputField: "video_url",
|
|
2514
|
+
inputKind: "video",
|
|
2515
|
+
name: "SAM 3.1 Video",
|
|
2516
|
+
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2517
|
+
pricing: "fal pricing varies by frame count",
|
|
2518
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/video",
|
|
2519
|
+
task: "multi-object video segmentation"
|
|
2226
2520
|
},
|
|
2227
|
-
"
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
description: "Automatically segment an image into combined and individual masks.",
|
|
2521
|
+
"sam3-3d-align": {
|
|
2522
|
+
category: "3d",
|
|
2523
|
+
description: "Align SAM 3D objects and bodies into a shared scene.",
|
|
2524
|
+
endpoint: "fal-ai/sam-3/3d-align",
|
|
2525
|
+
inputField: "image_url",
|
|
2233
2526
|
inputKind: "image",
|
|
2527
|
+
name: "SAM 3D Align",
|
|
2528
|
+
outputKeys: ["scene_glb", "metadata", "artifacts_zip"],
|
|
2529
|
+
pricing: "fal pricing varies by scene",
|
|
2530
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-align",
|
|
2531
|
+
task: "3D scene alignment"
|
|
2532
|
+
},
|
|
2533
|
+
"sam3-3d-body": {
|
|
2534
|
+
category: "3d",
|
|
2535
|
+
defaultOptions: {
|
|
2536
|
+
export_meshes: true,
|
|
2537
|
+
include_3d_keypoints: true,
|
|
2538
|
+
include_mhr_params: true
|
|
2539
|
+
},
|
|
2540
|
+
description: "Reconstruct human body meshes and keypoints from a single image.",
|
|
2541
|
+
endpoint: "fal-ai/sam-3/3d-body",
|
|
2234
2542
|
inputField: "image_url",
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2543
|
+
inputKind: "image",
|
|
2544
|
+
name: "SAM 3D Body",
|
|
2545
|
+
outputKeys: ["model_glb", "visualization", "meshes", "metadata"],
|
|
2546
|
+
pricing: "$0.015/inference",
|
|
2547
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-body",
|
|
2548
|
+
task: "single-image 3D body reconstruction"
|
|
2549
|
+
},
|
|
2550
|
+
"sam3-3d-objects": {
|
|
2551
|
+
category: "3d",
|
|
2238
2552
|
defaultOptions: {
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2553
|
+
prompt: "car"
|
|
2554
|
+
},
|
|
2555
|
+
description: "Reconstruct one or more 3D objects from an image and prompts.",
|
|
2556
|
+
endpoint: "fal-ai/sam-3/3d-objects",
|
|
2557
|
+
inputField: "image_url",
|
|
2558
|
+
inputKind: "image",
|
|
2559
|
+
name: "SAM 3D Objects",
|
|
2560
|
+
outputKeys: [
|
|
2561
|
+
"gaussian_splat",
|
|
2562
|
+
"model_glb",
|
|
2563
|
+
"metadata",
|
|
2564
|
+
"individual_splats",
|
|
2565
|
+
"individual_glbs",
|
|
2566
|
+
"artifacts_zip"
|
|
2567
|
+
],
|
|
2568
|
+
pricing: "$0.02/generation",
|
|
2569
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-objects",
|
|
2570
|
+
task: "single-image 3D object reconstruction"
|
|
2245
2571
|
},
|
|
2246
2572
|
"sam3-image": {
|
|
2247
|
-
name: "SAM 3 Image",
|
|
2248
|
-
endpoint: "fal-ai/sam-3/image",
|
|
2249
|
-
task: "promptable image segmentation",
|
|
2250
2573
|
category: "segmentation",
|
|
2251
|
-
description: "Segment image objects with text, point, or box prompts.",
|
|
2252
|
-
inputKind: "image",
|
|
2253
|
-
inputField: "image_url",
|
|
2254
|
-
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2255
|
-
pricing: "$0.005/request",
|
|
2256
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/image",
|
|
2257
2574
|
defaultOptions: {
|
|
2258
2575
|
apply_mask: true,
|
|
2259
2576
|
max_masks: 3,
|
|
2260
2577
|
output_format: "png"
|
|
2261
|
-
}
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
name: "SAM 3.1 Image",
|
|
2265
|
-
endpoint: "fal-ai/sam-3-1/image",
|
|
2266
|
-
task: "promptable image segmentation",
|
|
2267
|
-
category: "segmentation",
|
|
2268
|
-
description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.",
|
|
2269
|
-
inputKind: "image",
|
|
2578
|
+
},
|
|
2579
|
+
description: "Segment image objects with text, point, or box prompts.",
|
|
2580
|
+
endpoint: "fal-ai/sam-3/image",
|
|
2270
2581
|
inputField: "image_url",
|
|
2582
|
+
inputKind: "image",
|
|
2583
|
+
name: "SAM 3 Image",
|
|
2271
2584
|
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2272
2585
|
pricing: "$0.005/request",
|
|
2273
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3
|
|
2274
|
-
|
|
2275
|
-
apply_mask: true,
|
|
2276
|
-
max_masks: 3,
|
|
2277
|
-
output_format: "png"
|
|
2278
|
-
}
|
|
2586
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/image",
|
|
2587
|
+
task: "promptable image segmentation"
|
|
2279
2588
|
},
|
|
2280
2589
|
"sam3-image-rle": {
|
|
2281
|
-
name: "SAM 3 Image RLE",
|
|
2282
|
-
endpoint: "fal-ai/sam-3/image-rle",
|
|
2283
|
-
task: "promptable image segmentation to RLE",
|
|
2284
2590
|
category: "segmentation",
|
|
2591
|
+
defaultOptions: {
|
|
2592
|
+
apply_mask: true,
|
|
2593
|
+
max_masks: 3
|
|
2594
|
+
},
|
|
2285
2595
|
description: "Segment image objects and return run-length encoded masks.",
|
|
2286
|
-
|
|
2596
|
+
endpoint: "fal-ai/sam-3/image-rle",
|
|
2287
2597
|
inputField: "image_url",
|
|
2598
|
+
inputKind: "image",
|
|
2599
|
+
name: "SAM 3 Image RLE",
|
|
2288
2600
|
outputKeys: ["rle_masks", "metadata", "scores", "boxes"],
|
|
2289
2601
|
pricing: "$0.005/request",
|
|
2290
2602
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/image-rle",
|
|
2291
|
-
|
|
2292
|
-
apply_mask: true,
|
|
2293
|
-
max_masks: 3
|
|
2294
|
-
}
|
|
2603
|
+
task: "promptable image segmentation to RLE"
|
|
2295
2604
|
},
|
|
2296
2605
|
"sam3-video": {
|
|
2297
|
-
name: "SAM 3 Video",
|
|
2298
|
-
endpoint: "fal-ai/sam-3/video",
|
|
2299
|
-
task: "promptable video segmentation",
|
|
2300
2606
|
category: "segmentation",
|
|
2301
|
-
description: "Segment and track prompted objects across video frames.",
|
|
2302
|
-
inputKind: "video",
|
|
2303
|
-
inputField: "video_url",
|
|
2304
|
-
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2305
|
-
pricing: "$0.005/16 frames",
|
|
2306
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/video",
|
|
2307
2607
|
defaultOptions: {
|
|
2308
2608
|
apply_mask: true,
|
|
2309
2609
|
detection_threshold: 0.5,
|
|
2310
2610
|
prompt: "person",
|
|
2311
2611
|
video_output_type: "X264 (.mp4)"
|
|
2312
|
-
}
|
|
2612
|
+
},
|
|
2613
|
+
description: "Segment and track prompted objects across video frames.",
|
|
2614
|
+
endpoint: "fal-ai/sam-3/video",
|
|
2615
|
+
inputField: "video_url",
|
|
2616
|
+
inputKind: "video",
|
|
2617
|
+
name: "SAM 3 Video",
|
|
2618
|
+
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2619
|
+
pricing: "$0.005/16 frames",
|
|
2620
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/video",
|
|
2621
|
+
task: "promptable video segmentation"
|
|
2313
2622
|
},
|
|
2314
2623
|
"sam3-video-rle": {
|
|
2315
|
-
name: "SAM 3 Video RLE",
|
|
2316
|
-
endpoint: "fal-ai/sam-3/video-rle",
|
|
2317
|
-
task: "promptable video segmentation to RLE",
|
|
2318
2624
|
category: "segmentation",
|
|
2625
|
+
defaultOptions: {
|
|
2626
|
+
apply_mask: true,
|
|
2627
|
+
detection_threshold: 0.5,
|
|
2628
|
+
prompt: "person"
|
|
2629
|
+
},
|
|
2319
2630
|
description: "Track prompted video objects and return RLE mask data.",
|
|
2320
|
-
|
|
2631
|
+
endpoint: "fal-ai/sam-3/video-rle",
|
|
2321
2632
|
inputField: "video_url",
|
|
2633
|
+
inputKind: "video",
|
|
2634
|
+
name: "SAM 3 Video RLE",
|
|
2322
2635
|
outputKeys: ["rle_masks", "metadata"],
|
|
2323
2636
|
pricing: "$0.005/16 frames",
|
|
2324
2637
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/video-rle",
|
|
2325
|
-
|
|
2326
|
-
apply_mask: true,
|
|
2327
|
-
detection_threshold: 0.5,
|
|
2328
|
-
prompt: "person"
|
|
2329
|
-
}
|
|
2638
|
+
task: "promptable video segmentation to RLE"
|
|
2330
2639
|
},
|
|
2331
|
-
"
|
|
2332
|
-
|
|
2333
|
-
endpoint: "fal-ai/sam-3-1/video",
|
|
2334
|
-
task: "multi-object video segmentation",
|
|
2335
|
-
category: "segmentation",
|
|
2336
|
-
description: "SAM 3.1 video segmentation with Object Multiplex tracking for multiple objects.",
|
|
2337
|
-
inputKind: "video",
|
|
2338
|
-
inputField: "video_url",
|
|
2339
|
-
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2340
|
-
pricing: "fal pricing varies by frame count",
|
|
2341
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/video",
|
|
2640
|
+
"topaz-image": {
|
|
2641
|
+
category: "upscale",
|
|
2342
2642
|
defaultOptions: {
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
endpoint: "fal-ai/sam-3/3d-objects",
|
|
2350
|
-
task: "single-image 3D object reconstruction",
|
|
2351
|
-
category: "3d",
|
|
2352
|
-
description: "Reconstruct one or more 3D objects from an image and prompts.",
|
|
2353
|
-
inputKind: "image",
|
|
2643
|
+
model: "Standard V2",
|
|
2644
|
+
output_format: "jpeg",
|
|
2645
|
+
upscale_factor: 2
|
|
2646
|
+
},
|
|
2647
|
+
description: "Professional Topaz image enhancement and upscaling.",
|
|
2648
|
+
endpoint: "fal-ai/topaz/upscale/image",
|
|
2354
2649
|
inputField: "image_url",
|
|
2355
|
-
outputKeys: [
|
|
2356
|
-
"gaussian_splat",
|
|
2357
|
-
"model_glb",
|
|
2358
|
-
"metadata",
|
|
2359
|
-
"individual_splats",
|
|
2360
|
-
"individual_glbs",
|
|
2361
|
-
"artifacts_zip"
|
|
2362
|
-
],
|
|
2363
|
-
pricing: "$0.02/generation",
|
|
2364
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-objects",
|
|
2365
|
-
defaultOptions: {
|
|
2366
|
-
prompt: "car"
|
|
2367
|
-
}
|
|
2368
|
-
},
|
|
2369
|
-
"sam3-3d-body": {
|
|
2370
|
-
name: "SAM 3D Body",
|
|
2371
|
-
endpoint: "fal-ai/sam-3/3d-body",
|
|
2372
|
-
task: "single-image 3D body reconstruction",
|
|
2373
|
-
category: "3d",
|
|
2374
|
-
description: "Reconstruct human body meshes and keypoints from a single image.",
|
|
2375
2650
|
inputKind: "image",
|
|
2376
|
-
|
|
2377
|
-
outputKeys: ["
|
|
2378
|
-
pricing: "$0.
|
|
2379
|
-
sourceUrl: "https://fal.ai/models/fal-ai/
|
|
2380
|
-
|
|
2381
|
-
export_meshes: true,
|
|
2382
|
-
include_3d_keypoints: true,
|
|
2383
|
-
include_mhr_params: true
|
|
2384
|
-
}
|
|
2651
|
+
name: "Topaz Image Upscale",
|
|
2652
|
+
outputKeys: ["image"],
|
|
2653
|
+
pricing: "$0.08+ by output megapixels",
|
|
2654
|
+
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/image",
|
|
2655
|
+
task: "image enhancement"
|
|
2385
2656
|
},
|
|
2386
|
-
"
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2657
|
+
"topaz-video": {
|
|
2658
|
+
category: "upscale",
|
|
2659
|
+
defaultOptions: {
|
|
2660
|
+
model: "Proteus",
|
|
2661
|
+
upscale_factor: 2
|
|
2662
|
+
},
|
|
2663
|
+
description: "Professional Topaz video enhancement and upscaling.",
|
|
2664
|
+
endpoint: "fal-ai/topaz/upscale/video",
|
|
2665
|
+
inputField: "video_url",
|
|
2666
|
+
inputKind: "video",
|
|
2667
|
+
name: "Topaz Video Upscale",
|
|
2668
|
+
outputKeys: ["video"],
|
|
2669
|
+
pricing: "$0.01-$0.08/sec by output resolution",
|
|
2670
|
+
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/video",
|
|
2671
|
+
task: "video enhancement"
|
|
2397
2672
|
}
|
|
2398
2673
|
};
|
|
2399
2674
|
var FAL_TOOLS_CHECKED_AT = FAL_EXPLORE_CHECKED_AT;
|
|
2400
|
-
var FAL_TOOL_IDS = Object.keys(
|
|
2675
|
+
var FAL_TOOL_IDS = Object.keys(
|
|
2676
|
+
FAL_TOOLS
|
|
2677
|
+
);
|
|
2401
2678
|
function isFalToolId(tool) {
|
|
2402
2679
|
return Object.hasOwn(FAL_TOOLS, tool);
|
|
2403
2680
|
}
|
|
@@ -2406,7 +2683,7 @@ function buildFalToolRequest(options) {
|
|
|
2406
2683
|
throw new Error(`Unknown fal tool: ${options.tool}`);
|
|
2407
2684
|
}
|
|
2408
2685
|
const tool = FAL_TOOLS[options.tool];
|
|
2409
|
-
const values = options.inputs ?? (options.input ? [options.input] : []);
|
|
2686
|
+
const values = options.inputs ?? (options.input !== void 0 && options.input !== "" ? [options.input] : []);
|
|
2410
2687
|
if (values.length === 0) {
|
|
2411
2688
|
throw new Error(`${options.tool} requires input media`);
|
|
2412
2689
|
}
|
|
@@ -2417,7 +2694,7 @@ function buildFalToolRequest(options) {
|
|
|
2417
2694
|
...options.options,
|
|
2418
2695
|
[tool.inputField]: mediaValue
|
|
2419
2696
|
};
|
|
2420
|
-
return { endpoint: tool.endpoint,
|
|
2697
|
+
return { body, endpoint: tool.endpoint, tool };
|
|
2421
2698
|
}
|
|
2422
2699
|
|
|
2423
2700
|
// src/server.ts
|
|
@@ -2425,16 +2702,6 @@ var FAL_BASE_URL = "https://fal.run";
|
|
|
2425
2702
|
var FAL_QUEUE_URL = "https://queue.fal.run";
|
|
2426
2703
|
var FAL_API_URL = "https://api.fal.ai";
|
|
2427
2704
|
var FAL_REST_URL = "https://rest.alpha.fal.ai";
|
|
2428
|
-
function endpointFromQueueUrl(url, fallback) {
|
|
2429
|
-
if (!url) return fallback;
|
|
2430
|
-
try {
|
|
2431
|
-
const parsed = new URL(url);
|
|
2432
|
-
const match = parsed.pathname.match(/^\/(.+)\/requests\//);
|
|
2433
|
-
return match?.[1] ?? fallback;
|
|
2434
|
-
} catch {
|
|
2435
|
-
return fallback;
|
|
2436
|
-
}
|
|
2437
|
-
}
|
|
2438
2705
|
var MotifServer = class {
|
|
2439
2706
|
apiKey;
|
|
2440
2707
|
timeout;
|
|
@@ -2457,8 +2724,8 @@ var MotifServer = class {
|
|
|
2457
2724
|
/** Generate images synchronously (blocks until fal.ai returns). */
|
|
2458
2725
|
async generate(options) {
|
|
2459
2726
|
const config = MODELS[options.model];
|
|
2460
|
-
if (config?.useQueue) {
|
|
2461
|
-
return this.generateQueued(options);
|
|
2727
|
+
if (config?.useQueue === true) {
|
|
2728
|
+
return await this.generateQueued(options);
|
|
2462
2729
|
}
|
|
2463
2730
|
let built;
|
|
2464
2731
|
try {
|
|
@@ -2468,9 +2735,9 @@ var MotifServer = class {
|
|
|
2468
2735
|
}
|
|
2469
2736
|
const { endpoint, body } = built;
|
|
2470
2737
|
const response = await this.request(`${FAL_BASE_URL}/${endpoint}`, {
|
|
2471
|
-
method: "POST",
|
|
2472
2738
|
body: JSON.stringify(body),
|
|
2473
|
-
headers: this.ephemeralHeaders(options)
|
|
2739
|
+
headers: this.ephemeralHeaders(options),
|
|
2740
|
+
method: "POST"
|
|
2474
2741
|
});
|
|
2475
2742
|
if (response.isErr()) {
|
|
2476
2743
|
return (0, import_neverthrow.err)(response.error);
|
|
@@ -2494,14 +2761,16 @@ var MotifServer = class {
|
|
|
2494
2761
|
return (0, import_neverthrow.err)(status.error);
|
|
2495
2762
|
}
|
|
2496
2763
|
if (status.value.status === "completed") {
|
|
2497
|
-
return this.getJobResult(job.value.endpoint, job.value.requestId);
|
|
2764
|
+
return await this.getJobResult(job.value.endpoint, job.value.requestId);
|
|
2498
2765
|
}
|
|
2499
2766
|
if (status.value.status === "failed") {
|
|
2500
2767
|
return (0, import_neverthrow.err)(
|
|
2501
2768
|
new MotifError(status.value.error ?? "Queued generation failed", 0)
|
|
2502
2769
|
);
|
|
2503
2770
|
}
|
|
2504
|
-
await new Promise((resolve) =>
|
|
2771
|
+
await new Promise((resolve) => {
|
|
2772
|
+
setTimeout(resolve, pollIntervalMs);
|
|
2773
|
+
});
|
|
2505
2774
|
}
|
|
2506
2775
|
return (0, import_neverthrow.err)(new MotifError("Queued generation timed out", 0));
|
|
2507
2776
|
}
|
|
@@ -2516,22 +2785,23 @@ var MotifServer = class {
|
|
|
2516
2785
|
}
|
|
2517
2786
|
const { endpoint, body } = built;
|
|
2518
2787
|
const response = await this.request(`${FAL_QUEUE_URL}/${endpoint}`, {
|
|
2519
|
-
method: "POST",
|
|
2520
2788
|
body: JSON.stringify(body),
|
|
2521
|
-
headers: this.ephemeralHeaders(options)
|
|
2789
|
+
headers: this.ephemeralHeaders(options),
|
|
2790
|
+
method: "POST"
|
|
2522
2791
|
});
|
|
2523
2792
|
if (response.isErr()) {
|
|
2524
2793
|
return (0, import_neverthrow.err)(response.error);
|
|
2525
2794
|
}
|
|
2526
2795
|
const data = await response.value.json();
|
|
2796
|
+
const submission = parseQueueSubmission(data);
|
|
2527
2797
|
return (0, import_neverthrow.ok)({
|
|
2528
|
-
|
|
2529
|
-
endpoint: endpointFromQueueUrl(data.response_url, endpoint),
|
|
2798
|
+
endpoint: endpointFromQueueUrl(submission.responseUrl, endpoint),
|
|
2530
2799
|
estimatedCost: estimateCost(
|
|
2531
2800
|
options.model,
|
|
2532
2801
|
options.resolution,
|
|
2533
2802
|
options.numImages
|
|
2534
|
-
)
|
|
2803
|
+
),
|
|
2804
|
+
requestId: submission.requestId
|
|
2535
2805
|
});
|
|
2536
2806
|
}
|
|
2537
2807
|
/** Check the status of a queued generation. */
|
|
@@ -2542,23 +2812,25 @@ var MotifServer = class {
|
|
|
2542
2812
|
return (0, import_neverthrow.err)(response.error);
|
|
2543
2813
|
}
|
|
2544
2814
|
const data = await response.value.json();
|
|
2815
|
+
const record = isRecord(data) ? data : {};
|
|
2816
|
+
const rawStatus = asString(record.status);
|
|
2545
2817
|
let status;
|
|
2546
|
-
if (
|
|
2818
|
+
if (rawStatus === "IN_QUEUE") {
|
|
2547
2819
|
status = "queued";
|
|
2548
|
-
} else if (
|
|
2820
|
+
} else if (rawStatus === "IN_PROGRESS") {
|
|
2549
2821
|
status = "processing";
|
|
2550
|
-
} else if (
|
|
2822
|
+
} else if (rawStatus === "COMPLETED") {
|
|
2551
2823
|
status = "completed";
|
|
2552
|
-
} else if (
|
|
2824
|
+
} else if (rawStatus === "FAILED" || rawStatus === "ERROR" || rawStatus === "CANCELED") {
|
|
2553
2825
|
status = "failed";
|
|
2554
2826
|
} else {
|
|
2555
|
-
return (0, import_neverthrow.err)(new MotifError(`Unknown job status: ${
|
|
2827
|
+
return (0, import_neverthrow.err)(new MotifError(`Unknown job status: ${rawStatus}`, 0));
|
|
2556
2828
|
}
|
|
2557
2829
|
return (0, import_neverthrow.ok)({
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
queuePosition:
|
|
2561
|
-
|
|
2830
|
+
error: asString(record.error) ?? asString(record.detail),
|
|
2831
|
+
logs: parseLogs(record.logs),
|
|
2832
|
+
queuePosition: asNumber(record.queue_position),
|
|
2833
|
+
status
|
|
2562
2834
|
});
|
|
2563
2835
|
}
|
|
2564
2836
|
/** Fetch the completed result from the queue. */
|
|
@@ -2591,21 +2863,38 @@ var MotifServer = class {
|
|
|
2591
2863
|
}
|
|
2592
2864
|
const body = { image_url: imageUrl };
|
|
2593
2865
|
if (model === "crystal") {
|
|
2594
|
-
if (scaleFactor !== void 0)
|
|
2595
|
-
|
|
2866
|
+
if (scaleFactor !== void 0) {
|
|
2867
|
+
body.scale_factor = scaleFactor;
|
|
2868
|
+
}
|
|
2869
|
+
if (creativity !== void 0) {
|
|
2870
|
+
body.creativity = creativity;
|
|
2871
|
+
}
|
|
2596
2872
|
} else {
|
|
2597
|
-
if (scaleFactor !== void 0)
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
if (
|
|
2601
|
-
|
|
2602
|
-
|
|
2873
|
+
if (scaleFactor !== void 0) {
|
|
2874
|
+
body.upscale_factor = scaleFactor;
|
|
2875
|
+
}
|
|
2876
|
+
if (creativity !== void 0) {
|
|
2877
|
+
body.creativity = creativity;
|
|
2878
|
+
}
|
|
2879
|
+
if (resemblance !== void 0) {
|
|
2880
|
+
body.resemblance = resemblance;
|
|
2881
|
+
}
|
|
2882
|
+
if (upscalePrompt !== void 0 && upscalePrompt !== "") {
|
|
2883
|
+
body.prompt = upscalePrompt;
|
|
2884
|
+
}
|
|
2885
|
+
if (negativePrompt !== void 0 && negativePrompt !== "") {
|
|
2886
|
+
body.negative_prompt = negativePrompt;
|
|
2887
|
+
}
|
|
2888
|
+
if (numInferenceSteps !== void 0) {
|
|
2603
2889
|
body.num_inference_steps = numInferenceSteps;
|
|
2604
|
-
|
|
2890
|
+
}
|
|
2891
|
+
if (guidanceScale !== void 0) {
|
|
2892
|
+
body.guidance_scale = guidanceScale;
|
|
2893
|
+
}
|
|
2605
2894
|
}
|
|
2606
2895
|
const response = await this.request(`${FAL_BASE_URL}/${config.endpoint}`, {
|
|
2607
|
-
|
|
2608
|
-
|
|
2896
|
+
body: JSON.stringify(body),
|
|
2897
|
+
method: "POST"
|
|
2609
2898
|
});
|
|
2610
2899
|
if (response.isErr()) {
|
|
2611
2900
|
return (0, import_neverthrow.err)(response.error);
|
|
@@ -2632,17 +2921,25 @@ var MotifServer = class {
|
|
|
2632
2921
|
}
|
|
2633
2922
|
const rbBody = { image_url: imageUrl };
|
|
2634
2923
|
if (model === "rmbg") {
|
|
2635
|
-
if (variant)
|
|
2636
|
-
|
|
2924
|
+
if (variant) {
|
|
2925
|
+
rbBody.model = variant;
|
|
2926
|
+
}
|
|
2927
|
+
if (operatingResolution) {
|
|
2637
2928
|
rbBody.operating_resolution = operatingResolution;
|
|
2638
|
-
|
|
2639
|
-
if (
|
|
2929
|
+
}
|
|
2930
|
+
if (outputFormat) {
|
|
2931
|
+
rbBody.output_format = outputFormat;
|
|
2932
|
+
}
|
|
2933
|
+
if (refineForeground !== void 0) {
|
|
2640
2934
|
rbBody.refine_foreground = refineForeground;
|
|
2641
|
-
|
|
2935
|
+
}
|
|
2936
|
+
if (outputMask !== void 0) {
|
|
2937
|
+
rbBody.output_mask = outputMask;
|
|
2938
|
+
}
|
|
2642
2939
|
}
|
|
2643
2940
|
const response = await this.request(`${FAL_BASE_URL}/${config.endpoint}`, {
|
|
2644
|
-
|
|
2645
|
-
|
|
2941
|
+
body: JSON.stringify(rbBody),
|
|
2942
|
+
method: "POST"
|
|
2646
2943
|
});
|
|
2647
2944
|
if (response.isErr()) {
|
|
2648
2945
|
return (0, import_neverthrow.err)(response.error);
|
|
@@ -2671,28 +2968,33 @@ var MotifServer = class {
|
|
|
2671
2968
|
return (0, import_neverthrow.err)(new MotifError("Kling video model not found", 0));
|
|
2672
2969
|
}
|
|
2673
2970
|
const body = {
|
|
2674
|
-
start_image_url: imageUrl,
|
|
2675
|
-
prompt,
|
|
2676
2971
|
duration: String(duration),
|
|
2677
|
-
generate_audio: generateAudio
|
|
2972
|
+
generate_audio: generateAudio,
|
|
2973
|
+
prompt,
|
|
2974
|
+
start_image_url: imageUrl
|
|
2678
2975
|
};
|
|
2679
|
-
if (endImageUrl) {
|
|
2976
|
+
if (endImageUrl !== void 0 && endImageUrl !== "") {
|
|
2680
2977
|
body.end_image_url = endImageUrl;
|
|
2681
2978
|
}
|
|
2682
|
-
if (negativePrompt
|
|
2683
|
-
|
|
2979
|
+
if (negativePrompt !== void 0 && negativePrompt !== "") {
|
|
2980
|
+
body.negative_prompt = negativePrompt;
|
|
2981
|
+
}
|
|
2982
|
+
if (cfgScale !== void 0) {
|
|
2983
|
+
body.cfg_scale = cfgScale;
|
|
2984
|
+
}
|
|
2684
2985
|
const response = await this.request(`${FAL_QUEUE_URL}/${config.endpoint}`, {
|
|
2685
|
-
|
|
2686
|
-
|
|
2986
|
+
body: JSON.stringify(body),
|
|
2987
|
+
method: "POST"
|
|
2687
2988
|
});
|
|
2688
2989
|
if (response.isErr()) {
|
|
2689
2990
|
return (0, import_neverthrow.err)(response.error);
|
|
2690
2991
|
}
|
|
2691
2992
|
const data = await response.value.json();
|
|
2993
|
+
const submission = parseQueueSubmission(data);
|
|
2692
2994
|
return (0, import_neverthrow.ok)({
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2995
|
+
endpoint: endpointFromQueueUrl(submission.responseUrl, config.endpoint),
|
|
2996
|
+
estimatedCost: estimateVideoCost(duration, generateAudio),
|
|
2997
|
+
requestId: submission.requestId
|
|
2696
2998
|
});
|
|
2697
2999
|
}
|
|
2698
3000
|
/** Fetch the completed video result from the queue. */
|
|
@@ -2703,14 +3005,15 @@ var MotifServer = class {
|
|
|
2703
3005
|
return (0, import_neverthrow.err)(response.error);
|
|
2704
3006
|
}
|
|
2705
3007
|
const data = await response.value.json();
|
|
2706
|
-
|
|
3008
|
+
const video = isRecord(data) && isRecord(data.video) ? data.video : void 0;
|
|
3009
|
+
if (video === void 0) {
|
|
2707
3010
|
return (0, import_neverthrow.err)(new MotifError("No video in response", 0));
|
|
2708
3011
|
}
|
|
2709
3012
|
return (0, import_neverthrow.ok)({
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
3013
|
+
contentType: asString(video.content_type) ?? "",
|
|
3014
|
+
fileName: asString(video.file_name) ?? "",
|
|
3015
|
+
fileSize: asNumber(video.file_size) ?? 0,
|
|
3016
|
+
url: asString(video.url) ?? ""
|
|
2714
3017
|
});
|
|
2715
3018
|
}
|
|
2716
3019
|
/** ─── File Upload ─────────────────────────────────────────── */
|
|
@@ -2722,26 +3025,33 @@ var MotifServer = class {
|
|
|
2722
3025
|
const initiateResponse = await this.request(
|
|
2723
3026
|
`${FAL_REST_URL}/storage/upload/initiate?storage_type=fal-cdn-v3`,
|
|
2724
3027
|
{
|
|
2725
|
-
method: "POST",
|
|
2726
3028
|
body: JSON.stringify({
|
|
2727
3029
|
content_type: options.contentType,
|
|
2728
3030
|
file_name: options.fileName
|
|
2729
|
-
})
|
|
3031
|
+
}),
|
|
3032
|
+
method: "POST"
|
|
2730
3033
|
}
|
|
2731
3034
|
);
|
|
2732
3035
|
if (initiateResponse.isErr()) {
|
|
2733
3036
|
return (0, import_neverthrow.err)(initiateResponse.error);
|
|
2734
3037
|
}
|
|
2735
|
-
const
|
|
3038
|
+
const initiateData = await initiateResponse.value.json();
|
|
3039
|
+
const fileUrl = isRecord(initiateData) ? asString(initiateData.file_url) ?? "" : "";
|
|
3040
|
+
const uploadUrl = isRecord(initiateData) ? asString(initiateData.upload_url) : void 0;
|
|
3041
|
+
if (uploadUrl === void 0 || uploadUrl === "") {
|
|
3042
|
+
return (0, import_neverthrow.err)(
|
|
3043
|
+
new MotifError("Upload initiate response missing upload_url", 0)
|
|
3044
|
+
);
|
|
3045
|
+
}
|
|
2736
3046
|
let putResponse;
|
|
2737
3047
|
try {
|
|
2738
3048
|
const body = Buffer.from(
|
|
2739
3049
|
file instanceof Uint8Array ? file : new Uint8Array(file)
|
|
2740
3050
|
);
|
|
2741
|
-
putResponse = await fetch(
|
|
2742
|
-
|
|
3051
|
+
putResponse = await fetch(uploadUrl, {
|
|
3052
|
+
body,
|
|
2743
3053
|
headers: { "Content-Type": options.contentType },
|
|
2744
|
-
|
|
3054
|
+
method: "PUT"
|
|
2745
3055
|
});
|
|
2746
3056
|
} catch (error) {
|
|
2747
3057
|
return (0, import_neverthrow.err)(
|
|
@@ -2759,7 +3069,7 @@ var MotifServer = class {
|
|
|
2759
3069
|
)
|
|
2760
3070
|
);
|
|
2761
3071
|
}
|
|
2762
|
-
return (0, import_neverthrow.ok)(
|
|
3072
|
+
return (0, import_neverthrow.ok)(fileUrl);
|
|
2763
3073
|
}
|
|
2764
3074
|
/** ─── Utilities ───────────────────────────────────────────── */
|
|
2765
3075
|
/** Run a registered fal utility/tool endpoint. */
|
|
@@ -2776,13 +3086,14 @@ var MotifServer = class {
|
|
|
2776
3086
|
);
|
|
2777
3087
|
}
|
|
2778
3088
|
const response = await this.request(`${FAL_BASE_URL}/${request.endpoint}`, {
|
|
2779
|
-
|
|
2780
|
-
|
|
3089
|
+
body: JSON.stringify(request.body),
|
|
3090
|
+
method: "POST"
|
|
2781
3091
|
});
|
|
2782
3092
|
if (response.isErr()) {
|
|
2783
3093
|
return (0, import_neverthrow.err)(response.error);
|
|
2784
3094
|
}
|
|
2785
|
-
|
|
3095
|
+
const data = await response.value.json();
|
|
3096
|
+
return (0, import_neverthrow.ok)(isRecord(data) ? data : {});
|
|
2786
3097
|
}
|
|
2787
3098
|
/**
|
|
2788
3099
|
* Delete fal's stored IO payloads for a completed request.
|
|
@@ -2799,7 +3110,7 @@ var MotifServer = class {
|
|
|
2799
3110
|
if (response.isErr()) {
|
|
2800
3111
|
return (0, import_neverthrow.err)(response.error);
|
|
2801
3112
|
}
|
|
2802
|
-
return (0, import_neverthrow.ok)(
|
|
3113
|
+
return (0, import_neverthrow.ok)();
|
|
2803
3114
|
}
|
|
2804
3115
|
/** Estimate cost for a generation (no API call). */
|
|
2805
3116
|
estimateCost(model, resolution, numImages) {
|
|
@@ -2831,21 +3142,25 @@ var MotifServer = class {
|
|
|
2831
3142
|
let lastError = null;
|
|
2832
3143
|
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
2833
3144
|
const controller = new AbortController();
|
|
2834
|
-
const timeoutId = setTimeout(() =>
|
|
3145
|
+
const timeoutId = setTimeout(() => {
|
|
3146
|
+
controller.abort();
|
|
3147
|
+
}, this.timeout);
|
|
2835
3148
|
try {
|
|
2836
3149
|
const response = await fetch(url, {
|
|
2837
3150
|
...options,
|
|
2838
|
-
signal: controller.signal,
|
|
2839
3151
|
headers: {
|
|
2840
3152
|
Authorization: `Key ${this.apiKey}`,
|
|
2841
3153
|
"Content-Type": "application/json",
|
|
2842
|
-
...options.headers
|
|
2843
|
-
}
|
|
3154
|
+
...toHeaderRecord(options.headers)
|
|
3155
|
+
},
|
|
3156
|
+
signal: controller.signal
|
|
2844
3157
|
});
|
|
2845
3158
|
clearTimeout(timeoutId);
|
|
2846
3159
|
if ((response.status === 429 || response.status >= 500) && attempt < this.retries) {
|
|
2847
3160
|
const delay = 1e3 * 2 ** attempt;
|
|
2848
|
-
await new Promise((r) =>
|
|
3161
|
+
await new Promise((r) => {
|
|
3162
|
+
setTimeout(r, delay);
|
|
3163
|
+
});
|
|
2849
3164
|
continue;
|
|
2850
3165
|
}
|
|
2851
3166
|
if (!response.ok) {
|
|
@@ -2869,38 +3184,45 @@ var MotifServer = class {
|
|
|
2869
3184
|
);
|
|
2870
3185
|
if (attempt < this.retries) {
|
|
2871
3186
|
const delay = 1e3 * 2 ** attempt;
|
|
2872
|
-
await new Promise((r) =>
|
|
3187
|
+
await new Promise((r) => {
|
|
3188
|
+
setTimeout(r, delay);
|
|
3189
|
+
});
|
|
2873
3190
|
}
|
|
2874
3191
|
}
|
|
2875
3192
|
}
|
|
2876
3193
|
return (0, import_neverthrow.err)(lastError ?? new MotifError("Request failed after retries", 0));
|
|
2877
3194
|
}
|
|
2878
3195
|
ephemeralHeaders(options) {
|
|
2879
|
-
return options.ephemeral ? { "X-Fal-Store-IO": "0" } : {};
|
|
3196
|
+
return options.ephemeral === true ? { "X-Fal-Store-IO": "0" } : {};
|
|
2880
3197
|
}
|
|
2881
3198
|
/**
|
|
2882
3199
|
* Normalize fal.ai responses.
|
|
2883
3200
|
* Some APIs return `{ image: {...} }` instead of `{ images: [...] }`.
|
|
2884
3201
|
*/
|
|
2885
3202
|
normalizeResponse(data, fallbackRequestId) {
|
|
2886
|
-
|
|
2887
|
-
const requestId = obj.request_id ?? obj.requestId ?? fallbackRequestId;
|
|
2888
|
-
if ("detail" in obj) {
|
|
3203
|
+
if (!isRecord(data)) {
|
|
2889
3204
|
return (0, import_neverthrow.err)(
|
|
2890
|
-
new MotifError(
|
|
3205
|
+
new MotifError("Unexpected fal response shape", 0, "FAL_ERROR")
|
|
2891
3206
|
);
|
|
2892
3207
|
}
|
|
3208
|
+
const obj = data;
|
|
3209
|
+
const requestId = asString(obj.request_id) ?? asString(obj.requestId) ?? fallbackRequestId;
|
|
3210
|
+
if ("detail" in obj) {
|
|
3211
|
+
return (0, import_neverthrow.err)(new MotifError(asString(obj.detail) ?? "", 0, "FAL_ERROR"));
|
|
3212
|
+
}
|
|
2893
3213
|
if ("image" in obj && !("images" in obj)) {
|
|
2894
3214
|
return (0, import_neverthrow.ok)({
|
|
2895
|
-
images: [obj.image],
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
3215
|
+
images: [toMotifImage(obj.image)],
|
|
3216
|
+
prompt: asString(obj.prompt),
|
|
3217
|
+
requestId,
|
|
3218
|
+
seed: asNumber(obj.seed)
|
|
2899
3219
|
});
|
|
2900
3220
|
}
|
|
2901
3221
|
return (0, import_neverthrow.ok)({
|
|
2902
|
-
|
|
2903
|
-
|
|
3222
|
+
images: parseImages(obj.images),
|
|
3223
|
+
prompt: asString(obj.prompt),
|
|
3224
|
+
requestId,
|
|
3225
|
+
seed: asNumber(obj.seed)
|
|
2904
3226
|
});
|
|
2905
3227
|
}
|
|
2906
3228
|
};
|