@howells/motif-sdk 6.0.0 → 7.0.0
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 +5 -5
- package/dist/image.js +7 -605
- package/dist/index.cjs +11 -746
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +11 -746
- package/dist/registry.d.ts +1757 -0
- package/dist/registry.js +2714 -0
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -314,7 +314,7 @@ const CREATIVE_TAXONOMY = {
|
|
|
314
314
|
description: "Natural, unposed documentary portraits of people. Pair with a mood for the light.",
|
|
315
315
|
id: "portrait",
|
|
316
316
|
label: "Documentary portrait",
|
|
317
|
-
model: "
|
|
317
|
+
model: "seedream5"
|
|
318
318
|
},
|
|
319
319
|
{
|
|
320
320
|
acceptsMood: false,
|
|
@@ -701,7 +701,6 @@ const AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-10-07";
|
|
|
701
701
|
const AA_IMAGE_SOURCES = ["https://artificialanalysis.ai/image/leaderboard/text-to-image", "https://artificialanalysis.ai/image/leaderboard/editing"];
|
|
702
702
|
const FAL_PRICING_CHECKED_AT = "2026-05-12";
|
|
703
703
|
const FAL_PRICING_CHECKED_JUL_2026 = "2026-07-11";
|
|
704
|
-
const FAL_PRICING_CHECKED_AUG_2026 = "2026-08-23";
|
|
705
704
|
const FAL_PRICING_CHECKED_SEP_2026 = "2026-09-16";
|
|
706
705
|
const FAL_PRICING_CHECKED_OCT_2026 = "2026-10-29";
|
|
707
706
|
const MODELS = {
|
|
@@ -1000,7 +999,7 @@ const MODELS = {
|
|
|
1000
999
|
quality: "frontier",
|
|
1001
1000
|
speed: "unknown"
|
|
1002
1001
|
},
|
|
1003
|
-
useCase: "
|
|
1002
|
+
useCase: "Gemini workhorse with 0.5K output"
|
|
1004
1003
|
},
|
|
1005
1004
|
editEndpoint: "fal-ai/nano-banana-2/edit",
|
|
1006
1005
|
endpoint: "fal-ai/nano-banana-2",
|
|
@@ -1105,211 +1104,6 @@ const MODELS = {
|
|
|
1105
1104
|
supportsWebSearch: true,
|
|
1106
1105
|
type: "generation"
|
|
1107
1106
|
},
|
|
1108
|
-
gemini: {
|
|
1109
|
-
benchmark: { artificialAnalysis: {
|
|
1110
|
-
editing: {
|
|
1111
|
-
elo: 987,
|
|
1112
|
-
rank: 50
|
|
1113
|
-
},
|
|
1114
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1115
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1116
|
-
textToImage: {
|
|
1117
|
-
elo: 985,
|
|
1118
|
-
rank: 60
|
|
1119
|
-
}
|
|
1120
|
-
} },
|
|
1121
|
-
editEndpoint: "fal-ai/gemini-25-flash-image/edit",
|
|
1122
|
-
endpoint: "fal-ai/gemini-25-flash-image",
|
|
1123
|
-
falPricing: {
|
|
1124
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1125
|
-
currency: "USD",
|
|
1126
|
-
endpointId: "fal-ai/gemini-25-flash-image",
|
|
1127
|
-
estimatedCostPerImageUsd: .0398,
|
|
1128
|
-
source: "fal-pricing-api",
|
|
1129
|
-
unit: "images",
|
|
1130
|
-
unitPrice: .0398
|
|
1131
|
-
},
|
|
1132
|
-
maxReferenceImages: 4,
|
|
1133
|
-
name: "Gemini 2.5 Flash",
|
|
1134
|
-
pricePerImageUsd: .0398,
|
|
1135
|
-
pricing: "$0.04",
|
|
1136
|
-
sizeMode: "aspect_ratio",
|
|
1137
|
-
supportedAspects: [
|
|
1138
|
-
"21:9",
|
|
1139
|
-
"16:9",
|
|
1140
|
-
"3:2",
|
|
1141
|
-
"4:3",
|
|
1142
|
-
"5:4",
|
|
1143
|
-
"1:1",
|
|
1144
|
-
"4:5",
|
|
1145
|
-
"3:4",
|
|
1146
|
-
"2:3",
|
|
1147
|
-
"9:16"
|
|
1148
|
-
],
|
|
1149
|
-
supportsAspect: true,
|
|
1150
|
-
supportsEdit: true,
|
|
1151
|
-
supportsNumImages: true,
|
|
1152
|
-
supportsOutputFormat: true,
|
|
1153
|
-
supportsResolution: false,
|
|
1154
|
-
supportsSafetyTolerance: true,
|
|
1155
|
-
supportsSeed: true,
|
|
1156
|
-
supportsSyncMode: true,
|
|
1157
|
-
type: "generation"
|
|
1158
|
-
},
|
|
1159
|
-
gemini3: {
|
|
1160
|
-
editEndpoint: "fal-ai/gemini-3-pro-image-preview/edit",
|
|
1161
|
-
endpoint: "fal-ai/gemini-3-pro-image-preview",
|
|
1162
|
-
falPricing: {
|
|
1163
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1164
|
-
currency: "USD",
|
|
1165
|
-
endpointId: "fal-ai/gemini-3-pro-image-preview",
|
|
1166
|
-
estimatedCostPerImageUsd: .15,
|
|
1167
|
-
source: "fal-pricing-api",
|
|
1168
|
-
unit: "images",
|
|
1169
|
-
unitPrice: .15
|
|
1170
|
-
},
|
|
1171
|
-
maxReferenceImages: 4,
|
|
1172
|
-
name: "Gemini 3 Pro",
|
|
1173
|
-
pricePerImageUsd: .15,
|
|
1174
|
-
pricing: "$0.15",
|
|
1175
|
-
sizeMode: "aspect_ratio",
|
|
1176
|
-
supportedAspects: [
|
|
1177
|
-
"auto",
|
|
1178
|
-
"21:9",
|
|
1179
|
-
"16:9",
|
|
1180
|
-
"3:2",
|
|
1181
|
-
"4:3",
|
|
1182
|
-
"5:4",
|
|
1183
|
-
"1:1",
|
|
1184
|
-
"4:5",
|
|
1185
|
-
"3:4",
|
|
1186
|
-
"2:3",
|
|
1187
|
-
"9:16"
|
|
1188
|
-
],
|
|
1189
|
-
supportedResolutions: [
|
|
1190
|
-
"1K",
|
|
1191
|
-
"2K",
|
|
1192
|
-
"4K"
|
|
1193
|
-
],
|
|
1194
|
-
supportsAspect: true,
|
|
1195
|
-
supportsEdit: true,
|
|
1196
|
-
supportsNumImages: true,
|
|
1197
|
-
supportsOutputFormat: true,
|
|
1198
|
-
supportsResolution: true,
|
|
1199
|
-
supportsSafetyTolerance: true,
|
|
1200
|
-
supportsSeed: true,
|
|
1201
|
-
supportsSyncMode: true,
|
|
1202
|
-
supportsWebSearch: true,
|
|
1203
|
-
type: "generation"
|
|
1204
|
-
},
|
|
1205
|
-
seedream4: {
|
|
1206
|
-
benchmark: {
|
|
1207
|
-
artificialAnalysis: {
|
|
1208
|
-
editing: {
|
|
1209
|
-
elo: 1015,
|
|
1210
|
-
rank: 36
|
|
1211
|
-
},
|
|
1212
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1213
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1214
|
-
textToImage: {
|
|
1215
|
-
elo: 1030,
|
|
1216
|
-
rank: 21
|
|
1217
|
-
}
|
|
1218
|
-
},
|
|
1219
|
-
speed: {
|
|
1220
|
-
medianSeconds: 14.3,
|
|
1221
|
-
p95Seconds: 21,
|
|
1222
|
-
source: "artificial-analysis-models"
|
|
1223
|
-
},
|
|
1224
|
-
tiers: {
|
|
1225
|
-
price: "budget",
|
|
1226
|
-
quality: "best",
|
|
1227
|
-
speed: "balanced"
|
|
1228
|
-
},
|
|
1229
|
-
useCase: "Legacy budget generation and large multi-reference edits"
|
|
1230
|
-
},
|
|
1231
|
-
customImageSize: {
|
|
1232
|
-
maxPixels: 16777216,
|
|
1233
|
-
minPixels: 921600
|
|
1234
|
-
},
|
|
1235
|
-
editEndpoint: "fal-ai/bytedance/seedream/v4/edit",
|
|
1236
|
-
endpoint: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
1237
|
-
falPricing: {
|
|
1238
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1239
|
-
currency: "USD",
|
|
1240
|
-
endpointId: "fal-ai/bytedance/seedream/v4/text-to-image",
|
|
1241
|
-
estimatedCostPerImageUsd: .03,
|
|
1242
|
-
source: "fal-pricing-api",
|
|
1243
|
-
unit: "images",
|
|
1244
|
-
unitPrice: .03
|
|
1245
|
-
},
|
|
1246
|
-
maxReferenceImages: 10,
|
|
1247
|
-
name: "Seedream 4.0",
|
|
1248
|
-
pricePerImageUsd: .03,
|
|
1249
|
-
pricing: "$0.03",
|
|
1250
|
-
sizeMode: "image_size_enum",
|
|
1251
|
-
supportsAspect: true,
|
|
1252
|
-
supportsEdit: true,
|
|
1253
|
-
supportsNumImages: true,
|
|
1254
|
-
supportsResolution: false,
|
|
1255
|
-
supportsSeed: true,
|
|
1256
|
-
supportsSyncMode: true,
|
|
1257
|
-
type: "generation"
|
|
1258
|
-
},
|
|
1259
|
-
seedream45: {
|
|
1260
|
-
benchmark: {
|
|
1261
|
-
artificialAnalysis: {
|
|
1262
|
-
editing: {
|
|
1263
|
-
elo: 1037,
|
|
1264
|
-
rank: 32
|
|
1265
|
-
},
|
|
1266
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1267
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1268
|
-
textToImage: {
|
|
1269
|
-
elo: 1022,
|
|
1270
|
-
rank: 26
|
|
1271
|
-
}
|
|
1272
|
-
},
|
|
1273
|
-
speed: {
|
|
1274
|
-
medianSeconds: 18.2,
|
|
1275
|
-
p95Seconds: 43.3,
|
|
1276
|
-
source: "artificial-analysis-models"
|
|
1277
|
-
},
|
|
1278
|
-
tiers: {
|
|
1279
|
-
price: "standard",
|
|
1280
|
-
quality: "better",
|
|
1281
|
-
speed: "balanced"
|
|
1282
|
-
},
|
|
1283
|
-
useCase: "Cheap current Seedream model with good animation/art scores"
|
|
1284
|
-
},
|
|
1285
|
-
customImageSize: {
|
|
1286
|
-
maxPixels: 16777216,
|
|
1287
|
-
minPixels: 3686400
|
|
1288
|
-
},
|
|
1289
|
-
editEndpoint: "fal-ai/bytedance/seedream/v4.5/edit",
|
|
1290
|
-
endpoint: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
1291
|
-
falPricing: {
|
|
1292
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1293
|
-
currency: "USD",
|
|
1294
|
-
endpointId: "fal-ai/bytedance/seedream/v4.5/text-to-image",
|
|
1295
|
-
estimatedCostPerImageUsd: .04,
|
|
1296
|
-
source: "fal-pricing-api",
|
|
1297
|
-
unit: "images",
|
|
1298
|
-
unitPrice: .04
|
|
1299
|
-
},
|
|
1300
|
-
maxReferenceImages: 10,
|
|
1301
|
-
name: "Seedream 4.5",
|
|
1302
|
-
pricePerImageUsd: .04,
|
|
1303
|
-
pricing: "$0.04",
|
|
1304
|
-
sizeMode: "image_size_enum",
|
|
1305
|
-
supportsAspect: true,
|
|
1306
|
-
supportsEdit: true,
|
|
1307
|
-
supportsNumImages: true,
|
|
1308
|
-
supportsResolution: false,
|
|
1309
|
-
supportsSeed: true,
|
|
1310
|
-
supportsSyncMode: true,
|
|
1311
|
-
type: "generation"
|
|
1312
|
-
},
|
|
1313
1107
|
seedream5: {
|
|
1314
1108
|
benchmark: { artificialAnalysis: {
|
|
1315
1109
|
editing: {
|
|
@@ -1393,65 +1187,6 @@ const MODELS = {
|
|
|
1393
1187
|
supportsSyncMode: true,
|
|
1394
1188
|
maxReferenceImages: 10
|
|
1395
1189
|
},
|
|
1396
|
-
"flux2-max": {
|
|
1397
|
-
benchmark: {
|
|
1398
|
-
artificialAnalysis: {
|
|
1399
|
-
editing: {
|
|
1400
|
-
elo: 997,
|
|
1401
|
-
rank: 49
|
|
1402
|
-
},
|
|
1403
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1404
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1405
|
-
textToImage: {
|
|
1406
|
-
elo: 1020,
|
|
1407
|
-
rank: 28
|
|
1408
|
-
}
|
|
1409
|
-
},
|
|
1410
|
-
speed: {
|
|
1411
|
-
medianSeconds: 31.6,
|
|
1412
|
-
p95Seconds: 41,
|
|
1413
|
-
source: "artificial-analysis-models"
|
|
1414
|
-
},
|
|
1415
|
-
tiers: {
|
|
1416
|
-
price: "premium",
|
|
1417
|
-
quality: "best",
|
|
1418
|
-
speed: "slow"
|
|
1419
|
-
},
|
|
1420
|
-
useCase: "Best FLUX quality and high-end editing"
|
|
1421
|
-
},
|
|
1422
|
-
customImageSize: {
|
|
1423
|
-
maxEdge: 2560,
|
|
1424
|
-
maxPixels: 4194304,
|
|
1425
|
-
minEdge: 256,
|
|
1426
|
-
multipleOf: 16
|
|
1427
|
-
},
|
|
1428
|
-
editEndpoint: "fal-ai/flux-2-max/edit",
|
|
1429
|
-
endpoint: "fal-ai/flux-2-max",
|
|
1430
|
-
falPricing: {
|
|
1431
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1432
|
-
currency: "USD",
|
|
1433
|
-
endpointId: "fal-ai/flux-2-max",
|
|
1434
|
-
estimatedCostPerImageUsd: .07,
|
|
1435
|
-
source: "fal-pricing-api",
|
|
1436
|
-
unit: "megapixels",
|
|
1437
|
-
unitPrice: .07
|
|
1438
|
-
},
|
|
1439
|
-
maxReferenceImages: 10,
|
|
1440
|
-
name: "FLUX.2 Max",
|
|
1441
|
-
pricePerImageUsd: .07,
|
|
1442
|
-
pricing: "$0.07/MP",
|
|
1443
|
-
sizeMode: "image_size_enum",
|
|
1444
|
-
supportsAspect: true,
|
|
1445
|
-
supportsEdit: true,
|
|
1446
|
-
supportsNumImages: false,
|
|
1447
|
-
supportsOutputFormat: true,
|
|
1448
|
-
supportsResolution: false,
|
|
1449
|
-
supportsSafetyChecker: true,
|
|
1450
|
-
supportsSafetyTolerance: true,
|
|
1451
|
-
supportsSeed: true,
|
|
1452
|
-
supportsSyncMode: true,
|
|
1453
|
-
type: "generation"
|
|
1454
|
-
},
|
|
1455
1190
|
"flux2-pro": {
|
|
1456
1191
|
benchmark: {
|
|
1457
1192
|
artificialAnalysis: {
|
|
@@ -1573,69 +1308,6 @@ const MODELS = {
|
|
|
1573
1308
|
supportsSyncMode: true,
|
|
1574
1309
|
type: "generation"
|
|
1575
1310
|
},
|
|
1576
|
-
"flux2-dev": {
|
|
1577
|
-
benchmark: {
|
|
1578
|
-
artificialAnalysis: {
|
|
1579
|
-
editing: {
|
|
1580
|
-
elo: 1e3,
|
|
1581
|
-
rank: 45
|
|
1582
|
-
},
|
|
1583
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1584
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1585
|
-
textToImage: {
|
|
1586
|
-
elo: 1e3,
|
|
1587
|
-
rank: 42
|
|
1588
|
-
}
|
|
1589
|
-
},
|
|
1590
|
-
speed: {
|
|
1591
|
-
medianSeconds: 4.6,
|
|
1592
|
-
p95Seconds: 69.6,
|
|
1593
|
-
source: "artificial-analysis-models"
|
|
1594
|
-
},
|
|
1595
|
-
tiers: {
|
|
1596
|
-
price: "variable",
|
|
1597
|
-
quality: "better",
|
|
1598
|
-
speed: "fast"
|
|
1599
|
-
},
|
|
1600
|
-
useCase: "Open FLUX.2 quality with low average cost"
|
|
1601
|
-
},
|
|
1602
|
-
customImageSize: {
|
|
1603
|
-
maxEdge: 2048,
|
|
1604
|
-
minEdge: 512
|
|
1605
|
-
},
|
|
1606
|
-
editEndpoint: "fal-ai/flux-2/edit",
|
|
1607
|
-
endpoint: "fal-ai/flux-2",
|
|
1608
|
-
falPricing: {
|
|
1609
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1610
|
-
currency: "USD",
|
|
1611
|
-
endpointId: "fal-ai/flux-2",
|
|
1612
|
-
estimatedCostPerImageUsd: .012,
|
|
1613
|
-
source: "fal-pricing-api",
|
|
1614
|
-
unit: "compute seconds",
|
|
1615
|
-
unitPrice: .00167
|
|
1616
|
-
},
|
|
1617
|
-
maxReferenceImages: 4,
|
|
1618
|
-
name: "FLUX.2 [dev]",
|
|
1619
|
-
pricePerImageUsd: .012,
|
|
1620
|
-
pricing: "$0.00167/sec",
|
|
1621
|
-
sizeMode: "image_size_enum",
|
|
1622
|
-
supportsAspect: true,
|
|
1623
|
-
streaming: {
|
|
1624
|
-
generation: true,
|
|
1625
|
-
edit: true
|
|
1626
|
-
},
|
|
1627
|
-
supportsEdit: true,
|
|
1628
|
-
supportsGuidanceScale: true,
|
|
1629
|
-
supportsInferenceSteps: true,
|
|
1630
|
-
supportsNumImages: true,
|
|
1631
|
-
supportsOutputFormat: true,
|
|
1632
|
-
supportsResolution: false,
|
|
1633
|
-
supportsSafetyChecker: true,
|
|
1634
|
-
supportsSafetyTolerance: true,
|
|
1635
|
-
supportsSeed: true,
|
|
1636
|
-
supportsSyncMode: true,
|
|
1637
|
-
type: "generation"
|
|
1638
|
-
},
|
|
1639
1311
|
"flux2-turbo": {
|
|
1640
1312
|
customImageSize: {
|
|
1641
1313
|
maxEdge: 2048,
|
|
@@ -1666,188 +1338,6 @@ const MODELS = {
|
|
|
1666
1338
|
supportsSyncMode: true,
|
|
1667
1339
|
type: "generation"
|
|
1668
1340
|
},
|
|
1669
|
-
flux: {
|
|
1670
|
-
endpoint: "fal-ai/flux-pro/v1.1-ultra",
|
|
1671
|
-
falPricing: {
|
|
1672
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1673
|
-
currency: "USD",
|
|
1674
|
-
endpointId: "fal-ai/flux-pro/v1.1-ultra",
|
|
1675
|
-
estimatedCostPerImageUsd: .06,
|
|
1676
|
-
source: "fal-pricing-api",
|
|
1677
|
-
unit: "images",
|
|
1678
|
-
unitPrice: .06
|
|
1679
|
-
},
|
|
1680
|
-
maxReferenceImages: 1,
|
|
1681
|
-
name: "FLUX Pro Ultra",
|
|
1682
|
-
pricePerImageUsd: .06,
|
|
1683
|
-
pricing: "$0.06",
|
|
1684
|
-
sizeMode: "aspect_ratio",
|
|
1685
|
-
supportsAspect: true,
|
|
1686
|
-
supportsEdit: true,
|
|
1687
|
-
supportsEnhancePrompt: true,
|
|
1688
|
-
supportsImagePromptStrength: true,
|
|
1689
|
-
supportsNumImages: true,
|
|
1690
|
-
supportsOutputFormat: true,
|
|
1691
|
-
supportsRaw: true,
|
|
1692
|
-
supportsResolution: false,
|
|
1693
|
-
supportsSafetyTolerance: true,
|
|
1694
|
-
supportsSeed: true,
|
|
1695
|
-
supportsSyncMode: true,
|
|
1696
|
-
type: "generation"
|
|
1697
|
-
},
|
|
1698
|
-
"flux-fast": {
|
|
1699
|
-
customImageSize: {},
|
|
1700
|
-
endpoint: "fal-ai/flux/schnell",
|
|
1701
|
-
falPricing: {
|
|
1702
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1703
|
-
currency: "USD",
|
|
1704
|
-
endpointId: "fal-ai/flux/schnell",
|
|
1705
|
-
estimatedCostPerImageUsd: .003,
|
|
1706
|
-
source: "fal-pricing-api",
|
|
1707
|
-
unit: "megapixels",
|
|
1708
|
-
unitPrice: .003
|
|
1709
|
-
},
|
|
1710
|
-
name: "FLUX Schnell",
|
|
1711
|
-
pricePerImageUsd: .003,
|
|
1712
|
-
pricing: "$0.003",
|
|
1713
|
-
sizeMode: "image_size_enum",
|
|
1714
|
-
supportsAspect: true,
|
|
1715
|
-
supportsEdit: false,
|
|
1716
|
-
supportsGuidanceScale: true,
|
|
1717
|
-
supportsInferenceSteps: true,
|
|
1718
|
-
supportsNumImages: true,
|
|
1719
|
-
supportsOutputFormat: true,
|
|
1720
|
-
supportsResolution: false,
|
|
1721
|
-
supportsSeed: true,
|
|
1722
|
-
supportsSyncMode: true,
|
|
1723
|
-
type: "generation"
|
|
1724
|
-
},
|
|
1725
|
-
recraft: {
|
|
1726
|
-
customImageSize: {},
|
|
1727
|
-
endpoint: "fal-ai/recraft/v3/text-to-image",
|
|
1728
|
-
falPricing: {
|
|
1729
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1730
|
-
currency: "USD",
|
|
1731
|
-
endpointId: "fal-ai/recraft/v3/text-to-image",
|
|
1732
|
-
estimatedCostPerImageUsd: .04,
|
|
1733
|
-
source: "fal-pricing-api",
|
|
1734
|
-
unit: "images",
|
|
1735
|
-
unitPrice: .04
|
|
1736
|
-
},
|
|
1737
|
-
name: "Recraft V3",
|
|
1738
|
-
pricePerImageUsd: .04,
|
|
1739
|
-
pricing: "$0.04",
|
|
1740
|
-
sizeMode: "image_size_enum",
|
|
1741
|
-
supportsAspect: true,
|
|
1742
|
-
supportsEdit: false,
|
|
1743
|
-
supportsNumImages: false,
|
|
1744
|
-
supportsResolution: false,
|
|
1745
|
-
supportsStyle: true,
|
|
1746
|
-
supportsSyncMode: true,
|
|
1747
|
-
type: "generation"
|
|
1748
|
-
},
|
|
1749
|
-
reve: {
|
|
1750
|
-
benchmark: {
|
|
1751
|
-
tiers: {
|
|
1752
|
-
price: "premium",
|
|
1753
|
-
quality: "frontier",
|
|
1754
|
-
speed: "unknown"
|
|
1755
|
-
},
|
|
1756
|
-
useCase: "Historical Reve route; not currently verified on fal"
|
|
1757
|
-
},
|
|
1758
|
-
editEndpoint: "fal-ai/reve/edit",
|
|
1759
|
-
endpoint: "fal-ai/reve/text-to-image",
|
|
1760
|
-
falPricing: {
|
|
1761
|
-
checkedAt: FAL_PRICING_CHECKED_AUG_2026,
|
|
1762
|
-
currency: "USD",
|
|
1763
|
-
endpointId: "fal-ai/reve/text-to-image",
|
|
1764
|
-
estimatedCostPerImageUsd: .04,
|
|
1765
|
-
source: "fal-pricing-api",
|
|
1766
|
-
unit: "images",
|
|
1767
|
-
unitPrice: .04
|
|
1768
|
-
},
|
|
1769
|
-
maxReferenceImages: 1,
|
|
1770
|
-
name: "Reve 2.1",
|
|
1771
|
-
pricePerImageUsd: .04,
|
|
1772
|
-
pricing: "$0.04",
|
|
1773
|
-
sizeMode: "aspect_ratio",
|
|
1774
|
-
supportedAspects: [
|
|
1775
|
-
"16:9",
|
|
1776
|
-
"9:16",
|
|
1777
|
-
"3:2",
|
|
1778
|
-
"2:3",
|
|
1779
|
-
"4:3",
|
|
1780
|
-
"3:4",
|
|
1781
|
-
"1:1"
|
|
1782
|
-
],
|
|
1783
|
-
supportsAspect: true,
|
|
1784
|
-
supportsEdit: true,
|
|
1785
|
-
supportsNumImages: true,
|
|
1786
|
-
supportsOutputFormat: true,
|
|
1787
|
-
supportsResolution: false,
|
|
1788
|
-
supportsSeed: false,
|
|
1789
|
-
supportsSyncMode: true,
|
|
1790
|
-
type: "generation"
|
|
1791
|
-
},
|
|
1792
|
-
recraft4: {
|
|
1793
|
-
benchmark: { artificialAnalysis: {
|
|
1794
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1795
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1796
|
-
textToImage: {
|
|
1797
|
-
elo: 984,
|
|
1798
|
-
rank: 62
|
|
1799
|
-
}
|
|
1800
|
-
} },
|
|
1801
|
-
customImageSize: {},
|
|
1802
|
-
endpoint: "fal-ai/recraft/v4/text-to-image",
|
|
1803
|
-
falPricing: {
|
|
1804
|
-
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
1805
|
-
currency: "USD",
|
|
1806
|
-
endpointId: "fal-ai/recraft/v4/text-to-image",
|
|
1807
|
-
estimatedCostPerImageUsd: .04,
|
|
1808
|
-
source: "fal-pricing-api",
|
|
1809
|
-
unit: "images",
|
|
1810
|
-
unitPrice: .04
|
|
1811
|
-
},
|
|
1812
|
-
name: "Recraft V4",
|
|
1813
|
-
pricePerImageUsd: .04,
|
|
1814
|
-
pricing: "$0.04",
|
|
1815
|
-
sizeMode: "image_size_enum",
|
|
1816
|
-
supportsAspect: true,
|
|
1817
|
-
supportsEdit: false,
|
|
1818
|
-
supportsNumImages: false,
|
|
1819
|
-
supportsResolution: false,
|
|
1820
|
-
supportsSyncMode: true,
|
|
1821
|
-
type: "generation"
|
|
1822
|
-
},
|
|
1823
|
-
ideogram: {
|
|
1824
|
-
customImageSize: {},
|
|
1825
|
-
endpoint: "fal-ai/ideogram/v3",
|
|
1826
|
-
falPricing: {
|
|
1827
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1828
|
-
currency: "USD",
|
|
1829
|
-
endpointId: "fal-ai/ideogram/v3",
|
|
1830
|
-
estimatedCostPerImageUsd: .03,
|
|
1831
|
-
source: "fal-pricing-api",
|
|
1832
|
-
unit: "images",
|
|
1833
|
-
unitPrice: .03
|
|
1834
|
-
},
|
|
1835
|
-
name: "Ideogram V3",
|
|
1836
|
-
pricePerImageUsd: .03,
|
|
1837
|
-
pricing: "$0.03",
|
|
1838
|
-
sizeMode: "image_size_enum",
|
|
1839
|
-
supportsAspect: true,
|
|
1840
|
-
supportsEdit: false,
|
|
1841
|
-
supportsExpandPrompt: true,
|
|
1842
|
-
supportsNegativePrompt: true,
|
|
1843
|
-
supportsNumImages: true,
|
|
1844
|
-
supportsRenderingSpeed: true,
|
|
1845
|
-
supportsResolution: false,
|
|
1846
|
-
supportsSeed: true,
|
|
1847
|
-
supportsStyle: true,
|
|
1848
|
-
supportsSyncMode: true,
|
|
1849
|
-
type: "generation"
|
|
1850
|
-
},
|
|
1851
1341
|
ideogram4: {
|
|
1852
1342
|
benchmark: { artificialAnalysis: {
|
|
1853
1343
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
@@ -1948,52 +1438,6 @@ const MODELS = {
|
|
|
1948
1438
|
supportsSyncMode: true,
|
|
1949
1439
|
type: "generation"
|
|
1950
1440
|
},
|
|
1951
|
-
qwen: {
|
|
1952
|
-
benchmark: {
|
|
1953
|
-
artificialAnalysis: {
|
|
1954
|
-
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1955
|
-
sourceUrls: AA_IMAGE_SOURCES,
|
|
1956
|
-
textToImage: {
|
|
1957
|
-
elo: 890,
|
|
1958
|
-
rank: 106
|
|
1959
|
-
}
|
|
1960
|
-
},
|
|
1961
|
-
speed: {
|
|
1962
|
-
medianSeconds: 23.3,
|
|
1963
|
-
p95Seconds: 491,
|
|
1964
|
-
source: "artificial-analysis-models"
|
|
1965
|
-
},
|
|
1966
|
-
tiers: {
|
|
1967
|
-
price: "budget",
|
|
1968
|
-
quality: "better",
|
|
1969
|
-
speed: "slow"
|
|
1970
|
-
},
|
|
1971
|
-
useCase: "Low-cost open-weight text and design generation"
|
|
1972
|
-
},
|
|
1973
|
-
customImageSize: {},
|
|
1974
|
-
endpoint: "fal-ai/qwen-image",
|
|
1975
|
-
falPricing: {
|
|
1976
|
-
checkedAt: FAL_PRICING_CHECKED_AT,
|
|
1977
|
-
currency: "USD",
|
|
1978
|
-
endpointId: "fal-ai/qwen-image",
|
|
1979
|
-
estimatedCostPerImageUsd: .02,
|
|
1980
|
-
source: "fal-pricing-api",
|
|
1981
|
-
unit: "megapixels",
|
|
1982
|
-
unitPrice: .02
|
|
1983
|
-
},
|
|
1984
|
-
name: "Qwen Image",
|
|
1985
|
-
pricePerImageUsd: .02,
|
|
1986
|
-
pricing: "$0.02/MP",
|
|
1987
|
-
sizeMode: "image_size_enum",
|
|
1988
|
-
supportsAspect: true,
|
|
1989
|
-
supportsEdit: false,
|
|
1990
|
-
supportsNumImages: true,
|
|
1991
|
-
supportsOutputFormat: true,
|
|
1992
|
-
supportsResolution: false,
|
|
1993
|
-
supportsSeed: true,
|
|
1994
|
-
supportsSyncMode: true,
|
|
1995
|
-
type: "generation"
|
|
1996
|
-
},
|
|
1997
1441
|
qwen3: {
|
|
1998
1442
|
benchmark: {
|
|
1999
1443
|
artificialAnalysis: {
|
|
@@ -2394,29 +1838,9 @@ const MODELS = {
|
|
|
2394
1838
|
supportsNumImages: false,
|
|
2395
1839
|
supportsResolution: false,
|
|
2396
1840
|
type: "utility"
|
|
2397
|
-
},
|
|
2398
|
-
rmbg: {
|
|
2399
|
-
endpoint: "fal-ai/birefnet",
|
|
2400
|
-
name: "BiRefNet (Background Removal)",
|
|
2401
|
-
pricing: "$0.02",
|
|
2402
|
-
supportsAspect: false,
|
|
2403
|
-
supportsEdit: false,
|
|
2404
|
-
supportsNumImages: false,
|
|
2405
|
-
supportsResolution: false,
|
|
2406
|
-
type: "utility"
|
|
2407
|
-
},
|
|
2408
|
-
bria: {
|
|
2409
|
-
endpoint: "fal-ai/bria/background/remove",
|
|
2410
|
-
name: "Bria RMBG 2.0",
|
|
2411
|
-
pricing: "$0.02",
|
|
2412
|
-
supportsAspect: false,
|
|
2413
|
-
supportsEdit: false,
|
|
2414
|
-
supportsNumImages: false,
|
|
2415
|
-
supportsResolution: false,
|
|
2416
|
-
type: "utility"
|
|
2417
1841
|
}
|
|
2418
1842
|
};
|
|
2419
|
-
/** Curated generation
|
|
1843
|
+
/** Curated generation Models, the only ones Motif recommends. */
|
|
2420
1844
|
const GENERATION_MODELS = [
|
|
2421
1845
|
"sunburst",
|
|
2422
1846
|
"flare",
|
|
@@ -2442,28 +1866,7 @@ const GENERATION_MODELS = [
|
|
|
2442
1866
|
"ideogram3-transparent",
|
|
2443
1867
|
"recraft41"
|
|
2444
1868
|
];
|
|
2445
|
-
/** Retained for old pins, explicit overrides and tuned Looks, never auto-selected. */
|
|
2446
|
-
const LEGACY_GENERATION_MODELS = [
|
|
2447
|
-
"gemini",
|
|
2448
|
-
"gemini3",
|
|
2449
|
-
"seedream4",
|
|
2450
|
-
"seedream45",
|
|
2451
|
-
"flux2-max",
|
|
2452
|
-
"flux2-dev",
|
|
2453
|
-
"flux",
|
|
2454
|
-
"flux-fast",
|
|
2455
|
-
"recraft",
|
|
2456
|
-
"recraft4",
|
|
2457
|
-
"ideogram",
|
|
2458
|
-
"qwen"
|
|
2459
|
-
];
|
|
2460
1869
|
GENERATION_MODELS.filter((id) => MODELS[id]?.supportsEdit === true);
|
|
2461
|
-
const UTILITY_MODELS = [
|
|
2462
|
-
"clarity",
|
|
2463
|
-
"crystal",
|
|
2464
|
-
"rmbg",
|
|
2465
|
-
"bria"
|
|
2466
|
-
];
|
|
2467
1870
|
//#endregion
|
|
2468
1871
|
//#region src/cost.ts
|
|
2469
1872
|
/**
|
|
@@ -2477,7 +1880,7 @@ function estimateCost(model, resolution, numImages = 1, editImages = 0) {
|
|
|
2477
1880
|
if (model === "grok-image-2" && editImages > 0) return (resolution === "2K" || resolution === "4K" ? .08 : .06) * numImages + .01 * editImages;
|
|
2478
1881
|
if (model === "grok-image-quality") return (resolution === "2K" || resolution === "4K" ? .07 : .05) * numImages + .01 * editImages;
|
|
2479
1882
|
if (configuredPrice !== void 0) {
|
|
2480
|
-
if (
|
|
1883
|
+
if (model === "banana" && resolution === "4K") return configuredPrice * 2 * numImages;
|
|
2481
1884
|
if (model === "seedream5" && (resolution === "2K" || resolution === "4K")) return configuredPrice * 2 * numImages;
|
|
2482
1885
|
if (model === "grok-image-2" && (resolution === "2K" || resolution === "4K")) return .08 * numImages;
|
|
2483
1886
|
if (model === "banana2") return configuredPrice * (resolution === "4K" ? 2 : resolution === "2K" ? 1.5 : resolution === "0.5K" ? .75 : 1) * numImages;
|
|
@@ -2485,17 +1888,8 @@ function estimateCost(model, resolution, numImages = 1, editImages = 0) {
|
|
|
2485
1888
|
}
|
|
2486
1889
|
switch (model) {
|
|
2487
1890
|
case "gpt": return .133 * numImages;
|
|
2488
|
-
case "banana":
|
|
2489
|
-
case "gemini3": return (resolution === "4K" ? .3 : .15) * numImages;
|
|
2490
|
-
case "gemini": return .039 * numImages;
|
|
2491
|
-
case "flux":
|
|
2492
|
-
case "ideogram": return .06 * numImages;
|
|
2493
|
-
case "recraft": return .04 * numImages;
|
|
2494
|
-
case "flux-fast": return .003 * numImages;
|
|
2495
1891
|
case "clarity": return .03 * numImages;
|
|
2496
|
-
case "crystal":
|
|
2497
|
-
case "rmbg":
|
|
2498
|
-
case "bria": return .02 * numImages;
|
|
1892
|
+
case "crystal": return .02 * numImages;
|
|
2499
1893
|
default: return .1 * numImages;
|
|
2500
1894
|
}
|
|
2501
1895
|
}
|
|
@@ -2639,11 +2033,9 @@ const OPTION_CAPABILITIES = {
|
|
|
2639
2033
|
enableGoogleSearch: (config) => config.supportsGoogleSearch === true,
|
|
2640
2034
|
enableSafetyChecker: (config) => config.supportsSafetyChecker === true,
|
|
2641
2035
|
enableWebSearch: (config) => config.supportsWebSearch === true,
|
|
2642
|
-
enhancePrompt: (config) => config.supportsEnhancePrompt === true,
|
|
2643
2036
|
expandPrompt: (config) => config.supportsExpandPrompt === true,
|
|
2644
2037
|
guidanceScale: (config) => config.supportsGuidanceScale === true,
|
|
2645
2038
|
"image editing": (config) => config.supportsEdit,
|
|
2646
|
-
imagePromptStrength: (config) => config.supportsImagePromptStrength === true,
|
|
2647
2039
|
imageSize: (config) => config.sizeMode === "gpt_size" || config.sizeMode === "image_size_enum",
|
|
2648
2040
|
inputFidelity: (config) => config.sizeMode === "gpt_size",
|
|
2649
2041
|
limitGenerations: (config) => config.supportsLimitGenerations === true,
|
|
@@ -2654,12 +2046,10 @@ const OPTION_CAPABILITIES = {
|
|
|
2654
2046
|
numInferenceSteps: (config) => config.supportsInferenceSteps === true,
|
|
2655
2047
|
outputFormat: (config) => config.supportsOutputFormat === true,
|
|
2656
2048
|
quality: (config) => config.supportsQuality === true,
|
|
2657
|
-
raw: (config) => config.supportsRaw === true,
|
|
2658
2049
|
renderingSpeed: (config) => config.supportsRenderingSpeed === true,
|
|
2659
2050
|
resolution: (config) => config.supportsResolution,
|
|
2660
2051
|
safetyTolerance: (config) => config.supportsSafetyTolerance === true,
|
|
2661
2052
|
seed: (config) => config.supportsSeed === true,
|
|
2662
|
-
style: (config) => config.supportsStyle === true,
|
|
2663
2053
|
syncMode: (config) => config.supportsSyncMode === true,
|
|
2664
2054
|
thinkingLevel: (config) => config.supportsThinkingLevel === true,
|
|
2665
2055
|
"transparent output": (config) => config.supportsBackground === true || config.transparentOutput === true
|
|
@@ -2687,7 +2077,7 @@ function modelsSupporting(option) {
|
|
|
2687
2077
|
*/
|
|
2688
2078
|
var UnsupportedOptionError = class extends Error {
|
|
2689
2079
|
code = "INVALID_OPTION";
|
|
2690
|
-
/** Display name of the model that refused, e.g. `"Seedream
|
|
2080
|
+
/** Display name of the model that refused, e.g. `"Seedream 5 Pro"`. */
|
|
2691
2081
|
model;
|
|
2692
2082
|
/** Generation model ids that accept `option`. */
|
|
2693
2083
|
modelsSupporting;
|
|
@@ -2776,8 +2166,6 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
2776
2166
|
if (config.sizeMode !== "gpt_size") unsupported(config, "inputFidelity");
|
|
2777
2167
|
}
|
|
2778
2168
|
if (options.imageSize !== void 0 && sizeMode !== "gpt_size" && sizeMode !== "image_size_enum") unsupported(config, "imageSize");
|
|
2779
|
-
if (options.imagePromptStrength !== void 0 && config.supportsImagePromptStrength !== true) unsupported(config, "imagePromptStrength");
|
|
2780
|
-
if (options.imagePromptStrength !== void 0 && !hasEditImages) throw new Error("imagePromptStrength requires editImageUrls");
|
|
2781
2169
|
if (options.maskImageUrl !== void 0 && config.supportsMaskImage !== true) unsupported(config, "maskImageUrl");
|
|
2782
2170
|
if (options.maskImageUrl !== void 0 && !hasEditImages) throw new Error("maskImageUrl requires editImageUrls");
|
|
2783
2171
|
if (options.markupImageUrl !== void 0 && config.supportsMarkupImage !== true) unsupported(config, "markupImageUrl");
|
|
@@ -2796,13 +2184,10 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
2796
2184
|
if (!qualities.includes(options.quality)) throw new Error(`${config.name} quality must be one of ${qualities.join(", ")}`);
|
|
2797
2185
|
}
|
|
2798
2186
|
if (options.negativePrompt !== void 0 && config.supportsNegativePrompt !== true) unsupported(config, "negativePrompt");
|
|
2799
|
-
if (options.style !== void 0 && config.supportsStyle !== true) unsupported(config, "style");
|
|
2800
2187
|
if (options.syncMode !== void 0 && config.supportsSyncMode !== true) unsupported(config, "syncMode");
|
|
2801
2188
|
if (options.renderingSpeed !== void 0 && config.supportsRenderingSpeed !== true) unsupported(config, "renderingSpeed");
|
|
2802
2189
|
if (options.guidanceScale !== void 0 && config.supportsGuidanceScale !== true) unsupported(config, "guidanceScale");
|
|
2803
2190
|
if (options.numInferenceSteps !== void 0 && config.supportsInferenceSteps !== true) unsupported(config, "numInferenceSteps");
|
|
2804
|
-
if (options.raw !== void 0 && config.supportsRaw !== true) unsupported(config, "raw");
|
|
2805
|
-
if (options.enhancePrompt !== void 0 && config.supportsEnhancePrompt !== true) unsupported(config, "enhancePrompt");
|
|
2806
2191
|
if (options.safetyTolerance !== void 0 && config.supportsSafetyTolerance !== true) unsupported(config, "safetyTolerance");
|
|
2807
2192
|
if (options.enableWebSearch !== void 0 && config.supportsWebSearch !== true) unsupported(config, "enableWebSearch");
|
|
2808
2193
|
if (options.enableGoogleSearch !== void 0 && config.supportsGoogleSearch !== true) unsupported(config, "enableGoogleSearch");
|
|
@@ -2822,7 +2207,7 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
2822
2207
|
* - `none`: no size control (video models)
|
|
2823
2208
|
*/
|
|
2824
2209
|
function buildGenerateBody(options) {
|
|
2825
|
-
const { prompt, model, creative, aspect = "1:1", resolution = "2K", numImages = 1, background, editImageUrls, enableGoogleSearch, enableSafetyChecker, transparent, inputFidelity, imageSize,
|
|
2210
|
+
const { prompt, model, creative, aspect = "1:1", resolution = "2K", numImages = 1, background, editImageUrls, enableGoogleSearch, enableSafetyChecker, transparent, inputFidelity, imageSize, limitGenerations, maskImageUrl, markupImageUrl, seed, outputFormat, quality, negativePrompt, syncMode, thinkingLevel, renderingSpeed, guidanceScale, numInferenceSteps, safetyTolerance, enableWebSearch, expandPrompt } = options;
|
|
2826
2211
|
const config = MODELS[model];
|
|
2827
2212
|
if (!config) throw new Error(`Unknown model: ${model}`);
|
|
2828
2213
|
let { endpoint } = config;
|
|
@@ -2858,12 +2243,6 @@ function buildGenerateBody(options) {
|
|
|
2858
2243
|
if (!formats.includes(outputFormat)) throw new Error(`${config.name} ${hasEditImages ? "edits support" : "supports"} output formats: ${formats.join(", ")}`);
|
|
2859
2244
|
body.output_format = outputFormat;
|
|
2860
2245
|
}
|
|
2861
|
-
if (config.supportsRaw === true && raw !== void 0) body.raw = raw;
|
|
2862
|
-
if (config.supportsEnhancePrompt === true && enhancePrompt !== void 0) body.enhance_prompt = enhancePrompt;
|
|
2863
|
-
if (config.supportsImagePromptStrength === true && imagePromptStrength !== void 0) body.image_prompt_strength = imagePromptStrength;
|
|
2864
|
-
if (model === "flux") {
|
|
2865
|
-
if (safetyTolerance !== void 0 && safetyTolerance !== "") body.safety_tolerance = safetyTolerance;
|
|
2866
|
-
}
|
|
2867
2246
|
if (config.supportsGuidanceScale === true && guidanceScale !== void 0) body.guidance_scale = guidanceScale;
|
|
2868
2247
|
if (config.supportsInferenceSteps === true && numInferenceSteps !== void 0) body.num_inference_steps = numInferenceSteps;
|
|
2869
2248
|
if (config.supportsSafetyTolerance === true) {
|
|
@@ -2884,25 +2263,17 @@ function buildGenerateBody(options) {
|
|
|
2884
2263
|
if (config.supportsThinkingLevel === true) {
|
|
2885
2264
|
if (thinkingLevel) body.thinking_level = thinkingLevel;
|
|
2886
2265
|
}
|
|
2887
|
-
if (config.supportsStyle === true && style !== void 0 && style !== "") body.style = style;
|
|
2888
2266
|
if (config.supportsNegativePrompt === true) {
|
|
2889
2267
|
if (negativePrompt !== void 0 && negativePrompt !== "") body.negative_prompt = negativePrompt;
|
|
2890
2268
|
}
|
|
2891
|
-
if (model === "ideogram") {
|
|
2892
|
-
if (style !== void 0 && style !== "") body.style = style;
|
|
2893
|
-
}
|
|
2894
2269
|
if (config.supportsRenderingSpeed === true) {
|
|
2895
2270
|
if (renderingSpeed) body.rendering_speed = renderingSpeed;
|
|
2896
2271
|
}
|
|
2897
2272
|
if (config.supportsExpandPrompt === true) {
|
|
2898
2273
|
if (expandPrompt !== void 0) body.expand_prompt = expandPrompt;
|
|
2899
2274
|
}
|
|
2900
|
-
if (model === "flux" && hasEditImages) {
|
|
2901
|
-
body.image_url = editImages[0];
|
|
2902
|
-
body.image_prompt_strength = imagePromptStrength ?? .5;
|
|
2903
|
-
}
|
|
2904
2275
|
if (config.supportsNumImages) body.num_images = numImages;
|
|
2905
|
-
if (hasEditImages && sizeMode !== "gpt_size"
|
|
2276
|
+
if (hasEditImages && sizeMode !== "gpt_size") {
|
|
2906
2277
|
if (!config.supportsEdit) throw new Error(`Model ${model} does not support image editing`);
|
|
2907
2278
|
endpoint = config.editEndpoint ?? `${endpoint}/edit`;
|
|
2908
2279
|
const editImagesField = config.editImagesField ?? "image_urls";
|
|
@@ -4691,100 +4062,6 @@ var FalClient = class {
|
|
|
4691
4062
|
const data = await response.value.json();
|
|
4692
4063
|
return this.normalizeResponse(data, requestId);
|
|
4693
4064
|
}
|
|
4694
|
-
/** ─── Processing ──────────────────────────────────────────── */
|
|
4695
|
-
/** Upscale an image using clarity or crystal upscaler. */
|
|
4696
|
-
async upscale(options) {
|
|
4697
|
-
const { imageUrl, model = "clarity", scaleFactor, creativity, resemblance, prompt: upscalePrompt, negativePrompt, numInferenceSteps, guidanceScale } = options;
|
|
4698
|
-
const config = MODELS[model];
|
|
4699
|
-
if (!config || config.type !== "utility") return (0, neverthrow.err)(new MotifError(`Invalid upscale model: ${model}`, 0));
|
|
4700
|
-
const body = { image_url: imageUrl };
|
|
4701
|
-
if (model === "crystal") {
|
|
4702
|
-
if (scaleFactor !== void 0) body.scale_factor = scaleFactor;
|
|
4703
|
-
if (creativity !== void 0) body.creativity = creativity;
|
|
4704
|
-
} else {
|
|
4705
|
-
if (scaleFactor !== void 0) body.upscale_factor = scaleFactor;
|
|
4706
|
-
if (creativity !== void 0) body.creativity = creativity;
|
|
4707
|
-
if (resemblance !== void 0) body.resemblance = resemblance;
|
|
4708
|
-
if (upscalePrompt !== void 0 && upscalePrompt !== "") body.prompt = upscalePrompt;
|
|
4709
|
-
if (negativePrompt !== void 0 && negativePrompt !== "") body.negative_prompt = negativePrompt;
|
|
4710
|
-
if (numInferenceSteps !== void 0) body.num_inference_steps = numInferenceSteps;
|
|
4711
|
-
if (guidanceScale !== void 0) body.guidance_scale = guidanceScale;
|
|
4712
|
-
}
|
|
4713
|
-
const response = await this.request(`${FAL_BASE_URL}/${config.endpoint}`, {
|
|
4714
|
-
body: JSON.stringify(body),
|
|
4715
|
-
method: "POST"
|
|
4716
|
-
});
|
|
4717
|
-
if (response.isErr()) return (0, neverthrow.err)(response.error);
|
|
4718
|
-
const data = await response.value.json();
|
|
4719
|
-
return this.normalizeResponse(data);
|
|
4720
|
-
}
|
|
4721
|
-
/** Remove the background from an image. */
|
|
4722
|
-
async removeBackground(options) {
|
|
4723
|
-
const { imageUrl, model = "rmbg", variant, operatingResolution, outputFormat, refineForeground, outputMask } = options;
|
|
4724
|
-
const config = MODELS[model];
|
|
4725
|
-
if (!config) return (0, neverthrow.err)(new MotifError(`Invalid background removal model: ${model}`, 0));
|
|
4726
|
-
const rbBody = { image_url: imageUrl };
|
|
4727
|
-
if (model === "rmbg") {
|
|
4728
|
-
if (variant) rbBody.model = variant;
|
|
4729
|
-
if (operatingResolution) rbBody.operating_resolution = operatingResolution;
|
|
4730
|
-
if (outputFormat) rbBody.output_format = outputFormat;
|
|
4731
|
-
if (refineForeground !== void 0) rbBody.refine_foreground = refineForeground;
|
|
4732
|
-
if (outputMask !== void 0) rbBody.output_mask = outputMask;
|
|
4733
|
-
}
|
|
4734
|
-
const response = await this.request(`${FAL_BASE_URL}/${config.endpoint}`, {
|
|
4735
|
-
body: JSON.stringify(rbBody),
|
|
4736
|
-
method: "POST"
|
|
4737
|
-
});
|
|
4738
|
-
if (response.isErr()) return (0, neverthrow.err)(response.error);
|
|
4739
|
-
const data = await response.value.json();
|
|
4740
|
-
return this.normalizeResponse(data);
|
|
4741
|
-
}
|
|
4742
|
-
/** ─── Video Generation ───────────────────────────────────── */
|
|
4743
|
-
/**
|
|
4744
|
-
* Generate a video from an image using Kling v3 Pro.
|
|
4745
|
-
* This uses the queue API since video generation takes 30-120s.
|
|
4746
|
-
* Returns immediately with a job — poll with getJobStatus/getVideoResult.
|
|
4747
|
-
*/
|
|
4748
|
-
async submitVideo(options) {
|
|
4749
|
-
const { imageUrl, prompt, duration = 5, generateAudio = true, endImageUrl, negativePrompt, cfgScale } = options;
|
|
4750
|
-
const config = MODELS.kling;
|
|
4751
|
-
if (!config) return (0, neverthrow.err)(new MotifError("Kling video model not found", 0));
|
|
4752
|
-
const body = {
|
|
4753
|
-
duration: String(duration),
|
|
4754
|
-
generate_audio: generateAudio,
|
|
4755
|
-
prompt,
|
|
4756
|
-
start_image_url: imageUrl
|
|
4757
|
-
};
|
|
4758
|
-
if (endImageUrl !== void 0 && endImageUrl !== "") body.end_image_url = endImageUrl;
|
|
4759
|
-
if (negativePrompt !== void 0 && negativePrompt !== "") body.negative_prompt = negativePrompt;
|
|
4760
|
-
if (cfgScale !== void 0) body.cfg_scale = cfgScale;
|
|
4761
|
-
const response = await this.request(`${FAL_QUEUE_URL}/${config.endpoint}`, {
|
|
4762
|
-
body: JSON.stringify(body),
|
|
4763
|
-
method: "POST"
|
|
4764
|
-
});
|
|
4765
|
-
if (response.isErr()) return (0, neverthrow.err)(response.error);
|
|
4766
|
-
const submission = parseQueueSubmission(await response.value.json());
|
|
4767
|
-
return (0, neverthrow.ok)({
|
|
4768
|
-
endpoint: endpointFromQueueUrl(submission.responseUrl, config.endpoint),
|
|
4769
|
-
estimatedCost: estimateVideoCost(duration, generateAudio),
|
|
4770
|
-
requestId: submission.requestId
|
|
4771
|
-
});
|
|
4772
|
-
}
|
|
4773
|
-
/** Fetch the completed video result from the queue. */
|
|
4774
|
-
async getVideoResult(endpoint, requestId) {
|
|
4775
|
-
const url = `${FAL_QUEUE_URL}/${endpoint}/requests/${requestId}`;
|
|
4776
|
-
const response = await this.request(url);
|
|
4777
|
-
if (response.isErr()) return (0, neverthrow.err)(response.error);
|
|
4778
|
-
const data = await response.value.json();
|
|
4779
|
-
const video = isRecord$1(data) && isRecord$1(data.video) ? data.video : void 0;
|
|
4780
|
-
if (video === void 0) return (0, neverthrow.err)(new MotifError("No video in response", 0));
|
|
4781
|
-
return (0, neverthrow.ok)({
|
|
4782
|
-
contentType: asString(video.content_type) ?? "",
|
|
4783
|
-
fileName: asString(video.file_name) ?? "",
|
|
4784
|
-
fileSize: asNumber(video.file_size) ?? 0,
|
|
4785
|
-
url: asString(video.url) ?? ""
|
|
4786
|
-
});
|
|
4787
|
-
}
|
|
4788
4065
|
/** ─── File Upload ─────────────────────────────────────────── */
|
|
4789
4066
|
/**
|
|
4790
4067
|
* Upload a file to fal.ai CDN storage and return the public URL.
|
|
@@ -4880,10 +4157,6 @@ var FalClient = class {
|
|
|
4880
4157
|
get generationModels() {
|
|
4881
4158
|
return GENERATION_MODELS;
|
|
4882
4159
|
}
|
|
4883
|
-
/** Utility model keys. */
|
|
4884
|
-
get utilityModels() {
|
|
4885
|
-
return UTILITY_MODELS;
|
|
4886
|
-
}
|
|
4887
4160
|
/** Registered fal utility/tool endpoints. */
|
|
4888
4161
|
get tools() {
|
|
4889
4162
|
return FAL_TOOLS;
|
|
@@ -5815,7 +5088,7 @@ const TASKS = {
|
|
|
5815
5088
|
summary: "Remove an object, person, text or clutter from an image and fill the gap."
|
|
5816
5089
|
},
|
|
5817
5090
|
generate: {
|
|
5818
|
-
basis: "Order follows Arena text-to-image (https://arena.ai/leaderboard/image/text-to-image), read 2026-10-29
|
|
5091
|
+
basis: "Order follows Arena text-to-image (https://arena.ai/leaderboard/image/text-to-image), read 2026-10-29. Sunburst and Flare lead quality at the benchmarked max setting. Balanced starts with Nano Banana 2.1 on preliminary Arena evidence, then Grok Image 2 and Muse Image. Models not yet on the board follow the ranked ones in their Tier, in their previous order. The Artificial Analysis v2 snapshot of 2026-10-07 stays as recorded benchmark data. Fast keeps Nano Banana 2 Lite, budget Grok and Seedream 5 Lite, and FLUX.2 Turbo. Design, transparency and tuned Look routes are capability exceptions. Generation with References uses the separate editing ranking. Older routes are explicit/pin/Look-only.",
|
|
5819
5092
|
models: GENERATION_MODELS_RANKED,
|
|
5820
5093
|
notFor: "Variations of an image you already have (vary), or a consistent set of images (series run).",
|
|
5821
5094
|
rankedAt: IMAGE_RANKED_AT,
|
|
@@ -6303,7 +5576,7 @@ const TASKS = {
|
|
|
6303
5576
|
summary: "Trace a raster image to a clean SVG."
|
|
6304
5577
|
},
|
|
6305
5578
|
vary: {
|
|
6306
|
-
basis: "Order follows Arena image edit, single image (https://arena.ai/leaderboard/image/image-edit/single-image), read 2026-10-29
|
|
5579
|
+
basis: "Order follows Arena image edit, single image (https://arena.ai/leaderboard/image/image-edit/single-image), read 2026-10-29. Editing order differs from generation: Grok Image 2 leads balanced, ahead of Nano Banana 2.1, and Seedream 5 Pro outranks GPT Image 1.5. Arena scores Krea 3 only at its Ultra setting, which costs $0.27 to $0.35 an edit and ignores the requested size, so krea3, which runs fal's default setting, is ranked as unscored. Models not yet on the board follow the ranked ones in their Tier, in their previous order. The Artificial Analysis v2 snapshot of 2026-10-07 stays as recorded benchmark data. Sunburst and Flare use max quality. vary reuses a previously chosen Model when explicitly supplied, including retained legacy routes.",
|
|
6307
5580
|
models: EDITING_MODELS_RANKED,
|
|
6308
5581
|
notFor: "A specific change to an image described in words (generate with a reference), or a set of different scenes in one style (series run).",
|
|
6309
5582
|
rankedAt: IMAGE_RANKED_AT,
|
|
@@ -8683,7 +7956,7 @@ function resolveFixed(task, fixed, request, needed, keys) {
|
|
|
8683
7956
|
const { chosenBy, model } = fixed;
|
|
8684
7957
|
const tier = request.tier ?? "balanced";
|
|
8685
7958
|
const entries = TASKS[task].models;
|
|
8686
|
-
const entry = entries.find((candidate) => candidate.model === model && candidate.mode === request.mode)
|
|
7959
|
+
const entry = entries.find((candidate) => candidate.model === model && candidate.mode === request.mode);
|
|
8687
7960
|
const profile = modelProfile(model);
|
|
8688
7961
|
if (entry === void 0 || profile === void 0) {
|
|
8689
7962
|
const servesTask = entries.some((candidate) => candidate.model === model);
|
|
@@ -8696,14 +7969,6 @@ function resolveFixed(task, fixed, request, needed, keys) {
|
|
|
8696
7969
|
unblockers.push(unblockerFor(result));
|
|
8697
7970
|
return unresolved(task, result.blockedBy, unblockers, `${model} (${chosenBy}) ${describeBlock(result.blockedBy, request, result.missingKey, result.missingInput)}.`, result.missingKey);
|
|
8698
7971
|
}
|
|
8699
|
-
/** Old pins and tuned Looks remain usable without recommending predecessors. */
|
|
8700
|
-
function legacyEntry(task, model, mode, tier) {
|
|
8701
|
-
if (mode !== void 0 || task !== "generate" && task !== "vary" || !LEGACY_GENERATION_MODELS.some((id) => id === model) || task === "vary" && MODELS[model]?.supportsEdit !== true) return;
|
|
8702
|
-
return {
|
|
8703
|
-
model,
|
|
8704
|
-
tier
|
|
8705
|
-
};
|
|
8706
|
-
}
|
|
8707
7972
|
function unknownForMode(task, model, mode, entries) {
|
|
8708
7973
|
const otherModes = entries.filter((candidate) => candidate.model === model).map((candidate) => candidate.mode ?? "no mode");
|
|
8709
7974
|
const inMode = [...new Set(entries.filter((candidate) => candidate.mode === mode).map((candidate) => candidate.model))];
|