@howells/motif-sdk 1.1.0 → 1.3.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/dist/image.d.ts +8 -0
- package/dist/image.js +1071 -199
- package/dist/index.cjs +2054 -417
- package/dist/index.d.cts +2461 -402
- package/dist/index.d.ts +2461 -402
- package/dist/index.js +2043 -416
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(src_exports, {
|
|
|
28
28
|
FAL_TOOLS: () => FAL_TOOLS,
|
|
29
29
|
FAL_TOOLS_CHECKED_AT: () => FAL_TOOLS_CHECKED_AT,
|
|
30
30
|
FAL_TOOL_IDS: () => FAL_TOOL_IDS,
|
|
31
|
+
FAL_TOOL_PARAMETERS: () => FAL_TOOL_PARAMETERS,
|
|
31
32
|
FORMAT_PRESETS: () => FORMAT_PRESETS,
|
|
32
33
|
FalClient: () => FalClient,
|
|
33
34
|
GENERATION_MODELS: () => GENERATION_MODELS,
|
|
@@ -35,6 +36,7 @@ __export(src_exports, {
|
|
|
35
36
|
IMAGE_EDITING_TOP_20: () => IMAGE_EDITING_TOP_20,
|
|
36
37
|
IMAGE_TEXT_TO_IMAGE_TOP_20: () => IMAGE_TEXT_TO_IMAGE_TOP_20,
|
|
37
38
|
MODELS: () => MODELS,
|
|
39
|
+
MODEL_OUTPUT: () => MODEL_OUTPUT,
|
|
38
40
|
MotifError: () => MotifError,
|
|
39
41
|
RECRAFT_STYLES: () => RECRAFT_STYLES,
|
|
40
42
|
RESOLUTIONS: () => RESOLUTIONS,
|
|
@@ -46,19 +48,27 @@ __export(src_exports, {
|
|
|
46
48
|
aspectToGptSize: () => aspectToGptSize,
|
|
47
49
|
buildFalToolRequest: () => buildFalToolRequest,
|
|
48
50
|
buildGenerateBody: () => buildGenerateBody,
|
|
51
|
+
describeModelOutput: () => describeModelOutput,
|
|
49
52
|
enrichPrompt: () => enrichPrompt,
|
|
50
|
-
err: () =>
|
|
53
|
+
err: () => import_neverthrow3.err,
|
|
51
54
|
estimateCost: () => estimateCost,
|
|
52
55
|
estimateVideoCost: () => estimateVideoCost,
|
|
56
|
+
falToolParameters: () => falToolParameters,
|
|
57
|
+
formatCost: () => formatCost,
|
|
53
58
|
getFalKeyFromEnv: () => getFalKeyFromEnv,
|
|
54
59
|
isFalToolId: () => isFalToolId,
|
|
60
|
+
losslessAvailability: () => losslessAvailability,
|
|
61
|
+
measuredToolCost: () => measuredToolCost,
|
|
62
|
+
modelOutput: () => modelOutput,
|
|
55
63
|
motifEnvSchema: () => motifEnvSchema,
|
|
56
|
-
ok: () =>
|
|
64
|
+
ok: () => import_neverthrow3.ok,
|
|
57
65
|
parseMotifEnv: () => parseMotifEnv,
|
|
58
|
-
|
|
66
|
+
projectedToolCost: () => projectedToolCost,
|
|
67
|
+
sanitizePrompt: () => sanitizePrompt,
|
|
68
|
+
sumCosts: () => sumCosts
|
|
59
69
|
});
|
|
60
70
|
module.exports = __toCommonJS(src_exports);
|
|
61
|
-
var
|
|
71
|
+
var import_neverthrow3 = require("neverthrow");
|
|
62
72
|
|
|
63
73
|
// src/aspects.ts
|
|
64
74
|
var ASPECT_RATIOS = [
|
|
@@ -158,22 +168,23 @@ var FORMAT_PRESETS = {
|
|
|
158
168
|
};
|
|
159
169
|
|
|
160
170
|
// src/models.ts
|
|
161
|
-
var AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-
|
|
171
|
+
var AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-08-23";
|
|
162
172
|
var AA_IMAGE_SOURCES = [
|
|
163
173
|
"https://artificialanalysis.ai/image/leaderboard/text-to-image",
|
|
164
174
|
"https://artificialanalysis.ai/image/leaderboard/editing"
|
|
165
175
|
];
|
|
166
176
|
var FAL_PRICING_CHECKED_AT = "2026-05-12";
|
|
167
177
|
var FAL_PRICING_CHECKED_JUL_2026 = "2026-07-11";
|
|
178
|
+
var FAL_PRICING_CHECKED_AUG_2026 = "2026-08-23";
|
|
168
179
|
var MODELS = {
|
|
169
180
|
// ─── Generation Models ────────────────────────────────────────
|
|
170
181
|
gpt2: {
|
|
171
182
|
benchmark: {
|
|
172
183
|
artificialAnalysis: {
|
|
173
|
-
editing: { elo:
|
|
184
|
+
editing: { elo: 1256, rank: 3 },
|
|
174
185
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
175
186
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
176
|
-
textToImage: { elo:
|
|
187
|
+
textToImage: { elo: 1369, rank: 1 }
|
|
177
188
|
},
|
|
178
189
|
speed: {
|
|
179
190
|
medianSeconds: 200.7,
|
|
@@ -213,10 +224,10 @@ var MODELS = {
|
|
|
213
224
|
gpt: {
|
|
214
225
|
benchmark: {
|
|
215
226
|
artificialAnalysis: {
|
|
216
|
-
editing: { elo:
|
|
227
|
+
editing: { elo: 1250, rank: 5 },
|
|
217
228
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
218
229
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
219
|
-
textToImage: { elo:
|
|
230
|
+
textToImage: { elo: 1310, rank: 4 }
|
|
220
231
|
},
|
|
221
232
|
speed: {
|
|
222
233
|
medianSeconds: 34.6,
|
|
@@ -256,10 +267,10 @@ var MODELS = {
|
|
|
256
267
|
banana2: {
|
|
257
268
|
benchmark: {
|
|
258
269
|
artificialAnalysis: {
|
|
259
|
-
editing: { elo:
|
|
270
|
+
editing: { elo: 1249, rank: 7 },
|
|
260
271
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
261
272
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
262
|
-
textToImage: { elo:
|
|
273
|
+
textToImage: { elo: 1320, rank: 3 }
|
|
263
274
|
},
|
|
264
275
|
tiers: { price: "premium", quality: "frontier", speed: "unknown" },
|
|
265
276
|
useCase: "Best balance of quality, edit support, web search, and cost"
|
|
@@ -297,10 +308,10 @@ var MODELS = {
|
|
|
297
308
|
banana: {
|
|
298
309
|
benchmark: {
|
|
299
310
|
artificialAnalysis: {
|
|
300
|
-
editing: { elo:
|
|
311
|
+
editing: { elo: 1245, rank: 9 },
|
|
301
312
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
302
313
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
303
|
-
textToImage: { elo:
|
|
314
|
+
textToImage: { elo: 1297, rank: 6 }
|
|
304
315
|
},
|
|
305
316
|
speed: {
|
|
306
317
|
medianSeconds: 19.2,
|
|
@@ -340,6 +351,13 @@ var MODELS = {
|
|
|
340
351
|
type: "generation"
|
|
341
352
|
},
|
|
342
353
|
gemini: {
|
|
354
|
+
benchmark: {
|
|
355
|
+
artificialAnalysis: {
|
|
356
|
+
editing: { elo: 1180, rank: 29 },
|
|
357
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
358
|
+
sourceUrls: AA_IMAGE_SOURCES
|
|
359
|
+
}
|
|
360
|
+
},
|
|
343
361
|
editEndpoint: "fal-ai/gemini-25-flash-image/edit",
|
|
344
362
|
endpoint: "fal-ai/gemini-25-flash-image",
|
|
345
363
|
falPricing: {
|
|
@@ -367,6 +385,14 @@ var MODELS = {
|
|
|
367
385
|
type: "generation"
|
|
368
386
|
},
|
|
369
387
|
gemini3: {
|
|
388
|
+
benchmark: {
|
|
389
|
+
artificialAnalysis: {
|
|
390
|
+
editing: { elo: 1245, rank: 9 },
|
|
391
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
392
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
393
|
+
textToImage: { elo: 1297, rank: 6 }
|
|
394
|
+
}
|
|
395
|
+
},
|
|
370
396
|
editEndpoint: "fal-ai/gemini-3-pro-image-preview/edit",
|
|
371
397
|
endpoint: "fal-ai/gemini-3-pro-image-preview",
|
|
372
398
|
falPricing: {
|
|
@@ -397,10 +423,10 @@ var MODELS = {
|
|
|
397
423
|
seedream4: {
|
|
398
424
|
benchmark: {
|
|
399
425
|
artificialAnalysis: {
|
|
400
|
-
editing: { elo:
|
|
426
|
+
editing: { elo: 1185, rank: 28 },
|
|
401
427
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
402
428
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
403
|
-
textToImage: { elo:
|
|
429
|
+
textToImage: { elo: 1226, rank: 16 }
|
|
404
430
|
},
|
|
405
431
|
speed: {
|
|
406
432
|
medianSeconds: 14.3,
|
|
@@ -437,10 +463,10 @@ var MODELS = {
|
|
|
437
463
|
seedream45: {
|
|
438
464
|
benchmark: {
|
|
439
465
|
artificialAnalysis: {
|
|
440
|
-
editing: { elo:
|
|
466
|
+
editing: { elo: 1186, rank: 26 },
|
|
441
467
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
442
468
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
443
|
-
textToImage: { elo:
|
|
469
|
+
textToImage: { elo: 1203, rank: 32 }
|
|
444
470
|
},
|
|
445
471
|
speed: {
|
|
446
472
|
medianSeconds: 18.2,
|
|
@@ -475,6 +501,14 @@ var MODELS = {
|
|
|
475
501
|
type: "generation"
|
|
476
502
|
},
|
|
477
503
|
seedream5: {
|
|
504
|
+
benchmark: {
|
|
505
|
+
artificialAnalysis: {
|
|
506
|
+
editing: { elo: 1248, rank: 8 },
|
|
507
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
508
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
509
|
+
textToImage: { elo: 1279, rank: 10 }
|
|
510
|
+
}
|
|
511
|
+
},
|
|
478
512
|
name: "Seedream 5.0 Pro",
|
|
479
513
|
endpoint: "bytedance/seedream/v5/pro/text-to-image",
|
|
480
514
|
editEndpoint: "bytedance/seedream/v5/pro/edit",
|
|
@@ -501,6 +535,13 @@ var MODELS = {
|
|
|
501
535
|
maxReferenceImages: 10
|
|
502
536
|
},
|
|
503
537
|
"seedream5-lite": {
|
|
538
|
+
benchmark: {
|
|
539
|
+
artificialAnalysis: {
|
|
540
|
+
editing: { elo: 1169, rank: 32 },
|
|
541
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
542
|
+
sourceUrls: AA_IMAGE_SOURCES
|
|
543
|
+
}
|
|
544
|
+
},
|
|
504
545
|
name: "Seedream 5.0 Lite",
|
|
505
546
|
endpoint: "fal-ai/bytedance/seedream/v5/lite/text-to-image",
|
|
506
547
|
editEndpoint: "fal-ai/bytedance/seedream/v5/lite/edit",
|
|
@@ -529,10 +570,10 @@ var MODELS = {
|
|
|
529
570
|
"flux2-max": {
|
|
530
571
|
benchmark: {
|
|
531
572
|
artificialAnalysis: {
|
|
532
|
-
editing: { elo:
|
|
573
|
+
editing: { elo: 1201, rank: 19 },
|
|
533
574
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
534
575
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
535
|
-
textToImage: { elo:
|
|
576
|
+
textToImage: { elo: 1225, rank: 17 }
|
|
536
577
|
},
|
|
537
578
|
speed: {
|
|
538
579
|
medianSeconds: 31.6,
|
|
@@ -572,10 +613,10 @@ var MODELS = {
|
|
|
572
613
|
"flux2-pro": {
|
|
573
614
|
benchmark: {
|
|
574
615
|
artificialAnalysis: {
|
|
575
|
-
editing: { elo: 1170,
|
|
616
|
+
editing: { elo: 1170, rank: 31 },
|
|
576
617
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
577
618
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
578
|
-
textToImage: { elo:
|
|
619
|
+
textToImage: { elo: 1207, rank: 30 }
|
|
579
620
|
},
|
|
580
621
|
speed: {
|
|
581
622
|
medianSeconds: 16.1,
|
|
@@ -615,10 +656,9 @@ var MODELS = {
|
|
|
615
656
|
"flux2-flex": {
|
|
616
657
|
benchmark: {
|
|
617
658
|
artificialAnalysis: {
|
|
618
|
-
editing: { elo: 1161, pricePer1k: 60, rank: 22 },
|
|
619
659
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
620
660
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
621
|
-
textToImage: { elo:
|
|
661
|
+
textToImage: { elo: 1223, rank: 18 }
|
|
622
662
|
},
|
|
623
663
|
speed: {
|
|
624
664
|
medianSeconds: 15.3,
|
|
@@ -662,8 +702,7 @@ var MODELS = {
|
|
|
662
702
|
benchmark: {
|
|
663
703
|
artificialAnalysis: {
|
|
664
704
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
665
|
-
sourceUrls: AA_IMAGE_SOURCES
|
|
666
|
-
textToImage: { elo: 1160, pricePer1k: 12, rank: 19, winRate: 0.57 }
|
|
705
|
+
sourceUrls: AA_IMAGE_SOURCES
|
|
667
706
|
},
|
|
668
707
|
speed: {
|
|
669
708
|
medianSeconds: 4.6,
|
|
@@ -806,7 +845,55 @@ var MODELS = {
|
|
|
806
845
|
supportsSyncMode: true,
|
|
807
846
|
type: "generation"
|
|
808
847
|
},
|
|
848
|
+
reve: {
|
|
849
|
+
benchmark: {
|
|
850
|
+
artificialAnalysis: {
|
|
851
|
+
// #2 on BOTH boards, which almost nothing else manages - the top text-to-image model
|
|
852
|
+
// (GPT Image 2) drops to 3rd for editing, and the top editor (MAI-Image-2.5-Pro) is not
|
|
853
|
+
// on fal at all. Reve is the best editor motif can actually reach.
|
|
854
|
+
editing: { elo: 1263, rank: 2 },
|
|
855
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
856
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
857
|
+
textToImage: { elo: 1322, rank: 2 }
|
|
858
|
+
},
|
|
859
|
+
tiers: { price: "premium", quality: "frontier", speed: "unknown" },
|
|
860
|
+
useCase: "Highest-ranked editor reachable on fal; strong prompt adherence and text rendering"
|
|
861
|
+
},
|
|
862
|
+
editEndpoint: "fal-ai/reve/edit",
|
|
863
|
+
endpoint: "fal-ai/reve/text-to-image",
|
|
864
|
+
falPricing: {
|
|
865
|
+
checkedAt: FAL_PRICING_CHECKED_AUG_2026,
|
|
866
|
+
currency: "USD",
|
|
867
|
+
endpointId: "fal-ai/reve/text-to-image",
|
|
868
|
+
estimatedCostPerImageUsd: 0.04,
|
|
869
|
+
source: "fal-pricing-api",
|
|
870
|
+
unit: "images",
|
|
871
|
+
unitPrice: 0.04
|
|
872
|
+
},
|
|
873
|
+
maxReferenceImages: 1,
|
|
874
|
+
name: "Reve 2.1",
|
|
875
|
+
pricePerImageUsd: 0.04,
|
|
876
|
+
pricing: "$0.04",
|
|
877
|
+
// fal's schema takes aspect_ratio from a fixed set and has no width/height or resolution
|
|
878
|
+
// parameter, so aspect is supported and resolution is not.
|
|
879
|
+
sizeMode: "aspect_ratio",
|
|
880
|
+
supportsAspect: true,
|
|
881
|
+
supportsEdit: true,
|
|
882
|
+
supportsNumImages: true,
|
|
883
|
+
supportsOutputFormat: true,
|
|
884
|
+
supportsResolution: false,
|
|
885
|
+
supportsSeed: false,
|
|
886
|
+
supportsSyncMode: true,
|
|
887
|
+
type: "generation"
|
|
888
|
+
},
|
|
809
889
|
recraft4: {
|
|
890
|
+
benchmark: {
|
|
891
|
+
artificialAnalysis: {
|
|
892
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
893
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
894
|
+
textToImage: { elo: 1215, rank: 25 }
|
|
895
|
+
}
|
|
896
|
+
},
|
|
810
897
|
endpoint: "fal-ai/recraft/v4/text-to-image",
|
|
811
898
|
falPricing: {
|
|
812
899
|
checkedAt: FAL_PRICING_CHECKED_JUL_2026,
|
|
@@ -857,6 +944,13 @@ var MODELS = {
|
|
|
857
944
|
type: "generation"
|
|
858
945
|
},
|
|
859
946
|
ideogram4: {
|
|
947
|
+
benchmark: {
|
|
948
|
+
artificialAnalysis: {
|
|
949
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
950
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
951
|
+
textToImage: { elo: 1220, rank: 19 }
|
|
952
|
+
}
|
|
953
|
+
},
|
|
860
954
|
name: "Ideogram V4",
|
|
861
955
|
endpoint: "ideogram/v4",
|
|
862
956
|
type: "generation",
|
|
@@ -889,10 +983,10 @@ var MODELS = {
|
|
|
889
983
|
"grok-image": {
|
|
890
984
|
benchmark: {
|
|
891
985
|
artificialAnalysis: {
|
|
892
|
-
editing: { elo:
|
|
986
|
+
editing: { elo: 1214, rank: 16 },
|
|
893
987
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
894
988
|
sourceUrls: AA_IMAGE_SOURCES,
|
|
895
|
-
textToImage: { elo:
|
|
989
|
+
textToImage: { elo: 1216, rank: 23 }
|
|
896
990
|
},
|
|
897
991
|
speed: {
|
|
898
992
|
medianSeconds: 5.1,
|
|
@@ -930,8 +1024,7 @@ var MODELS = {
|
|
|
930
1024
|
benchmark: {
|
|
931
1025
|
artificialAnalysis: {
|
|
932
1026
|
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
933
|
-
sourceUrls: AA_IMAGE_SOURCES
|
|
934
|
-
textToImage: { elo: 1158, pricePer1k: 20, rank: 20, winRate: 0.6 }
|
|
1027
|
+
sourceUrls: AA_IMAGE_SOURCES
|
|
935
1028
|
},
|
|
936
1029
|
speed: {
|
|
937
1030
|
medianSeconds: 23.3,
|
|
@@ -966,8 +1059,14 @@ var MODELS = {
|
|
|
966
1059
|
},
|
|
967
1060
|
qwen3: {
|
|
968
1061
|
benchmark: {
|
|
1062
|
+
artificialAnalysis: {
|
|
1063
|
+
editing: { elo: 1218, rank: 15 },
|
|
1064
|
+
snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
|
|
1065
|
+
sourceUrls: AA_IMAGE_SOURCES,
|
|
1066
|
+
textToImage: { elo: 1272, rank: 11 }
|
|
1067
|
+
},
|
|
969
1068
|
tiers: { price: "budget", quality: "better", speed: "unknown" },
|
|
970
|
-
useCase: "
|
|
1069
|
+
useCase: "Strong quality per dollar - 11th on text-to-image at $30/1k"
|
|
971
1070
|
},
|
|
972
1071
|
endpoint: "fal-ai/qwen-image-3/text-to-image",
|
|
973
1072
|
falPricing: {
|
|
@@ -1392,7 +1491,7 @@ function validateGenerateOptions(options, config, sizeMode, hasEditImages) {
|
|
|
1392
1491
|
if (options.background !== void 0 && config.supportsBackground !== true) {
|
|
1393
1492
|
unsupported(config, "background");
|
|
1394
1493
|
}
|
|
1395
|
-
if (options.transparent === true &&
|
|
1494
|
+
if (options.transparent === true && config.supportsBackground !== true) {
|
|
1396
1495
|
unsupported(config, "transparent output");
|
|
1397
1496
|
}
|
|
1398
1497
|
if (options.inputFidelity !== void 0) {
|
|
@@ -1674,353 +1773,351 @@ function buildGenerateBody(options) {
|
|
|
1674
1773
|
|
|
1675
1774
|
// src/leaderboards.ts
|
|
1676
1775
|
var IMAGE_TEXT_TO_IMAGE_TOP_20 = {
|
|
1677
|
-
capturedAt: "2026-
|
|
1776
|
+
capturedAt: "2026-08-23",
|
|
1678
1777
|
entries: [
|
|
1679
1778
|
{
|
|
1680
1779
|
apiPricing: "$211/1k images",
|
|
1681
1780
|
creator: "OpenAI",
|
|
1682
|
-
elo:
|
|
1781
|
+
elo: 1369,
|
|
1683
1782
|
isCurrent: true,
|
|
1684
1783
|
model: "GPT Image 2 (high)",
|
|
1685
1784
|
rank: 1,
|
|
1686
1785
|
routableModelId: "gpt2"
|
|
1687
1786
|
},
|
|
1688
1787
|
{
|
|
1689
|
-
apiPricing: "$
|
|
1690
|
-
creator: "
|
|
1691
|
-
elo:
|
|
1788
|
+
apiPricing: "$200/1k images",
|
|
1789
|
+
creator: "Reve",
|
|
1790
|
+
elo: 1322,
|
|
1692
1791
|
isCurrent: true,
|
|
1693
|
-
model: "
|
|
1792
|
+
model: "Reve 2.1",
|
|
1694
1793
|
rank: 2,
|
|
1695
|
-
routableModelId: "
|
|
1794
|
+
routableModelId: "reve"
|
|
1696
1795
|
},
|
|
1697
1796
|
{
|
|
1698
1797
|
apiPricing: "$67/1k images",
|
|
1699
1798
|
creator: "Google",
|
|
1700
|
-
elo:
|
|
1799
|
+
elo: 1320,
|
|
1701
1800
|
isCurrent: true,
|
|
1702
1801
|
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1703
1802
|
rank: 3,
|
|
1704
1803
|
routableModelId: "banana2"
|
|
1705
1804
|
},
|
|
1706
1805
|
{
|
|
1707
|
-
apiPricing: "$
|
|
1708
|
-
creator: "
|
|
1709
|
-
elo:
|
|
1806
|
+
apiPricing: "$133/1k images",
|
|
1807
|
+
creator: "OpenAI",
|
|
1808
|
+
elo: 1310,
|
|
1710
1809
|
isCurrent: true,
|
|
1711
|
-
model: "
|
|
1712
|
-
rank: 4
|
|
1810
|
+
model: "GPT Image 1.5 (high)",
|
|
1811
|
+
rank: 4,
|
|
1812
|
+
routableModelId: "gpt"
|
|
1713
1813
|
},
|
|
1714
1814
|
{
|
|
1715
|
-
apiPricing: "$
|
|
1716
|
-
creator: "
|
|
1717
|
-
elo:
|
|
1815
|
+
apiPricing: "$48/1k images",
|
|
1816
|
+
creator: "Microsoft AI",
|
|
1817
|
+
elo: 1305,
|
|
1718
1818
|
isCurrent: true,
|
|
1719
|
-
model: "
|
|
1720
|
-
rank: 5
|
|
1721
|
-
routableModelId: "banana"
|
|
1819
|
+
model: "MAI-Image-2.5",
|
|
1820
|
+
rank: 5
|
|
1722
1821
|
},
|
|
1723
1822
|
{
|
|
1724
|
-
apiPricing: "$
|
|
1725
|
-
creator: "
|
|
1726
|
-
elo:
|
|
1823
|
+
apiPricing: "$134/1k images",
|
|
1824
|
+
creator: "Google",
|
|
1825
|
+
elo: 1297,
|
|
1727
1826
|
isCurrent: true,
|
|
1728
|
-
model: "
|
|
1827
|
+
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
1729
1828
|
rank: 6,
|
|
1730
|
-
routableModelId: "
|
|
1829
|
+
routableModelId: "banana"
|
|
1731
1830
|
},
|
|
1732
1831
|
{
|
|
1733
|
-
apiPricing: "$
|
|
1734
|
-
creator: "Microsoft",
|
|
1735
|
-
elo:
|
|
1832
|
+
apiPricing: "$109/1k images",
|
|
1833
|
+
creator: "Microsoft AI",
|
|
1834
|
+
elo: 1293,
|
|
1736
1835
|
isCurrent: true,
|
|
1737
|
-
model: "MAI-Image-2",
|
|
1836
|
+
model: "MAI-Image-2.5-Pro",
|
|
1738
1837
|
rank: 7
|
|
1739
1838
|
},
|
|
1740
1839
|
{
|
|
1741
|
-
apiPricing: "$
|
|
1742
|
-
creator: "
|
|
1743
|
-
elo:
|
|
1840
|
+
apiPricing: "$34/1k images",
|
|
1841
|
+
creator: "Google",
|
|
1842
|
+
elo: 1289,
|
|
1744
1843
|
isCurrent: true,
|
|
1745
|
-
model: "
|
|
1746
|
-
rank: 8
|
|
1747
|
-
routableModelId: "flux2-max"
|
|
1844
|
+
model: "Nano Banana 2 Lite (Gemini 3.1 Flash Lite Image)",
|
|
1845
|
+
rank: 8
|
|
1748
1846
|
},
|
|
1749
1847
|
{
|
|
1750
|
-
apiPricing: "
|
|
1751
|
-
creator: "
|
|
1752
|
-
elo:
|
|
1848
|
+
apiPricing: "$43/1k images",
|
|
1849
|
+
creator: "Alibaba",
|
|
1850
|
+
elo: 1282,
|
|
1753
1851
|
isCurrent: true,
|
|
1754
|
-
model: "
|
|
1852
|
+
model: "Qwen-Image-3.0-Pro",
|
|
1755
1853
|
rank: 9
|
|
1756
1854
|
},
|
|
1757
1855
|
{
|
|
1758
|
-
apiPricing: "$
|
|
1759
|
-
creator: "
|
|
1760
|
-
elo:
|
|
1856
|
+
apiPricing: "$90/1k images",
|
|
1857
|
+
creator: "Bytedance",
|
|
1858
|
+
elo: 1279,
|
|
1761
1859
|
isCurrent: true,
|
|
1762
|
-
model: "
|
|
1860
|
+
model: "Seedream 5.0 Pro",
|
|
1763
1861
|
rank: 10,
|
|
1764
|
-
routableModelId: "
|
|
1862
|
+
routableModelId: "seedream5"
|
|
1765
1863
|
},
|
|
1766
1864
|
{
|
|
1767
|
-
apiPricing: "$
|
|
1768
|
-
creator: "
|
|
1769
|
-
elo:
|
|
1770
|
-
isCurrent:
|
|
1771
|
-
model: "
|
|
1772
|
-
rank: 11
|
|
1865
|
+
apiPricing: "$30/1k images",
|
|
1866
|
+
creator: "Alibaba",
|
|
1867
|
+
elo: 1272,
|
|
1868
|
+
isCurrent: true,
|
|
1869
|
+
model: "Qwen-Image-3.0",
|
|
1870
|
+
rank: 11,
|
|
1871
|
+
routableModelId: "qwen3"
|
|
1773
1872
|
},
|
|
1774
1873
|
{
|
|
1775
|
-
apiPricing: "$
|
|
1776
|
-
creator: "
|
|
1777
|
-
elo:
|
|
1874
|
+
apiPricing: "$75/1k images",
|
|
1875
|
+
creator: "Alibaba",
|
|
1876
|
+
elo: 1237,
|
|
1778
1877
|
isCurrent: true,
|
|
1779
|
-
model: "
|
|
1780
|
-
rank: 12
|
|
1781
|
-
routableModelId: "grok-image"
|
|
1878
|
+
model: "Qwen Image 2.0 Pro",
|
|
1879
|
+
rank: 12
|
|
1782
1880
|
},
|
|
1783
1881
|
{
|
|
1784
|
-
apiPricing: "$
|
|
1785
|
-
creator: "
|
|
1786
|
-
elo:
|
|
1882
|
+
apiPricing: "$50/1k images",
|
|
1883
|
+
creator: "SpaceXAI",
|
|
1884
|
+
elo: 1234,
|
|
1787
1885
|
isCurrent: true,
|
|
1788
|
-
model: "
|
|
1789
|
-
rank: 13
|
|
1790
|
-
routableModelId: "flux2-flex"
|
|
1886
|
+
model: "grok-imagine-image-quality",
|
|
1887
|
+
rank: 13
|
|
1791
1888
|
},
|
|
1792
1889
|
{
|
|
1793
|
-
apiPricing: "$
|
|
1794
|
-
creator: "
|
|
1795
|
-
elo:
|
|
1890
|
+
apiPricing: "$20/1k images",
|
|
1891
|
+
creator: "Microsoft AI",
|
|
1892
|
+
elo: 1228,
|
|
1796
1893
|
isCurrent: true,
|
|
1797
|
-
model: "
|
|
1894
|
+
model: "MAI-Image-2.5-Flash",
|
|
1798
1895
|
rank: 14
|
|
1799
1896
|
},
|
|
1800
1897
|
{
|
|
1801
|
-
apiPricing: "$
|
|
1802
|
-
creator: "
|
|
1803
|
-
elo:
|
|
1898
|
+
apiPricing: "$80/1k images",
|
|
1899
|
+
creator: "HiDream",
|
|
1900
|
+
elo: 1228,
|
|
1804
1901
|
isCurrent: true,
|
|
1805
|
-
model: "
|
|
1902
|
+
model: "HiDream-O1-Image-1.5",
|
|
1806
1903
|
rank: 15
|
|
1807
1904
|
},
|
|
1808
1905
|
{
|
|
1809
|
-
apiPricing: "$
|
|
1810
|
-
creator: "
|
|
1811
|
-
elo:
|
|
1812
|
-
isCurrent:
|
|
1813
|
-
model: "
|
|
1814
|
-
rank: 16
|
|
1906
|
+
apiPricing: "$30/1k images",
|
|
1907
|
+
creator: "ByteDance Seed",
|
|
1908
|
+
elo: 1226,
|
|
1909
|
+
isCurrent: true,
|
|
1910
|
+
model: "Seedream 4.0",
|
|
1911
|
+
rank: 16,
|
|
1912
|
+
routableModelId: "seedream4"
|
|
1815
1913
|
},
|
|
1816
1914
|
{
|
|
1817
|
-
apiPricing: "$
|
|
1818
|
-
creator: "
|
|
1819
|
-
elo:
|
|
1915
|
+
apiPricing: "$70/1k images",
|
|
1916
|
+
creator: "Black Forest Labs",
|
|
1917
|
+
elo: 1225,
|
|
1820
1918
|
isCurrent: true,
|
|
1821
|
-
model: "
|
|
1919
|
+
model: "FLUX.2 [max]",
|
|
1822
1920
|
rank: 17,
|
|
1823
|
-
routableModelId: "
|
|
1921
|
+
routableModelId: "flux2-max"
|
|
1824
1922
|
},
|
|
1825
1923
|
{
|
|
1826
|
-
apiPricing: "$
|
|
1827
|
-
creator: "
|
|
1828
|
-
elo:
|
|
1924
|
+
apiPricing: "$60/1k images",
|
|
1925
|
+
creator: "Black Forest Labs",
|
|
1926
|
+
elo: 1223,
|
|
1829
1927
|
isCurrent: true,
|
|
1830
|
-
model: "FLUX.2 [
|
|
1831
|
-
rank: 18
|
|
1928
|
+
model: "FLUX.2 [flex]",
|
|
1929
|
+
rank: 18,
|
|
1930
|
+
routableModelId: "flux2-flex"
|
|
1832
1931
|
},
|
|
1833
1932
|
{
|
|
1834
|
-
apiPricing: "$
|
|
1835
|
-
creator: "
|
|
1836
|
-
elo:
|
|
1933
|
+
apiPricing: "$60/1k images",
|
|
1934
|
+
creator: "Ideogram",
|
|
1935
|
+
elo: 1220,
|
|
1837
1936
|
isCurrent: true,
|
|
1838
|
-
model: "
|
|
1937
|
+
model: "Ideogram 4.0",
|
|
1839
1938
|
rank: 19,
|
|
1840
|
-
routableModelId: "
|
|
1939
|
+
routableModelId: "ideogram4"
|
|
1841
1940
|
},
|
|
1842
1941
|
{
|
|
1843
|
-
apiPricing: "$
|
|
1844
|
-
creator: "
|
|
1845
|
-
elo:
|
|
1942
|
+
apiPricing: "$60/1k images",
|
|
1943
|
+
creator: "Krea",
|
|
1944
|
+
elo: 1220,
|
|
1846
1945
|
isCurrent: true,
|
|
1847
|
-
model: "
|
|
1848
|
-
rank: 20
|
|
1849
|
-
routableModelId: "qwen"
|
|
1946
|
+
model: "Krea 2 Large",
|
|
1947
|
+
rank: 20
|
|
1850
1948
|
}
|
|
1851
1949
|
],
|
|
1852
1950
|
source: "https://artificialanalysis.ai/image/leaderboard/text-to-image"
|
|
1853
1951
|
};
|
|
1854
1952
|
var IMAGE_EDITING_TOP_20 = {
|
|
1855
|
-
capturedAt: "2026-
|
|
1953
|
+
capturedAt: "2026-08-23",
|
|
1856
1954
|
entries: [
|
|
1857
1955
|
{
|
|
1858
|
-
apiPricing: "$
|
|
1859
|
-
creator: "
|
|
1860
|
-
elo:
|
|
1956
|
+
apiPricing: "$109/1k images",
|
|
1957
|
+
creator: "Microsoft AI",
|
|
1958
|
+
elo: 1272,
|
|
1861
1959
|
isCurrent: true,
|
|
1862
|
-
model: "
|
|
1960
|
+
model: "MAI-Image-2.5-Pro",
|
|
1863
1961
|
rank: 1
|
|
1864
1962
|
},
|
|
1865
1963
|
{
|
|
1866
|
-
apiPricing: "$
|
|
1867
|
-
creator: "
|
|
1868
|
-
elo:
|
|
1964
|
+
apiPricing: "$200/1k images",
|
|
1965
|
+
creator: "Reve",
|
|
1966
|
+
elo: 1263,
|
|
1869
1967
|
isCurrent: true,
|
|
1870
|
-
model: "
|
|
1968
|
+
model: "Reve 2.1",
|
|
1871
1969
|
rank: 2,
|
|
1872
|
-
routableModelId: "
|
|
1970
|
+
routableModelId: "reve"
|
|
1873
1971
|
},
|
|
1874
1972
|
{
|
|
1875
1973
|
apiPricing: "$211/1k images",
|
|
1876
1974
|
creator: "OpenAI",
|
|
1877
|
-
elo:
|
|
1975
|
+
elo: 1256,
|
|
1878
1976
|
isCurrent: true,
|
|
1879
1977
|
model: "GPT Image 2 (high)",
|
|
1880
1978
|
rank: 3,
|
|
1881
1979
|
routableModelId: "gpt2"
|
|
1882
1980
|
},
|
|
1883
1981
|
{
|
|
1884
|
-
apiPricing: "$
|
|
1885
|
-
creator: "
|
|
1886
|
-
elo:
|
|
1982
|
+
apiPricing: "$48/1k images",
|
|
1983
|
+
creator: "Microsoft AI",
|
|
1984
|
+
elo: 1256,
|
|
1887
1985
|
isCurrent: true,
|
|
1888
|
-
model: "
|
|
1889
|
-
rank: 4
|
|
1890
|
-
routableModelId: "banana"
|
|
1986
|
+
model: "MAI-Image-2.5",
|
|
1987
|
+
rank: 4
|
|
1891
1988
|
},
|
|
1892
1989
|
{
|
|
1893
|
-
apiPricing: "$
|
|
1894
|
-
creator: "
|
|
1895
|
-
elo:
|
|
1990
|
+
apiPricing: "$133/1k images",
|
|
1991
|
+
creator: "OpenAI",
|
|
1992
|
+
elo: 1250,
|
|
1896
1993
|
isCurrent: true,
|
|
1897
|
-
model: "
|
|
1994
|
+
model: "GPT Image 1.5 (high)",
|
|
1898
1995
|
rank: 5,
|
|
1899
|
-
routableModelId: "
|
|
1996
|
+
routableModelId: "gpt"
|
|
1900
1997
|
},
|
|
1901
1998
|
{
|
|
1902
|
-
apiPricing: "$
|
|
1903
|
-
creator: "
|
|
1904
|
-
elo:
|
|
1999
|
+
apiPricing: "$43/1k images",
|
|
2000
|
+
creator: "Alibaba",
|
|
2001
|
+
elo: 1250,
|
|
1905
2002
|
isCurrent: true,
|
|
1906
|
-
model: "
|
|
2003
|
+
model: "Qwen-Image-3.0-Pro",
|
|
1907
2004
|
rank: 6
|
|
1908
2005
|
},
|
|
1909
2006
|
{
|
|
1910
|
-
apiPricing: "$
|
|
1911
|
-
creator: "
|
|
1912
|
-
elo:
|
|
2007
|
+
apiPricing: "$67/1k images",
|
|
2008
|
+
creator: "Google",
|
|
2009
|
+
elo: 1249,
|
|
1913
2010
|
isCurrent: true,
|
|
1914
|
-
model: "
|
|
2011
|
+
model: "Nano Banana 2 (Gemini 3.1 Flash Image Preview)",
|
|
1915
2012
|
rank: 7,
|
|
1916
|
-
routableModelId: "
|
|
2013
|
+
routableModelId: "banana2"
|
|
1917
2014
|
},
|
|
1918
2015
|
{
|
|
1919
|
-
apiPricing: "$
|
|
1920
|
-
creator: "
|
|
1921
|
-
elo:
|
|
2016
|
+
apiPricing: "$90/1k images",
|
|
2017
|
+
creator: "Bytedance",
|
|
2018
|
+
elo: 1248,
|
|
1922
2019
|
isCurrent: true,
|
|
1923
|
-
model: "
|
|
1924
|
-
rank: 8
|
|
2020
|
+
model: "Seedream 5.0 Pro",
|
|
2021
|
+
rank: 8,
|
|
2022
|
+
routableModelId: "seedream5"
|
|
1925
2023
|
},
|
|
1926
2024
|
{
|
|
1927
|
-
apiPricing: "
|
|
1928
|
-
creator: "
|
|
1929
|
-
elo:
|
|
2025
|
+
apiPricing: "$134/1k images",
|
|
2026
|
+
creator: "Google",
|
|
2027
|
+
elo: 1245,
|
|
1930
2028
|
isCurrent: true,
|
|
1931
|
-
model: "
|
|
1932
|
-
rank: 9
|
|
2029
|
+
model: "Nano Banana Pro (Gemini 3 Pro Image)",
|
|
2030
|
+
rank: 9,
|
|
2031
|
+
routableModelId: "banana"
|
|
1933
2032
|
},
|
|
1934
2033
|
{
|
|
1935
|
-
apiPricing: "$
|
|
1936
|
-
creator: "
|
|
1937
|
-
elo:
|
|
2034
|
+
apiPricing: "$20/1k images",
|
|
2035
|
+
creator: "Microsoft AI",
|
|
2036
|
+
elo: 1236,
|
|
1938
2037
|
isCurrent: true,
|
|
1939
|
-
model: "
|
|
1940
|
-
rank: 10
|
|
1941
|
-
routableModelId: "flux2-max"
|
|
2038
|
+
model: "MAI-Image-2.5-Flash",
|
|
2039
|
+
rank: 10
|
|
1942
2040
|
},
|
|
1943
2041
|
{
|
|
1944
|
-
apiPricing: "
|
|
1945
|
-
creator: "
|
|
1946
|
-
elo:
|
|
2042
|
+
apiPricing: "$50/1k images",
|
|
2043
|
+
creator: "SpaceXAI",
|
|
2044
|
+
elo: 1226,
|
|
1947
2045
|
isCurrent: true,
|
|
1948
|
-
model: "
|
|
2046
|
+
model: "grok-imagine-image-quality",
|
|
1949
2047
|
rank: 11
|
|
1950
2048
|
},
|
|
1951
2049
|
{
|
|
1952
|
-
apiPricing: "$
|
|
1953
|
-
creator: "
|
|
1954
|
-
elo:
|
|
2050
|
+
apiPricing: "$90/1k images",
|
|
2051
|
+
creator: "Tencent",
|
|
2052
|
+
elo: 1222,
|
|
1955
2053
|
isCurrent: true,
|
|
1956
|
-
model: "
|
|
2054
|
+
model: "HunyuanImage 3.0 Instruct",
|
|
1957
2055
|
rank: 12
|
|
1958
2056
|
},
|
|
1959
2057
|
{
|
|
1960
|
-
apiPricing: "$
|
|
1961
|
-
creator: "
|
|
1962
|
-
elo:
|
|
2058
|
+
apiPricing: "$80/1k images",
|
|
2059
|
+
creator: "Newport AI",
|
|
2060
|
+
elo: 1220,
|
|
1963
2061
|
isCurrent: true,
|
|
1964
|
-
model: "
|
|
2062
|
+
model: "DreamImage 2.0",
|
|
1965
2063
|
rank: 13
|
|
1966
2064
|
},
|
|
1967
2065
|
{
|
|
1968
|
-
apiPricing: "$
|
|
1969
|
-
creator: "
|
|
1970
|
-
elo:
|
|
2066
|
+
apiPricing: "$100/1k images",
|
|
2067
|
+
creator: "Luma Labs",
|
|
2068
|
+
elo: 1219,
|
|
1971
2069
|
isCurrent: true,
|
|
1972
|
-
model: "
|
|
2070
|
+
model: "Luma UNI 1 Max",
|
|
1973
2071
|
rank: 14
|
|
1974
2072
|
},
|
|
1975
2073
|
{
|
|
1976
|
-
apiPricing: "$
|
|
1977
|
-
creator: "
|
|
1978
|
-
elo:
|
|
2074
|
+
apiPricing: "$33/1k images",
|
|
2075
|
+
creator: "Alibaba",
|
|
2076
|
+
elo: 1218,
|
|
1979
2077
|
isCurrent: true,
|
|
1980
|
-
model: "
|
|
1981
|
-
rank: 15
|
|
2078
|
+
model: "Qwen-Image-3.0",
|
|
2079
|
+
rank: 15,
|
|
2080
|
+
routableModelId: "qwen3"
|
|
1982
2081
|
},
|
|
1983
2082
|
{
|
|
1984
|
-
apiPricing: "$
|
|
1985
|
-
creator: "
|
|
1986
|
-
elo:
|
|
2083
|
+
apiPricing: "$20/1k images",
|
|
2084
|
+
creator: "SpaceXAI",
|
|
2085
|
+
elo: 1214,
|
|
1987
2086
|
isCurrent: true,
|
|
1988
|
-
model: "
|
|
2087
|
+
model: "grok-imagine-image",
|
|
1989
2088
|
rank: 16,
|
|
1990
|
-
routableModelId: "
|
|
2089
|
+
routableModelId: "grok-image"
|
|
1991
2090
|
},
|
|
1992
2091
|
{
|
|
1993
|
-
apiPricing: "$
|
|
1994
|
-
creator: "
|
|
1995
|
-
elo:
|
|
2092
|
+
apiPricing: "$28/1k images",
|
|
2093
|
+
creator: "KlingAI",
|
|
2094
|
+
elo: 1208,
|
|
1996
2095
|
isCurrent: true,
|
|
1997
|
-
model: "
|
|
1998
|
-
rank: 17
|
|
1999
|
-
routableModelId: "seedream45"
|
|
2096
|
+
model: "Kling Image 3.0 Omni",
|
|
2097
|
+
rank: 17
|
|
2000
2098
|
},
|
|
2001
2099
|
{
|
|
2002
|
-
apiPricing: "$
|
|
2003
|
-
creator: "
|
|
2004
|
-
elo:
|
|
2100
|
+
apiPricing: "$34/1k images",
|
|
2101
|
+
creator: "Google",
|
|
2102
|
+
elo: 1202,
|
|
2005
2103
|
isCurrent: true,
|
|
2006
|
-
model: "
|
|
2104
|
+
model: "Nano Banana 2 Lite",
|
|
2007
2105
|
rank: 18
|
|
2008
2106
|
},
|
|
2009
2107
|
{
|
|
2010
|
-
apiPricing: "$
|
|
2011
|
-
creator: "
|
|
2012
|
-
elo:
|
|
2108
|
+
apiPricing: "$140/1k images",
|
|
2109
|
+
creator: "Black Forest Labs",
|
|
2110
|
+
elo: 1201,
|
|
2013
2111
|
isCurrent: true,
|
|
2014
|
-
model: "
|
|
2112
|
+
model: "FLUX.2 [max]",
|
|
2015
2113
|
rank: 19,
|
|
2016
|
-
routableModelId: "
|
|
2114
|
+
routableModelId: "flux2-max"
|
|
2017
2115
|
},
|
|
2018
2116
|
{
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
elo: 1172,
|
|
2117
|
+
creator: "Alibaba",
|
|
2118
|
+
elo: 1200,
|
|
2022
2119
|
isCurrent: true,
|
|
2023
|
-
model: "
|
|
2120
|
+
model: "Wan 2.7 Pro",
|
|
2024
2121
|
rank: 20
|
|
2025
2122
|
}
|
|
2026
2123
|
],
|
|
@@ -2250,7 +2347,31 @@ var VIDEO_IMAGE_TO_VIDEO_TOP_15 = {
|
|
|
2250
2347
|
};
|
|
2251
2348
|
|
|
2252
2349
|
// src/server.ts
|
|
2253
|
-
var
|
|
2350
|
+
var import_neverthrow2 = require("neverthrow");
|
|
2351
|
+
|
|
2352
|
+
// src/errors.ts
|
|
2353
|
+
var MotifError = class extends Error {
|
|
2354
|
+
status;
|
|
2355
|
+
code;
|
|
2356
|
+
/** fal's request-correlation id (from the `x-fal-request-id` header or the
|
|
2357
|
+
* error body). Ties a failure back to fal's dashboard/support. */
|
|
2358
|
+
requestId;
|
|
2359
|
+
constructor(message, status, code, requestId) {
|
|
2360
|
+
super(message);
|
|
2361
|
+
this.name = "MotifError";
|
|
2362
|
+
this.status = status;
|
|
2363
|
+
this.code = code;
|
|
2364
|
+
this.requestId = requestId;
|
|
2365
|
+
}
|
|
2366
|
+
};
|
|
2367
|
+
function toMotifError(error) {
|
|
2368
|
+
if (error instanceof MotifError) {
|
|
2369
|
+
return error;
|
|
2370
|
+
}
|
|
2371
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2372
|
+
const code = error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
2373
|
+
return new MotifError(message, 0, code);
|
|
2374
|
+
}
|
|
2254
2375
|
|
|
2255
2376
|
// src/fal-parse.ts
|
|
2256
2377
|
function isRecord(value) {
|
|
@@ -2348,9 +2469,369 @@ function requestIdFromBody(text) {
|
|
|
2348
2469
|
return asString(parsed.request_id) ?? asString(parsed.requestId) ?? asString(parsed.trace_id);
|
|
2349
2470
|
}
|
|
2350
2471
|
|
|
2351
|
-
// src/tools.ts
|
|
2352
|
-
var
|
|
2353
|
-
|
|
2472
|
+
// src/server-tools.ts
|
|
2473
|
+
var import_neverthrow = require("neverthrow");
|
|
2474
|
+
|
|
2475
|
+
// src/tool-registry/analysis.ts
|
|
2476
|
+
var ANALYSIS_TOOLS = {
|
|
2477
|
+
"got-ocr": {
|
|
2478
|
+
category: "analysis",
|
|
2479
|
+
description: "Transcribe text from one or more images, optionally as formatted multi-page output.",
|
|
2480
|
+
endpoint: "fal-ai/got-ocr/v2",
|
|
2481
|
+
inputField: "input_image_urls",
|
|
2482
|
+
inputKind: "images",
|
|
2483
|
+
name: "GOT-OCR 2.0",
|
|
2484
|
+
outputKeys: ["outputs"],
|
|
2485
|
+
price: { kind: "metered" },
|
|
2486
|
+
pricing: "$0.05/image",
|
|
2487
|
+
queued: true,
|
|
2488
|
+
sourceUrl: "https://fal.ai/models/fal-ai/got-ocr/v2",
|
|
2489
|
+
task: "optical character recognition"
|
|
2490
|
+
},
|
|
2491
|
+
"moondream-caption": {
|
|
2492
|
+
category: "analysis",
|
|
2493
|
+
description: "Write a short, normal, or long caption for an image.",
|
|
2494
|
+
endpoint: "fal-ai/moondream3-preview/caption",
|
|
2495
|
+
inputField: "image_url",
|
|
2496
|
+
inputKind: "image",
|
|
2497
|
+
name: "Moondream 3 Caption",
|
|
2498
|
+
outputKeys: ["output"],
|
|
2499
|
+
price: { kind: "metered" },
|
|
2500
|
+
pricing: "$0.40/M input tokens, $3.50/M output tokens",
|
|
2501
|
+
sourceUrl: "https://fal.ai/models/fal-ai/moondream3-preview/caption",
|
|
2502
|
+
task: "image captioning"
|
|
2503
|
+
},
|
|
2504
|
+
"moondream-detect": {
|
|
2505
|
+
category: "analysis",
|
|
2506
|
+
description: "Detect prompted objects and return their bounding boxes, with an optional preview.",
|
|
2507
|
+
endpoint: "fal-ai/moondream3-preview/detect",
|
|
2508
|
+
inputField: "image_url",
|
|
2509
|
+
inputKind: "image",
|
|
2510
|
+
name: "Moondream 3 Detect",
|
|
2511
|
+
outputKeys: ["objects", "image"],
|
|
2512
|
+
price: { kind: "metered" },
|
|
2513
|
+
pricing: "$0.40/M input tokens, $3.50/M output tokens",
|
|
2514
|
+
sourceUrl: "https://fal.ai/models/fal-ai/moondream3-preview/detect",
|
|
2515
|
+
task: "object detection"
|
|
2516
|
+
},
|
|
2517
|
+
"moondream-point": {
|
|
2518
|
+
category: "analysis",
|
|
2519
|
+
description: "Return point coordinates for every instance of a prompted subject.",
|
|
2520
|
+
endpoint: "fal-ai/moondream3-preview/point",
|
|
2521
|
+
inputField: "image_url",
|
|
2522
|
+
inputKind: "image",
|
|
2523
|
+
name: "Moondream 3 Point",
|
|
2524
|
+
outputKeys: ["points", "image"],
|
|
2525
|
+
price: { kind: "metered" },
|
|
2526
|
+
pricing: "$0.40/M input tokens, $3.50/M output tokens",
|
|
2527
|
+
sourceUrl: "https://fal.ai/models/fal-ai/moondream3-preview/point",
|
|
2528
|
+
task: "object pointing"
|
|
2529
|
+
},
|
|
2530
|
+
"moondream-query": {
|
|
2531
|
+
category: "analysis",
|
|
2532
|
+
description: "Answer a free-form question about an image, with reasoning.",
|
|
2533
|
+
endpoint: "fal-ai/moondream3-preview/query",
|
|
2534
|
+
inputField: "image_url",
|
|
2535
|
+
inputKind: "image",
|
|
2536
|
+
name: "Moondream 3 Query",
|
|
2537
|
+
outputKeys: ["output", "reasoning"],
|
|
2538
|
+
price: { kind: "metered" },
|
|
2539
|
+
pricing: "$0.40/M input tokens, $3.50/M output tokens",
|
|
2540
|
+
sourceUrl: "https://fal.ai/models/fal-ai/moondream3-preview/query",
|
|
2541
|
+
task: "visual question answering"
|
|
2542
|
+
},
|
|
2543
|
+
nsfw: {
|
|
2544
|
+
category: "moderation",
|
|
2545
|
+
description: "Predict whether one or more images contain NSFW concepts.",
|
|
2546
|
+
endpoint: "fal-ai/x-ailab/nsfw",
|
|
2547
|
+
inputField: "image_urls",
|
|
2548
|
+
inputKind: "images",
|
|
2549
|
+
name: "NSFW Checker",
|
|
2550
|
+
outputKeys: ["has_nsfw_concepts"],
|
|
2551
|
+
price: { kind: "metered" },
|
|
2552
|
+
pricing: "$0.001/image",
|
|
2553
|
+
sourceUrl: "https://fal.ai/models/fal-ai/x-ailab/nsfw",
|
|
2554
|
+
task: "vision moderation"
|
|
2555
|
+
}
|
|
2556
|
+
};
|
|
2557
|
+
|
|
2558
|
+
// src/tool-registry/assets.ts
|
|
2559
|
+
var ASSET_TOOLS = {
|
|
2560
|
+
"hunyuan3d-v3": {
|
|
2561
|
+
category: "3d",
|
|
2562
|
+
description: "Reconstruct a textured 3D mesh from a single image, with optional multi-view inputs.",
|
|
2563
|
+
endpoint: "fal-ai/hunyuan3d-v3/image-to-3d",
|
|
2564
|
+
inputField: "input_image_url",
|
|
2565
|
+
inputKind: "image",
|
|
2566
|
+
name: "Hunyuan3D v3 Image to 3D",
|
|
2567
|
+
outputKeys: ["model_glb", "model_urls", "thumbnail"],
|
|
2568
|
+
price: { kind: "call", usd: 0.375 },
|
|
2569
|
+
pricing: "$0.375/generation at the default Normal type; $0.45 low poly, $0.225 geometry only, and $0.15 each for PBR, multi-view, or a custom face count",
|
|
2570
|
+
queued: true,
|
|
2571
|
+
sourceUrl: "https://fal.ai/models/fal-ai/hunyuan3d-v3/image-to-3d",
|
|
2572
|
+
task: "single-image 3D reconstruction"
|
|
2573
|
+
},
|
|
2574
|
+
"ideogram-layerize-text": {
|
|
2575
|
+
category: "layers",
|
|
2576
|
+
description: "Split an image into background image layers plus editable HTML text containers.",
|
|
2577
|
+
endpoint: "fal-ai/ideogram/v3/layerize-text",
|
|
2578
|
+
inputField: "image_url",
|
|
2579
|
+
inputKind: "image",
|
|
2580
|
+
name: "Ideogram v3 Text Layerize",
|
|
2581
|
+
outputKeys: ["image_layers", "image", "text_html", "text_containers"],
|
|
2582
|
+
price: { kind: "call", usd: 0.09 },
|
|
2583
|
+
pricing: "$0.09/image",
|
|
2584
|
+
queued: true,
|
|
2585
|
+
sourceUrl: "https://fal.ai/models/fal-ai/ideogram/v3/layerize-text",
|
|
2586
|
+
task: "text and image layer extraction"
|
|
2587
|
+
},
|
|
2588
|
+
"ideogram-tiling": {
|
|
2589
|
+
category: "material",
|
|
2590
|
+
description: "Generate a seamlessly tiling texture, optionally conditioned on a source image.",
|
|
2591
|
+
endpoint: "ideogram/v4/tiling",
|
|
2592
|
+
inputField: "image_url",
|
|
2593
|
+
inputKind: "image",
|
|
2594
|
+
name: "Ideogram v4 Tiling",
|
|
2595
|
+
outputKeys: ["images"],
|
|
2596
|
+
price: { kind: "megapixel", usd: 0.06 },
|
|
2597
|
+
pricing: "$0.06/megapixel at the default BALANCED speed; $0.03 turbo, $0.10 quality",
|
|
2598
|
+
sourceUrl: "https://fal.ai/models/ideogram/v4/tiling",
|
|
2599
|
+
task: "seamless texture generation"
|
|
2600
|
+
},
|
|
2601
|
+
image2svg: {
|
|
2602
|
+
category: "vector",
|
|
2603
|
+
description: "Trace a raster image into layered SVG paths.",
|
|
2604
|
+
endpoint: "fal-ai/image2svg",
|
|
2605
|
+
inputField: "image_url",
|
|
2606
|
+
inputKind: "image",
|
|
2607
|
+
name: "Image to SVG",
|
|
2608
|
+
outputKeys: ["images"],
|
|
2609
|
+
price: { kind: "call", usd: 5e-3 },
|
|
2610
|
+
pricing: "$0.005/image",
|
|
2611
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image2svg",
|
|
2612
|
+
task: "raster to vector tracing"
|
|
2613
|
+
},
|
|
2614
|
+
patina: {
|
|
2615
|
+
category: "material",
|
|
2616
|
+
description: "Decompose a surface photograph into PBR maps: basecolor, normal, roughness, metalness, height.",
|
|
2617
|
+
endpoint: "fal-ai/patina",
|
|
2618
|
+
inputField: "image_url",
|
|
2619
|
+
inputKind: "image",
|
|
2620
|
+
name: "Patina PBR Maps",
|
|
2621
|
+
outputKeys: ["images"],
|
|
2622
|
+
// Output order follows the request's `maps` array, so read that first;
|
|
2623
|
+
// the fallback is the endpoint's own schema default.
|
|
2624
|
+
outputLabels: {
|
|
2625
|
+
images: {
|
|
2626
|
+
fallback: ["basecolor", "normal", "roughness", "metalness", "height"],
|
|
2627
|
+
fromOption: "maps"
|
|
2628
|
+
}
|
|
2629
|
+
},
|
|
2630
|
+
price: { kind: "metered" },
|
|
2631
|
+
pricing: "$0.01 base plus $0.01/megapixel per output map, so all 5 maps on a 1MP image cost $0.06; the listed rate is per map",
|
|
2632
|
+
queued: true,
|
|
2633
|
+
sourceUrl: "https://fal.ai/models/fal-ai/patina",
|
|
2634
|
+
task: "PBR material decomposition"
|
|
2635
|
+
},
|
|
2636
|
+
"patina-extract": {
|
|
2637
|
+
category: "material",
|
|
2638
|
+
description: "Extract a tiling PBR material from a prompted region of a photograph.",
|
|
2639
|
+
endpoint: "fal-ai/patina/material/extract",
|
|
2640
|
+
inputField: "image_url",
|
|
2641
|
+
inputKind: "image",
|
|
2642
|
+
name: "Patina Material Extract",
|
|
2643
|
+
outputKeys: ["images"],
|
|
2644
|
+
// Same `maps` option and schema default as fal-ai/patina, both verified.
|
|
2645
|
+
// `num_images` above 1 multiplies the array and breaks the mapping, which
|
|
2646
|
+
// the count check catches.
|
|
2647
|
+
outputLabels: {
|
|
2648
|
+
images: {
|
|
2649
|
+
fallback: ["basecolor", "normal", "roughness", "metalness", "height"],
|
|
2650
|
+
fromOption: "maps"
|
|
2651
|
+
}
|
|
2652
|
+
},
|
|
2653
|
+
price: { kind: "metered" },
|
|
2654
|
+
pricing: "$0.10 base only; add $0.02/megapixel plus $0.01/megapixel per map, so 1MP with all 5 maps is $0.17",
|
|
2655
|
+
queued: true,
|
|
2656
|
+
sourceUrl: "https://fal.ai/models/fal-ai/patina/material/extract",
|
|
2657
|
+
task: "tiling material extraction"
|
|
2658
|
+
},
|
|
2659
|
+
"qwen-layered": {
|
|
2660
|
+
category: "layers",
|
|
2661
|
+
description: "Split an image into a configurable number of stacked RGBA layers.",
|
|
2662
|
+
endpoint: "fal-ai/qwen-image-layered",
|
|
2663
|
+
inputField: "image_url",
|
|
2664
|
+
inputKind: "image",
|
|
2665
|
+
name: "Qwen Image Layered",
|
|
2666
|
+
outputKeys: ["images"],
|
|
2667
|
+
// fal publishes a figure but not what it counts. Encoding it as `call`
|
|
2668
|
+
// would assert a per-request price we cannot support, and this endpoint
|
|
2669
|
+
// returns several outputs — the same shape that made `seedream-layerize`
|
|
2670
|
+
// under-report by a factor of its layer count. `metered` reports null
|
|
2671
|
+
// rather than a number that is right only on one reading.
|
|
2672
|
+
price: { kind: "metered" },
|
|
2673
|
+
pricing: "$0.05 per image; fal does not say whether that counts the input image or each of the generated layers, so no estimate is reported",
|
|
2674
|
+
queued: true,
|
|
2675
|
+
sourceUrl: "https://fal.ai/models/fal-ai/qwen-image-layered",
|
|
2676
|
+
task: "image layer decomposition"
|
|
2677
|
+
},
|
|
2678
|
+
"recraft-vectorize": {
|
|
2679
|
+
category: "vector",
|
|
2680
|
+
description: "Convert a raster image into a clean SVG.",
|
|
2681
|
+
endpoint: "fal-ai/recraft/vectorize",
|
|
2682
|
+
inputField: "image_url",
|
|
2683
|
+
inputKind: "image",
|
|
2684
|
+
name: "Recraft Vectorize",
|
|
2685
|
+
outputKeys: ["image"],
|
|
2686
|
+
price: { kind: "call", usd: 0.04 },
|
|
2687
|
+
pricing: "$0.04/image, $0.08 with a vector style",
|
|
2688
|
+
sourceUrl: "https://fal.ai/models/fal-ai/recraft/vectorize",
|
|
2689
|
+
task: "raster to vector conversion"
|
|
2690
|
+
},
|
|
2691
|
+
"sam3-3d-align": {
|
|
2692
|
+
category: "3d",
|
|
2693
|
+
description: "Align SAM 3D objects and bodies into a shared scene.",
|
|
2694
|
+
endpoint: "fal-ai/sam-3/3d-align",
|
|
2695
|
+
inputField: "image_url",
|
|
2696
|
+
inputKind: "image",
|
|
2697
|
+
name: "SAM 3D Align",
|
|
2698
|
+
outputKeys: [
|
|
2699
|
+
"scene_glb",
|
|
2700
|
+
"model_glb",
|
|
2701
|
+
"visualization",
|
|
2702
|
+
"body_mesh_ply",
|
|
2703
|
+
"metadata"
|
|
2704
|
+
],
|
|
2705
|
+
// fal publishes a figure but not what it counts. Encoding it as `call`
|
|
2706
|
+
// would assert a per-request price we cannot support, and this endpoint
|
|
2707
|
+
// returns several outputs — the same shape that made `seedream-layerize`
|
|
2708
|
+
// under-report by a factor of its layer count. `metered` reports null
|
|
2709
|
+
// rather than a number that is right only on one reading.
|
|
2710
|
+
price: { kind: "metered" },
|
|
2711
|
+
pricing: "$0.02 per unit; fal does not define a unit, so no estimate is reported",
|
|
2712
|
+
queued: true,
|
|
2713
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-align",
|
|
2714
|
+
task: "3D scene alignment"
|
|
2715
|
+
},
|
|
2716
|
+
"sam3-3d-body": {
|
|
2717
|
+
category: "3d",
|
|
2718
|
+
defaultOptions: {
|
|
2719
|
+
export_meshes: true,
|
|
2720
|
+
include_3d_keypoints: true,
|
|
2721
|
+
include_mhr_params: true
|
|
2722
|
+
},
|
|
2723
|
+
description: "Reconstruct human body meshes and keypoints from a single image.",
|
|
2724
|
+
endpoint: "fal-ai/sam-3/3d-body",
|
|
2725
|
+
inputField: "image_url",
|
|
2726
|
+
inputKind: "image",
|
|
2727
|
+
name: "SAM 3D Body",
|
|
2728
|
+
outputKeys: ["model_glb", "visualization", "meshes", "metadata"],
|
|
2729
|
+
// fal publishes a figure but not what it counts. Encoding it as `call`
|
|
2730
|
+
// would assert a per-request price we cannot support, and this endpoint
|
|
2731
|
+
// returns several outputs — the same shape that made `seedream-layerize`
|
|
2732
|
+
// under-report by a factor of its layer count. `metered` reports null
|
|
2733
|
+
// rather than a number that is right only on one reading.
|
|
2734
|
+
price: { kind: "metered" },
|
|
2735
|
+
pricing: "$0.02 per unit; fal does not define a unit, so no estimate is reported",
|
|
2736
|
+
queued: true,
|
|
2737
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-body",
|
|
2738
|
+
task: "single-image 3D body reconstruction"
|
|
2739
|
+
},
|
|
2740
|
+
"sam3-3d-objects": {
|
|
2741
|
+
category: "3d",
|
|
2742
|
+
defaultOptions: {
|
|
2743
|
+
prompt: "car"
|
|
2744
|
+
},
|
|
2745
|
+
description: "Reconstruct one or more 3D objects from an image and prompts.",
|
|
2746
|
+
endpoint: "fal-ai/sam-3/3d-objects",
|
|
2747
|
+
inputField: "image_url",
|
|
2748
|
+
inputKind: "image",
|
|
2749
|
+
name: "SAM 3D Objects",
|
|
2750
|
+
outputKeys: [
|
|
2751
|
+
"gaussian_splat",
|
|
2752
|
+
"model_glb",
|
|
2753
|
+
"metadata",
|
|
2754
|
+
"individual_splats",
|
|
2755
|
+
"individual_glbs",
|
|
2756
|
+
"artifacts_zip"
|
|
2757
|
+
],
|
|
2758
|
+
// fal publishes a figure but not what it counts. Encoding it as `call`
|
|
2759
|
+
// would assert a per-request price we cannot support, and this endpoint
|
|
2760
|
+
// returns several outputs — the same shape that made `seedream-layerize`
|
|
2761
|
+
// under-report by a factor of its layer count. `metered` reports null
|
|
2762
|
+
// rather than a number that is right only on one reading.
|
|
2763
|
+
price: { kind: "metered" },
|
|
2764
|
+
pricing: "$0.02 per unit; fal does not define a unit, and this endpoint returns one mesh per detected object, so no estimate is reported",
|
|
2765
|
+
queued: true,
|
|
2766
|
+
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-objects",
|
|
2767
|
+
task: "single-image 3D object reconstruction"
|
|
2768
|
+
},
|
|
2769
|
+
"seedream-layerize": {
|
|
2770
|
+
category: "layers",
|
|
2771
|
+
description: "Split an image into editable Seedream layers plus flattened previews.",
|
|
2772
|
+
endpoint: "bytedance/seedream/v5/pro/layerize",
|
|
2773
|
+
inputField: "image_url",
|
|
2774
|
+
inputKind: "image",
|
|
2775
|
+
name: "Seedream v5 Pro Layerize",
|
|
2776
|
+
outputKeys: ["layers", "images"],
|
|
2777
|
+
// Every element of `layers` carries its own `name` ("Left amber glass
|
|
2778
|
+
// bottle") and a `z_index` that orders the stack, verified live. Without
|
|
2779
|
+
// this the stack lands as layers.png … layers-5.png and the only way to
|
|
2780
|
+
// tell the reconstructed background plate from an object is to open them.
|
|
2781
|
+
outputLabels: {
|
|
2782
|
+
layers: { fromItem: { nameField: "name", orderField: "z_index" } }
|
|
2783
|
+
},
|
|
2784
|
+
price: { kind: "metered" },
|
|
2785
|
+
pricing: "$0.03375 per generated layer below 1536x1536 total area, $0.0675 per layer above; the listed rate is per layer, not per call",
|
|
2786
|
+
queued: true,
|
|
2787
|
+
sourceUrl: "https://fal.ai/models/bytedance/seedream/v5/pro/layerize",
|
|
2788
|
+
task: "image layer decomposition"
|
|
2789
|
+
},
|
|
2790
|
+
"seedvr-seamless": {
|
|
2791
|
+
category: "material",
|
|
2792
|
+
description: "Upscale a tiling texture while keeping its edges seamless. ",
|
|
2793
|
+
endpoint: "fal-ai/seedvr/upscale/image/seamless",
|
|
2794
|
+
inputField: "image_url",
|
|
2795
|
+
inputKind: "image",
|
|
2796
|
+
name: "SeedVR Seamless Upscale",
|
|
2797
|
+
outputKeys: ["image"],
|
|
2798
|
+
price: { kind: "megapixel", usd: 25e-4 },
|
|
2799
|
+
pricing: "$0.0025/megapixel",
|
|
2800
|
+
queued: true,
|
|
2801
|
+
sourceUrl: "https://fal.ai/models/fal-ai/seedvr/upscale/image/seamless",
|
|
2802
|
+
task: "seamless texture upscaling"
|
|
2803
|
+
},
|
|
2804
|
+
"trellis-2": {
|
|
2805
|
+
category: "3d",
|
|
2806
|
+
description: "Reconstruct a textured 3D mesh from a single image, with UV unwrapping.",
|
|
2807
|
+
endpoint: "fal-ai/trellis-2",
|
|
2808
|
+
inputField: "image_url",
|
|
2809
|
+
inputKind: "image",
|
|
2810
|
+
name: "TRELLIS 2",
|
|
2811
|
+
outputKeys: ["model_glb"],
|
|
2812
|
+
price: { kind: "call", usd: 0.3 },
|
|
2813
|
+
pricing: "$0.30 at the default 1024p; $0.25 at 512p, $0.35 at 1536p",
|
|
2814
|
+
queued: true,
|
|
2815
|
+
sourceUrl: "https://fal.ai/models/fal-ai/trellis-2",
|
|
2816
|
+
task: "single-image 3D reconstruction"
|
|
2817
|
+
}
|
|
2818
|
+
};
|
|
2819
|
+
|
|
2820
|
+
// src/tool-registry/background.ts
|
|
2821
|
+
var BACKGROUND_TOOLS = {
|
|
2822
|
+
"ben-v2": {
|
|
2823
|
+
category: "background",
|
|
2824
|
+
description: "Fast, high-quality background removal for images.",
|
|
2825
|
+
endpoint: "fal-ai/ben/v2/image",
|
|
2826
|
+
inputField: "image_url",
|
|
2827
|
+
inputKind: "image",
|
|
2828
|
+
name: "BEN v2 Background Removal",
|
|
2829
|
+
outputKeys: ["image"],
|
|
2830
|
+
price: { kind: "megapixel", usd: 0.025 },
|
|
2831
|
+
pricing: "$0.025/megapixel",
|
|
2832
|
+
sourceUrl: "https://fal.ai/models/fal-ai/ben/v2/image",
|
|
2833
|
+
task: "image background removal"
|
|
2834
|
+
},
|
|
2354
2835
|
birefnet: {
|
|
2355
2836
|
category: "background",
|
|
2356
2837
|
defaultOptions: {
|
|
@@ -2365,6 +2846,7 @@ var FAL_TOOLS = {
|
|
|
2365
2846
|
inputKind: "image",
|
|
2366
2847
|
name: "BirefNet Background Removal",
|
|
2367
2848
|
outputKeys: ["image", "mask_image"],
|
|
2849
|
+
price: { kind: "metered" },
|
|
2368
2850
|
pricing: "$0/compute-second listed by fal",
|
|
2369
2851
|
sourceUrl: "https://fal.ai/models/fal-ai/birefnet/v2",
|
|
2370
2852
|
task: "image background removal"
|
|
@@ -2377,7 +2859,8 @@ var FAL_TOOLS = {
|
|
|
2377
2859
|
inputKind: "image",
|
|
2378
2860
|
name: "Bria RMBG 2.0",
|
|
2379
2861
|
outputKeys: ["image"],
|
|
2380
|
-
|
|
2862
|
+
price: { kind: "call", usd: 0.018 },
|
|
2863
|
+
pricing: "$0.018/generation",
|
|
2381
2864
|
sourceUrl: "https://fal.ai/models/fal-ai/bria/background/remove",
|
|
2382
2865
|
task: "image background removal"
|
|
2383
2866
|
},
|
|
@@ -2394,10 +2877,422 @@ var FAL_TOOLS = {
|
|
|
2394
2877
|
inputKind: "video",
|
|
2395
2878
|
name: "Bria Video Background Removal",
|
|
2396
2879
|
outputKeys: ["video"],
|
|
2397
|
-
|
|
2880
|
+
price: { kind: "second", usd: 425e-5 },
|
|
2881
|
+
pricing: "$0.00425/sec",
|
|
2882
|
+
queued: true,
|
|
2398
2883
|
sourceUrl: "https://fal.ai/models/bria/video/background-removal",
|
|
2399
2884
|
task: "video background removal"
|
|
2400
2885
|
},
|
|
2886
|
+
ddcolor: {
|
|
2887
|
+
category: "restoration",
|
|
2888
|
+
description: "Colourise black-and-white photographs.",
|
|
2889
|
+
endpoint: "fal-ai/ddcolor",
|
|
2890
|
+
inputField: "image_url",
|
|
2891
|
+
inputKind: "image",
|
|
2892
|
+
name: "DDColor Colourisation",
|
|
2893
|
+
outputKeys: ["image"],
|
|
2894
|
+
price: { kind: "megapixel", usd: 1e-3 },
|
|
2895
|
+
pricing: "$0.001/megapixel",
|
|
2896
|
+
sourceUrl: "https://fal.ai/models/fal-ai/ddcolor",
|
|
2897
|
+
task: "photo colourisation"
|
|
2898
|
+
},
|
|
2899
|
+
rembg: {
|
|
2900
|
+
category: "background",
|
|
2901
|
+
defaultOptions: {
|
|
2902
|
+
crop_to_bbox: false
|
|
2903
|
+
},
|
|
2904
|
+
description: "Generic image background removal utility.",
|
|
2905
|
+
endpoint: "fal-ai/imageutils/rembg",
|
|
2906
|
+
inputField: "image_url",
|
|
2907
|
+
inputKind: "image",
|
|
2908
|
+
name: "Remove Background",
|
|
2909
|
+
outputKeys: ["image"],
|
|
2910
|
+
price: { kind: "metered" },
|
|
2911
|
+
pricing: "$0/compute-second listed by fal",
|
|
2912
|
+
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/rembg",
|
|
2913
|
+
task: "image background removal"
|
|
2914
|
+
},
|
|
2915
|
+
"seedvr-upscale": {
|
|
2916
|
+
category: "restoration",
|
|
2917
|
+
defaultOptions: {
|
|
2918
|
+
output_format: "png"
|
|
2919
|
+
},
|
|
2920
|
+
description: "Diffusion image restoration and upscaling with SeedVR.",
|
|
2921
|
+
endpoint: "fal-ai/seedvr/upscale/image",
|
|
2922
|
+
inputField: "image_url",
|
|
2923
|
+
inputKind: "image",
|
|
2924
|
+
name: "SeedVR Image Upscale",
|
|
2925
|
+
outputKeys: ["image"],
|
|
2926
|
+
price: { kind: "megapixel", usd: 1e-3 },
|
|
2927
|
+
pricing: "$0.001/megapixel",
|
|
2928
|
+
queued: true,
|
|
2929
|
+
sourceUrl: "https://fal.ai/models/fal-ai/seedvr/upscale/image",
|
|
2930
|
+
task: "image restoration and upscaling"
|
|
2931
|
+
},
|
|
2932
|
+
"topaz-adjust": {
|
|
2933
|
+
category: "restoration",
|
|
2934
|
+
defaultOptions: {
|
|
2935
|
+
output_format: "png"
|
|
2936
|
+
},
|
|
2937
|
+
description: "Topaz exposure, white balance, and colour adjustment.",
|
|
2938
|
+
endpoint: "topaz/adjust/image",
|
|
2939
|
+
inputField: "image_url",
|
|
2940
|
+
inputKind: "image",
|
|
2941
|
+
name: "Topaz Adjust",
|
|
2942
|
+
outputKeys: ["image"],
|
|
2943
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
2944
|
+
pricing: "$0.08 per 24 output megapixels",
|
|
2945
|
+
queued: true,
|
|
2946
|
+
sourceUrl: "https://fal.ai/models/topaz/adjust/image",
|
|
2947
|
+
task: "tonal adjustment"
|
|
2948
|
+
},
|
|
2949
|
+
"topaz-creative": {
|
|
2950
|
+
category: "restoration",
|
|
2951
|
+
defaultOptions: {
|
|
2952
|
+
output_format: "png"
|
|
2953
|
+
},
|
|
2954
|
+
description: "Topaz Bloom upscaling, which reimagines detail rather than preserving it.",
|
|
2955
|
+
endpoint: "topaz/upscale/image/creative",
|
|
2956
|
+
inputField: "image_url",
|
|
2957
|
+
inputKind: "image",
|
|
2958
|
+
name: "Topaz Creative Upscale",
|
|
2959
|
+
outputKeys: ["image"],
|
|
2960
|
+
price: { kind: "megapixel", usd: 0.96 / 24 },
|
|
2961
|
+
pricing: "$0.96 per 24 output megapixels",
|
|
2962
|
+
queued: true,
|
|
2963
|
+
sourceUrl: "https://fal.ai/models/topaz/upscale/image/creative",
|
|
2964
|
+
task: "creative image upscaling"
|
|
2965
|
+
},
|
|
2966
|
+
"topaz-denoise": {
|
|
2967
|
+
category: "restoration",
|
|
2968
|
+
defaultOptions: {
|
|
2969
|
+
output_format: "png"
|
|
2970
|
+
},
|
|
2971
|
+
description: "Topaz noise reduction at source resolution.",
|
|
2972
|
+
endpoint: "topaz/denoise/image",
|
|
2973
|
+
inputField: "image_url",
|
|
2974
|
+
inputKind: "image",
|
|
2975
|
+
name: "Topaz Denoise",
|
|
2976
|
+
outputKeys: ["image"],
|
|
2977
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
2978
|
+
pricing: "$0.08 per 24 output megapixels at the default Normal model; $0.16 with Denoise Max",
|
|
2979
|
+
queued: true,
|
|
2980
|
+
sourceUrl: "https://fal.ai/models/topaz/denoise/image",
|
|
2981
|
+
task: "image denoising"
|
|
2982
|
+
},
|
|
2983
|
+
"topaz-generative": {
|
|
2984
|
+
category: "restoration",
|
|
2985
|
+
defaultOptions: {
|
|
2986
|
+
output_format: "png"
|
|
2987
|
+
},
|
|
2988
|
+
description: "Topaz Wonder upscaling, which synthesises plausible detail as it enlarges.",
|
|
2989
|
+
endpoint: "topaz/upscale/image/generative",
|
|
2990
|
+
inputField: "image_url",
|
|
2991
|
+
inputKind: "image",
|
|
2992
|
+
name: "Topaz Generative Upscale",
|
|
2993
|
+
outputKeys: ["image"],
|
|
2994
|
+
price: { kind: "megapixel", usd: 0.24 / 24 },
|
|
2995
|
+
pricing: "$0.24 per 24 output megapixels at the default Wonder 3; $0.48 with Wonder, Wonder 2, Standard MAX, Redefine or Recover 3",
|
|
2996
|
+
queued: true,
|
|
2997
|
+
sourceUrl: "https://fal.ai/models/topaz/upscale/image/generative",
|
|
2998
|
+
task: "generative image upscaling"
|
|
2999
|
+
},
|
|
3000
|
+
"topaz-image": {
|
|
3001
|
+
category: "upscale",
|
|
3002
|
+
defaultOptions: {
|
|
3003
|
+
model: "Standard V2",
|
|
3004
|
+
output_format: "jpeg",
|
|
3005
|
+
upscale_factor: 2
|
|
3006
|
+
},
|
|
3007
|
+
description: "Professional Topaz image enhancement and upscaling.",
|
|
3008
|
+
endpoint: "fal-ai/topaz/upscale/image",
|
|
3009
|
+
inputField: "image_url",
|
|
3010
|
+
inputKind: "image",
|
|
3011
|
+
name: "Topaz Image Upscale",
|
|
3012
|
+
outputKeys: ["image"],
|
|
3013
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
3014
|
+
pricing: "$0.08 for output up to 24MP; $0.16 to 48MP, $0.32 to 96MP, up to $1.36 at 512MP",
|
|
3015
|
+
queued: true,
|
|
3016
|
+
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/image",
|
|
3017
|
+
task: "image enhancement"
|
|
3018
|
+
},
|
|
3019
|
+
"topaz-precision": {
|
|
3020
|
+
category: "restoration",
|
|
3021
|
+
defaultOptions: {
|
|
3022
|
+
output_format: "png"
|
|
3023
|
+
},
|
|
3024
|
+
description: "Topaz upscaling that preserves the original detail rather than inventing it.",
|
|
3025
|
+
endpoint: "topaz/upscale/image/precision",
|
|
3026
|
+
inputField: "image_url",
|
|
3027
|
+
inputKind: "image",
|
|
3028
|
+
name: "Topaz Precision Upscale",
|
|
3029
|
+
outputKeys: ["image"],
|
|
3030
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
3031
|
+
pricing: "$0.08 per 24 output megapixels, any precision model",
|
|
3032
|
+
queued: true,
|
|
3033
|
+
sourceUrl: "https://fal.ai/models/topaz/upscale/image/precision",
|
|
3034
|
+
task: "faithful image upscaling"
|
|
3035
|
+
},
|
|
3036
|
+
"topaz-restore": {
|
|
3037
|
+
category: "restoration",
|
|
3038
|
+
defaultOptions: {
|
|
3039
|
+
output_format: "png"
|
|
3040
|
+
},
|
|
3041
|
+
description: "Topaz restoration of damaged or degraded photographs at source resolution.",
|
|
3042
|
+
endpoint: "topaz/restore/image",
|
|
3043
|
+
inputField: "image_url",
|
|
3044
|
+
inputKind: "image",
|
|
3045
|
+
name: "Topaz Restore",
|
|
3046
|
+
outputKeys: ["image"],
|
|
3047
|
+
price: { kind: "megapixel", usd: 0.48 / 24 },
|
|
3048
|
+
pricing: "$0.48 per 24 output megapixels at the default Recover 3; $0.08 with Dust-Scratch V2",
|
|
3049
|
+
queued: true,
|
|
3050
|
+
sourceUrl: "https://fal.ai/models/topaz/restore/image",
|
|
3051
|
+
task: "photo restoration"
|
|
3052
|
+
},
|
|
3053
|
+
"topaz-sharpen": {
|
|
3054
|
+
category: "restoration",
|
|
3055
|
+
defaultOptions: {
|
|
3056
|
+
output_format: "png"
|
|
3057
|
+
},
|
|
3058
|
+
description: "Topaz deblurring and sharpening at source resolution.",
|
|
3059
|
+
endpoint: "topaz/sharpen/image",
|
|
3060
|
+
inputField: "image_url",
|
|
3061
|
+
inputKind: "image",
|
|
3062
|
+
name: "Topaz Sharpen",
|
|
3063
|
+
outputKeys: ["image"],
|
|
3064
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
3065
|
+
pricing: "$0.08 per 24 output megapixels at the default Standard model; $0.16 with Super Focus",
|
|
3066
|
+
queued: true,
|
|
3067
|
+
sourceUrl: "https://fal.ai/models/topaz/sharpen/image",
|
|
3068
|
+
task: "image sharpening"
|
|
3069
|
+
},
|
|
3070
|
+
"topaz-transparent": {
|
|
3071
|
+
category: "restoration",
|
|
3072
|
+
description: "Topaz upscaling that preserves the alpha channel end to end.",
|
|
3073
|
+
endpoint: "topaz/upscale/image/transparent",
|
|
3074
|
+
inputField: "image_url",
|
|
3075
|
+
inputKind: "image",
|
|
3076
|
+
name: "Topaz Transparent Upscale",
|
|
3077
|
+
outputKeys: ["image"],
|
|
3078
|
+
price: { kind: "megapixel", usd: 0.08 / 24 },
|
|
3079
|
+
pricing: "$0.08 per 24 output megapixels",
|
|
3080
|
+
queued: true,
|
|
3081
|
+
sourceUrl: "https://fal.ai/models/topaz/upscale/image/transparent",
|
|
3082
|
+
task: "transparent image upscaling"
|
|
3083
|
+
},
|
|
3084
|
+
"topaz-video": {
|
|
3085
|
+
category: "upscale",
|
|
3086
|
+
defaultOptions: {
|
|
3087
|
+
model: "Proteus",
|
|
3088
|
+
upscale_factor: 2
|
|
3089
|
+
},
|
|
3090
|
+
description: "Professional Topaz video enhancement and upscaling.",
|
|
3091
|
+
endpoint: "fal-ai/topaz/upscale/video",
|
|
3092
|
+
inputField: "video_url",
|
|
3093
|
+
inputKind: "video",
|
|
3094
|
+
name: "Topaz Video Upscale",
|
|
3095
|
+
outputKeys: ["video"],
|
|
3096
|
+
price: { kind: "second", usd: 0.01 },
|
|
3097
|
+
pricing: "$0.01/sec up to 720p; $0.02 to 1080p, $0.08 above, doubled at 60fps, halved with Gaia 2",
|
|
3098
|
+
queued: true,
|
|
3099
|
+
sourceUrl: "https://fal.ai/models/fal-ai/topaz/upscale/video",
|
|
3100
|
+
task: "video enhancement"
|
|
3101
|
+
}
|
|
3102
|
+
};
|
|
3103
|
+
|
|
3104
|
+
// src/tool-registry/editing.ts
|
|
3105
|
+
var EDITING_TOOLS = {
|
|
3106
|
+
"bria-eraser": {
|
|
3107
|
+
category: "erase",
|
|
3108
|
+
description: "Commercial-safe removal of a masked region, inpainted from surrounding context.",
|
|
3109
|
+
endpoint: "fal-ai/bria/eraser",
|
|
3110
|
+
inputField: "image_url",
|
|
3111
|
+
inputKind: "image",
|
|
3112
|
+
name: "Bria Eraser",
|
|
3113
|
+
outputKeys: ["image"],
|
|
3114
|
+
price: { kind: "call", usd: 0.04 },
|
|
3115
|
+
pricing: "$0.04/generation",
|
|
3116
|
+
sourceUrl: "https://fal.ai/models/fal-ai/bria/eraser",
|
|
3117
|
+
task: "masked object erasure"
|
|
3118
|
+
},
|
|
3119
|
+
"bria-expand": {
|
|
3120
|
+
category: "reframe",
|
|
3121
|
+
description: "Expand an image onto a larger canvas, generating the new border area.",
|
|
3122
|
+
endpoint: "fal-ai/bria/expand",
|
|
3123
|
+
inputField: "image_url",
|
|
3124
|
+
inputKind: "image",
|
|
3125
|
+
name: "Bria Image Expansion",
|
|
3126
|
+
outputKeys: ["image"],
|
|
3127
|
+
price: { kind: "call", usd: 0.04 },
|
|
3128
|
+
pricing: "$0.04/generation",
|
|
3129
|
+
sourceUrl: "https://fal.ai/models/fal-ai/bria/expand",
|
|
3130
|
+
task: "image outpainting"
|
|
3131
|
+
},
|
|
3132
|
+
"bria-genfill": {
|
|
3133
|
+
category: "erase",
|
|
3134
|
+
description: "Generative fill of a masked region from a prompt, commercial-safe.",
|
|
3135
|
+
endpoint: "fal-ai/bria/genfill",
|
|
3136
|
+
inputField: "image_url",
|
|
3137
|
+
inputKind: "image",
|
|
3138
|
+
name: "Bria GenFill",
|
|
3139
|
+
outputKeys: ["images"],
|
|
3140
|
+
price: { kind: "call", usd: 0.04 },
|
|
3141
|
+
pricing: "$0.04/generation",
|
|
3142
|
+
sourceUrl: "https://fal.ai/models/fal-ai/bria/genfill",
|
|
3143
|
+
task: "masked generative fill"
|
|
3144
|
+
},
|
|
3145
|
+
"finegrain-eraser": {
|
|
3146
|
+
category: "erase",
|
|
3147
|
+
description: "Remove a prompted object and its shadows and reflections, filling the gap.",
|
|
3148
|
+
endpoint: "fal-ai/finegrain-eraser",
|
|
3149
|
+
inputField: "image_url",
|
|
3150
|
+
inputKind: "image",
|
|
3151
|
+
name: "Finegrain Object Eraser",
|
|
3152
|
+
outputKeys: ["image"],
|
|
3153
|
+
price: { kind: "call", usd: 0.27 },
|
|
3154
|
+
pricing: "$0.27/image at the default standard mode; $0.18 express, $0.36 premium",
|
|
3155
|
+
sourceUrl: "https://fal.ai/models/fal-ai/finegrain-eraser",
|
|
3156
|
+
task: "prompted object erasure"
|
|
3157
|
+
},
|
|
3158
|
+
"flux-outpaint": {
|
|
3159
|
+
category: "reframe",
|
|
3160
|
+
description: "Outpaint an image by a per-edge pixel expansion with FLUX.2 pro.",
|
|
3161
|
+
endpoint: "fal-ai/flux-2-pro/outpaint",
|
|
3162
|
+
inputField: "image_url",
|
|
3163
|
+
inputKind: "image",
|
|
3164
|
+
name: "FLUX.2 Pro Outpaint",
|
|
3165
|
+
outputKeys: ["images"],
|
|
3166
|
+
price: { kind: "metered" },
|
|
3167
|
+
pricing: "$0.03 for the first output megapixel, then $0.015 per extra megapixel of input and output, rounded up",
|
|
3168
|
+
sourceUrl: "https://fal.ai/models/fal-ai/flux-2-pro/outpaint",
|
|
3169
|
+
task: "image outpainting"
|
|
3170
|
+
},
|
|
3171
|
+
"iclight-v2": {
|
|
3172
|
+
category: "relight",
|
|
3173
|
+
description: "Relight a subject from a prompt, harmonising it with a new light direction.",
|
|
3174
|
+
endpoint: "fal-ai/iclight-v2",
|
|
3175
|
+
inputField: "image_url",
|
|
3176
|
+
inputKind: "image",
|
|
3177
|
+
name: "IC-Light v2",
|
|
3178
|
+
outputKeys: ["images"],
|
|
3179
|
+
price: { kind: "megapixel", usd: 0.1 },
|
|
3180
|
+
pricing: "$0.10/megapixel",
|
|
3181
|
+
sourceUrl: "https://fal.ai/models/fal-ai/iclight-v2",
|
|
3182
|
+
task: "prompted relighting"
|
|
3183
|
+
},
|
|
3184
|
+
"ideogram-reframe": {
|
|
3185
|
+
category: "reframe",
|
|
3186
|
+
description: "Reframe an image to a new aspect ratio, generating the fill.",
|
|
3187
|
+
endpoint: "fal-ai/ideogram/v3/reframe",
|
|
3188
|
+
inputField: "image_url",
|
|
3189
|
+
inputKind: "image",
|
|
3190
|
+
name: "Ideogram v3 Reframe",
|
|
3191
|
+
outputKeys: ["images"],
|
|
3192
|
+
price: { kind: "call", usd: 0.06 },
|
|
3193
|
+
pricing: "$0.06/image at the default BALANCED speed; $0.03 turbo, $0.09 quality",
|
|
3194
|
+
sourceUrl: "https://fal.ai/models/fal-ai/ideogram/v3/reframe",
|
|
3195
|
+
task: "aspect ratio reframing"
|
|
3196
|
+
},
|
|
3197
|
+
"lighting-restoration": {
|
|
3198
|
+
category: "relight",
|
|
3199
|
+
description: "Restore natural, even lighting across one or more input images.",
|
|
3200
|
+
endpoint: "fal-ai/qwen-image-edit-plus-lora-gallery/lighting-restoration",
|
|
3201
|
+
inputField: "image_urls",
|
|
3202
|
+
inputKind: "images",
|
|
3203
|
+
name: "Qwen Lighting Restoration",
|
|
3204
|
+
outputKeys: ["images"],
|
|
3205
|
+
price: { kind: "megapixel", usd: 0.035 },
|
|
3206
|
+
pricing: "$0.035/megapixel",
|
|
3207
|
+
sourceUrl: "https://fal.ai/models/fal-ai/qwen-image-edit-plus-lora-gallery/lighting-restoration",
|
|
3208
|
+
task: "lighting restoration"
|
|
3209
|
+
},
|
|
3210
|
+
"object-removal": {
|
|
3211
|
+
category: "erase",
|
|
3212
|
+
description: "Remove a prompted object from an image and fill the gap.",
|
|
3213
|
+
endpoint: "fal-ai/object-removal",
|
|
3214
|
+
inputField: "image_url",
|
|
3215
|
+
inputKind: "image",
|
|
3216
|
+
name: "Object Removal",
|
|
3217
|
+
outputKeys: ["images"],
|
|
3218
|
+
price: { kind: "call", usd: 0.024 },
|
|
3219
|
+
pricing: "$0.024/image at the default best quality; $0.006 low, $0.012 medium, $0.018 high",
|
|
3220
|
+
sourceUrl: "https://fal.ai/models/fal-ai/object-removal",
|
|
3221
|
+
task: "prompted object removal"
|
|
3222
|
+
},
|
|
3223
|
+
"object-removal-bbox": {
|
|
3224
|
+
category: "erase",
|
|
3225
|
+
description: "Remove whatever falls inside supplied bounding boxes.",
|
|
3226
|
+
endpoint: "fal-ai/object-removal/bbox",
|
|
3227
|
+
inputField: "image_url",
|
|
3228
|
+
inputKind: "image",
|
|
3229
|
+
name: "Object Removal by Box",
|
|
3230
|
+
outputKeys: ["images"],
|
|
3231
|
+
price: { kind: "call", usd: 0.024 },
|
|
3232
|
+
pricing: "$0.024/image at the default best quality; $0.006 low, $0.012 medium, $0.018 high",
|
|
3233
|
+
sourceUrl: "https://fal.ai/models/fal-ai/object-removal/bbox",
|
|
3234
|
+
task: "bounding box object removal"
|
|
3235
|
+
},
|
|
3236
|
+
"object-removal-mask": {
|
|
3237
|
+
category: "erase",
|
|
3238
|
+
description: "Remove the masked region of an image and fill the gap.",
|
|
3239
|
+
endpoint: "fal-ai/object-removal/mask",
|
|
3240
|
+
inputField: "image_url",
|
|
3241
|
+
inputKind: "image",
|
|
3242
|
+
name: "Object Removal by Mask",
|
|
3243
|
+
outputKeys: ["images"],
|
|
3244
|
+
price: { kind: "call", usd: 0.024 },
|
|
3245
|
+
pricing: "$0.024/image at the default best quality; $0.006 low, $0.012 medium, $0.018 high",
|
|
3246
|
+
sourceUrl: "https://fal.ai/models/fal-ai/object-removal/mask",
|
|
3247
|
+
task: "masked object removal"
|
|
3248
|
+
},
|
|
3249
|
+
"remove-lighting": {
|
|
3250
|
+
category: "relight",
|
|
3251
|
+
description: "Strip baked-in lighting and shadows to leave a flat, neutral surface.",
|
|
3252
|
+
endpoint: "fal-ai/qwen-image-edit-plus-lora-gallery/remove-lighting",
|
|
3253
|
+
inputField: "image_urls",
|
|
3254
|
+
inputKind: "images",
|
|
3255
|
+
name: "Qwen Remove Lighting",
|
|
3256
|
+
outputKeys: ["images"],
|
|
3257
|
+
price: { kind: "megapixel", usd: 0.035 },
|
|
3258
|
+
pricing: "$0.035/megapixel",
|
|
3259
|
+
sourceUrl: "https://fal.ai/models/fal-ai/qwen-image-edit-plus-lora-gallery/remove-lighting",
|
|
3260
|
+
task: "lighting removal"
|
|
3261
|
+
},
|
|
3262
|
+
"smart-resize": {
|
|
3263
|
+
category: "reframe",
|
|
3264
|
+
description: "Resize one image to several target sizes, recomposing rather than cropping.",
|
|
3265
|
+
endpoint: "fal-ai/smart-resize",
|
|
3266
|
+
inputField: "image_url",
|
|
3267
|
+
inputKind: "image",
|
|
3268
|
+
name: "Smart Resize",
|
|
3269
|
+
outputKeys: ["images", "results"],
|
|
3270
|
+
price: { kind: "metered" },
|
|
3271
|
+
pricing: "$0.15 per output image, doubled at 4K, plus a $0.05 vision analysis fee per request",
|
|
3272
|
+
queued: true,
|
|
3273
|
+
sourceUrl: "https://fal.ai/models/fal-ai/smart-resize",
|
|
3274
|
+
task: "multi-size recomposition"
|
|
3275
|
+
},
|
|
3276
|
+
"text-removal": {
|
|
3277
|
+
category: "erase",
|
|
3278
|
+
defaultOptions: {
|
|
3279
|
+
output_format: "png"
|
|
3280
|
+
},
|
|
3281
|
+
description: "Remove all rendered text from an image, rebuilding what sat behind it.",
|
|
3282
|
+
endpoint: "fal-ai/image-editing/text-removal",
|
|
3283
|
+
inputField: "image_url",
|
|
3284
|
+
inputKind: "image",
|
|
3285
|
+
name: "Text Removal",
|
|
3286
|
+
outputKeys: ["images"],
|
|
3287
|
+
price: { kind: "call", usd: 0.04 },
|
|
3288
|
+
pricing: "$0.04/image",
|
|
3289
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-editing/text-removal",
|
|
3290
|
+
task: "text removal"
|
|
3291
|
+
}
|
|
3292
|
+
};
|
|
3293
|
+
|
|
3294
|
+
// src/tool-registry/structure.ts
|
|
3295
|
+
var STRUCTURE_TOOLS = {
|
|
2401
3296
|
"depth-anything": {
|
|
2402
3297
|
category: "preprocess",
|
|
2403
3298
|
description: "Generate Depth Anything v2 depth maps from input images.",
|
|
@@ -2406,10 +3301,37 @@ var FAL_TOOLS = {
|
|
|
2406
3301
|
inputKind: "image",
|
|
2407
3302
|
name: "Depth Anything v2 Preprocessor",
|
|
2408
3303
|
outputKeys: ["image"],
|
|
3304
|
+
price: { kind: "metered" },
|
|
2409
3305
|
pricing: "$0/compute-second listed by fal",
|
|
2410
3306
|
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/depth-anything/v2",
|
|
2411
3307
|
task: "depth preprocessing"
|
|
2412
3308
|
},
|
|
3309
|
+
dwpose: {
|
|
3310
|
+
category: "preprocess",
|
|
3311
|
+
description: "Extract body, hand, and face pose skeletons from an image.",
|
|
3312
|
+
endpoint: "fal-ai/dwpose",
|
|
3313
|
+
inputField: "image_url",
|
|
3314
|
+
inputKind: "image",
|
|
3315
|
+
name: "DWPose Estimation",
|
|
3316
|
+
outputKeys: ["image"],
|
|
3317
|
+
price: { kind: "second", usd: 6e-4 },
|
|
3318
|
+
pricing: "$0.0006/compute-second",
|
|
3319
|
+
sourceUrl: "https://fal.ai/models/fal-ai/dwpose",
|
|
3320
|
+
task: "pose preprocessing"
|
|
3321
|
+
},
|
|
3322
|
+
hed: {
|
|
3323
|
+
category: "preprocess",
|
|
3324
|
+
description: "Generate HED soft edge maps for ControlNet-style workflows.",
|
|
3325
|
+
endpoint: "fal-ai/image-preprocessors/hed",
|
|
3326
|
+
inputField: "image_url",
|
|
3327
|
+
inputKind: "image",
|
|
3328
|
+
name: "HED Edge Preprocessor",
|
|
3329
|
+
outputKeys: ["image"],
|
|
3330
|
+
price: { kind: "metered" },
|
|
3331
|
+
pricing: "$0/compute-second listed by fal",
|
|
3332
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/hed",
|
|
3333
|
+
task: "edge preprocessing"
|
|
3334
|
+
},
|
|
2413
3335
|
lineart: {
|
|
2414
3336
|
category: "preprocess",
|
|
2415
3337
|
defaultOptions: {
|
|
@@ -2421,6 +3343,7 @@ var FAL_TOOLS = {
|
|
|
2421
3343
|
inputKind: "image",
|
|
2422
3344
|
name: "Line Art Preprocessor",
|
|
2423
3345
|
outputKeys: ["image"],
|
|
3346
|
+
price: { kind: "metered" },
|
|
2424
3347
|
pricing: "$0/compute-second listed by fal",
|
|
2425
3348
|
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/lineart",
|
|
2426
3349
|
task: "image preprocessing"
|
|
@@ -2437,6 +3360,7 @@ var FAL_TOOLS = {
|
|
|
2437
3360
|
inputKind: "image",
|
|
2438
3361
|
name: "Marigold Depth Estimation",
|
|
2439
3362
|
outputKeys: ["image"],
|
|
3363
|
+
price: { kind: "metered" },
|
|
2440
3364
|
pricing: "$0/compute-second listed by fal",
|
|
2441
3365
|
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/marigold-depth",
|
|
2442
3366
|
task: "depth map"
|
|
@@ -2453,6 +3377,7 @@ var FAL_TOOLS = {
|
|
|
2453
3377
|
inputKind: "image",
|
|
2454
3378
|
name: "MiDaS Depth Estimation",
|
|
2455
3379
|
outputKeys: ["image"],
|
|
3380
|
+
price: { kind: "metered" },
|
|
2456
3381
|
pricing: "$0/compute-second listed by fal",
|
|
2457
3382
|
sourceUrl: "https://fal.ai/models/fal-ai/imageutils/depth",
|
|
2458
3383
|
task: "depth map"
|
|
@@ -2465,36 +3390,36 @@ var FAL_TOOLS = {
|
|
|
2465
3390
|
inputKind: "image",
|
|
2466
3391
|
name: "MiDaS Preprocessor",
|
|
2467
3392
|
outputKeys: ["depth_map", "normal_map"],
|
|
3393
|
+
price: { kind: "metered" },
|
|
2468
3394
|
pricing: "$0/compute-second listed by fal",
|
|
2469
3395
|
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/midas",
|
|
2470
3396
|
task: "depth and normal preprocessing"
|
|
2471
3397
|
},
|
|
2472
|
-
|
|
2473
|
-
category: "
|
|
2474
|
-
description: "
|
|
2475
|
-
endpoint: "fal-ai/
|
|
2476
|
-
inputField: "
|
|
2477
|
-
inputKind: "
|
|
2478
|
-
name: "
|
|
2479
|
-
outputKeys: ["
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
3398
|
+
mlsd: {
|
|
3399
|
+
category: "preprocess",
|
|
3400
|
+
description: "Detect straight line segments for architectural and interior control maps.",
|
|
3401
|
+
endpoint: "fal-ai/image-preprocessors/mlsd",
|
|
3402
|
+
inputField: "image_url",
|
|
3403
|
+
inputKind: "image",
|
|
3404
|
+
name: "M-LSD Line Preprocessor",
|
|
3405
|
+
outputKeys: ["image"],
|
|
3406
|
+
price: { kind: "metered" },
|
|
3407
|
+
pricing: "$0/compute-second listed by fal",
|
|
3408
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/mlsd",
|
|
3409
|
+
task: "line segment preprocessing"
|
|
2483
3410
|
},
|
|
2484
|
-
|
|
2485
|
-
category: "
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
},
|
|
2489
|
-
description: "Generic image background removal utility.",
|
|
2490
|
-
endpoint: "fal-ai/imageutils/rembg",
|
|
3411
|
+
pidi: {
|
|
3412
|
+
category: "preprocess",
|
|
3413
|
+
description: "Generate PiDiNet soft edge maps from an input image.",
|
|
3414
|
+
endpoint: "fal-ai/image-preprocessors/pidi",
|
|
2491
3415
|
inputField: "image_url",
|
|
2492
3416
|
inputKind: "image",
|
|
2493
|
-
name: "
|
|
3417
|
+
name: "PiDiNet Edge Preprocessor",
|
|
2494
3418
|
outputKeys: ["image"],
|
|
3419
|
+
price: { kind: "metered" },
|
|
2495
3420
|
pricing: "$0/compute-second listed by fal",
|
|
2496
|
-
sourceUrl: "https://fal.ai/models/fal-ai/
|
|
2497
|
-
task: "
|
|
3421
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/pidi",
|
|
3422
|
+
task: "edge preprocessing"
|
|
2498
3423
|
},
|
|
2499
3424
|
"sam-preprocessor": {
|
|
2500
3425
|
category: "preprocess",
|
|
@@ -2504,6 +3429,7 @@ var FAL_TOOLS = {
|
|
|
2504
3429
|
inputKind: "image",
|
|
2505
3430
|
name: "SAM Preprocessor",
|
|
2506
3431
|
outputKeys: ["image"],
|
|
3432
|
+
price: { kind: "metered" },
|
|
2507
3433
|
pricing: "$0/compute-second listed by fal",
|
|
2508
3434
|
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/sam",
|
|
2509
3435
|
task: "segmentation preprocessing"
|
|
@@ -2523,7 +3449,9 @@ var FAL_TOOLS = {
|
|
|
2523
3449
|
inputKind: "image",
|
|
2524
3450
|
name: "SAM 2 Auto Segment",
|
|
2525
3451
|
outputKeys: ["combined_mask", "individual_masks"],
|
|
3452
|
+
price: { kind: "metered" },
|
|
2526
3453
|
pricing: "$0/compute-second listed by fal",
|
|
3454
|
+
queued: true,
|
|
2527
3455
|
sourceUrl: "https://fal.ai/models/fal-ai/sam2/auto-segment",
|
|
2528
3456
|
task: "automatic image segmentation"
|
|
2529
3457
|
},
|
|
@@ -2540,7 +3468,8 @@ var FAL_TOOLS = {
|
|
|
2540
3468
|
inputKind: "image",
|
|
2541
3469
|
name: "SAM 3.1 Image",
|
|
2542
3470
|
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2543
|
-
|
|
3471
|
+
price: { kind: "call", usd: 0.01 },
|
|
3472
|
+
pricing: "$0.01/request",
|
|
2544
3473
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image",
|
|
2545
3474
|
task: "promptable image segmentation"
|
|
2546
3475
|
},
|
|
@@ -2556,61 +3485,12 @@ var FAL_TOOLS = {
|
|
|
2556
3485
|
inputKind: "video",
|
|
2557
3486
|
name: "SAM 3.1 Video",
|
|
2558
3487
|
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2559
|
-
|
|
3488
|
+
price: { kind: "metered" },
|
|
3489
|
+
pricing: "$0.01/16 frames of video input",
|
|
3490
|
+
queued: true,
|
|
2560
3491
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/video",
|
|
2561
3492
|
task: "multi-object video segmentation"
|
|
2562
3493
|
},
|
|
2563
|
-
"sam3-3d-align": {
|
|
2564
|
-
category: "3d",
|
|
2565
|
-
description: "Align SAM 3D objects and bodies into a shared scene.",
|
|
2566
|
-
endpoint: "fal-ai/sam-3/3d-align",
|
|
2567
|
-
inputField: "image_url",
|
|
2568
|
-
inputKind: "image",
|
|
2569
|
-
name: "SAM 3D Align",
|
|
2570
|
-
outputKeys: ["scene_glb", "metadata", "artifacts_zip"],
|
|
2571
|
-
pricing: "fal pricing varies by scene",
|
|
2572
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-align",
|
|
2573
|
-
task: "3D scene alignment"
|
|
2574
|
-
},
|
|
2575
|
-
"sam3-3d-body": {
|
|
2576
|
-
category: "3d",
|
|
2577
|
-
defaultOptions: {
|
|
2578
|
-
export_meshes: true,
|
|
2579
|
-
include_3d_keypoints: true,
|
|
2580
|
-
include_mhr_params: true
|
|
2581
|
-
},
|
|
2582
|
-
description: "Reconstruct human body meshes and keypoints from a single image.",
|
|
2583
|
-
endpoint: "fal-ai/sam-3/3d-body",
|
|
2584
|
-
inputField: "image_url",
|
|
2585
|
-
inputKind: "image",
|
|
2586
|
-
name: "SAM 3D Body",
|
|
2587
|
-
outputKeys: ["model_glb", "visualization", "meshes", "metadata"],
|
|
2588
|
-
pricing: "$0.015/inference",
|
|
2589
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-body",
|
|
2590
|
-
task: "single-image 3D body reconstruction"
|
|
2591
|
-
},
|
|
2592
|
-
"sam3-3d-objects": {
|
|
2593
|
-
category: "3d",
|
|
2594
|
-
defaultOptions: {
|
|
2595
|
-
prompt: "car"
|
|
2596
|
-
},
|
|
2597
|
-
description: "Reconstruct one or more 3D objects from an image and prompts.",
|
|
2598
|
-
endpoint: "fal-ai/sam-3/3d-objects",
|
|
2599
|
-
inputField: "image_url",
|
|
2600
|
-
inputKind: "image",
|
|
2601
|
-
name: "SAM 3D Objects",
|
|
2602
|
-
outputKeys: [
|
|
2603
|
-
"gaussian_splat",
|
|
2604
|
-
"model_glb",
|
|
2605
|
-
"metadata",
|
|
2606
|
-
"individual_splats",
|
|
2607
|
-
"individual_glbs",
|
|
2608
|
-
"artifacts_zip"
|
|
2609
|
-
],
|
|
2610
|
-
pricing: "$0.02/generation",
|
|
2611
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/3d-objects",
|
|
2612
|
-
task: "single-image 3D object reconstruction"
|
|
2613
|
-
},
|
|
2614
3494
|
"sam3-image": {
|
|
2615
3495
|
category: "segmentation",
|
|
2616
3496
|
defaultOptions: {
|
|
@@ -2624,6 +3504,7 @@ var FAL_TOOLS = {
|
|
|
2624
3504
|
inputKind: "image",
|
|
2625
3505
|
name: "SAM 3 Image",
|
|
2626
3506
|
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
3507
|
+
price: { kind: "call", usd: 5e-3 },
|
|
2627
3508
|
pricing: "$0.005/request",
|
|
2628
3509
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/image",
|
|
2629
3510
|
task: "promptable image segmentation"
|
|
@@ -2639,7 +3520,8 @@ var FAL_TOOLS = {
|
|
|
2639
3520
|
inputField: "image_url",
|
|
2640
3521
|
inputKind: "image",
|
|
2641
3522
|
name: "SAM 3 Image RLE",
|
|
2642
|
-
outputKeys: ["
|
|
3523
|
+
outputKeys: ["rle", "scores", "boxes", "metadata"],
|
|
3524
|
+
price: { kind: "call", usd: 5e-3 },
|
|
2643
3525
|
pricing: "$0.005/request",
|
|
2644
3526
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/image-rle",
|
|
2645
3527
|
task: "promptable image segmentation to RLE"
|
|
@@ -2658,7 +3540,9 @@ var FAL_TOOLS = {
|
|
|
2658
3540
|
inputKind: "video",
|
|
2659
3541
|
name: "SAM 3 Video",
|
|
2660
3542
|
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
2661
|
-
|
|
3543
|
+
price: { kind: "metered" },
|
|
3544
|
+
pricing: "$0.005/16 frames of video input",
|
|
3545
|
+
queued: true,
|
|
2662
3546
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/video",
|
|
2663
3547
|
task: "promptable video segmentation"
|
|
2664
3548
|
},
|
|
@@ -2674,45 +3558,65 @@ var FAL_TOOLS = {
|
|
|
2674
3558
|
inputField: "video_url",
|
|
2675
3559
|
inputKind: "video",
|
|
2676
3560
|
name: "SAM 3 Video RLE",
|
|
2677
|
-
|
|
2678
|
-
|
|
3561
|
+
// fal's video-rle endpoint no longer returns RLE data: its Output schema is
|
|
3562
|
+
// now identical to sam3-video's, so this entry differs only by endpoint.
|
|
3563
|
+
outputKeys: ["video", "boundingbox_frames_zip"],
|
|
3564
|
+
price: { kind: "metered" },
|
|
3565
|
+
pricing: "$0.005/16 frames of video",
|
|
3566
|
+
queued: true,
|
|
2679
3567
|
sourceUrl: "https://fal.ai/models/fal-ai/sam-3/video-rle",
|
|
2680
3568
|
task: "promptable video segmentation to RLE"
|
|
2681
3569
|
},
|
|
2682
|
-
|
|
2683
|
-
category: "
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
output_format: "jpeg",
|
|
2687
|
-
upscale_factor: 2
|
|
2688
|
-
},
|
|
2689
|
-
description: "Professional Topaz image enhancement and upscaling.",
|
|
2690
|
-
endpoint: "fal-ai/topaz/upscale/image",
|
|
3570
|
+
scribble: {
|
|
3571
|
+
category: "preprocess",
|
|
3572
|
+
description: "Turn an image into a scribble-style control map.",
|
|
3573
|
+
endpoint: "fal-ai/image-preprocessors/scribble",
|
|
2691
3574
|
inputField: "image_url",
|
|
2692
3575
|
inputKind: "image",
|
|
2693
|
-
name: "
|
|
3576
|
+
name: "Scribble Preprocessor",
|
|
2694
3577
|
outputKeys: ["image"],
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
3578
|
+
price: { kind: "metered" },
|
|
3579
|
+
pricing: "$0/compute-second listed by fal",
|
|
3580
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/scribble",
|
|
3581
|
+
task: "scribble preprocessing"
|
|
2698
3582
|
},
|
|
2699
|
-
|
|
2700
|
-
category: "
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
3583
|
+
teed: {
|
|
3584
|
+
category: "preprocess",
|
|
3585
|
+
description: "Generate TEED edge maps from an input image.",
|
|
3586
|
+
endpoint: "fal-ai/image-preprocessors/teed",
|
|
3587
|
+
inputField: "image_url",
|
|
3588
|
+
inputKind: "image",
|
|
3589
|
+
name: "TEED Edge Preprocessor",
|
|
3590
|
+
outputKeys: ["image"],
|
|
3591
|
+
price: { kind: "metered" },
|
|
3592
|
+
pricing: "$0/compute-second listed by fal",
|
|
3593
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/teed",
|
|
3594
|
+
task: "edge preprocessing"
|
|
3595
|
+
},
|
|
3596
|
+
"zoe-depth": {
|
|
3597
|
+
category: "preprocess",
|
|
3598
|
+
description: "Generate ZoeDepth metric depth maps from an input image.",
|
|
3599
|
+
endpoint: "fal-ai/image-preprocessors/zoe",
|
|
3600
|
+
inputField: "image_url",
|
|
3601
|
+
inputKind: "image",
|
|
3602
|
+
name: "ZoeDepth Preprocessor",
|
|
3603
|
+
outputKeys: ["image"],
|
|
3604
|
+
price: { kind: "metered" },
|
|
3605
|
+
pricing: "$0/compute-second listed by fal",
|
|
3606
|
+
sourceUrl: "https://fal.ai/models/fal-ai/image-preprocessors/zoe",
|
|
3607
|
+
task: "depth preprocessing"
|
|
2714
3608
|
}
|
|
2715
3609
|
};
|
|
3610
|
+
|
|
3611
|
+
// src/tools.ts
|
|
3612
|
+
var FAL_EXPLORE_CHECKED_AT = "2026-08-23";
|
|
3613
|
+
var FAL_TOOLS = {
|
|
3614
|
+
...ANALYSIS_TOOLS,
|
|
3615
|
+
...ASSET_TOOLS,
|
|
3616
|
+
...BACKGROUND_TOOLS,
|
|
3617
|
+
...EDITING_TOOLS,
|
|
3618
|
+
...STRUCTURE_TOOLS
|
|
3619
|
+
};
|
|
2716
3620
|
var FAL_TOOLS_CHECKED_AT = FAL_EXPLORE_CHECKED_AT;
|
|
2717
3621
|
var FAL_TOOL_IDS = Object.keys(
|
|
2718
3622
|
FAL_TOOLS
|
|
@@ -2739,9 +3643,110 @@ function buildFalToolRequest(options) {
|
|
|
2739
3643
|
return { body, endpoint: tool.endpoint, tool };
|
|
2740
3644
|
}
|
|
2741
3645
|
|
|
2742
|
-
// src/server.ts
|
|
3646
|
+
// src/server-tools.ts
|
|
2743
3647
|
var FAL_BASE_URL = "https://fal.run";
|
|
2744
3648
|
var FAL_QUEUE_URL = "https://queue.fal.run";
|
|
3649
|
+
var POLL_INTERVAL_MS = 3e3;
|
|
3650
|
+
var MAX_POLL_ATTEMPTS = 160;
|
|
3651
|
+
function buildToolRequest(options) {
|
|
3652
|
+
try {
|
|
3653
|
+
return (0, import_neverthrow.ok)(buildFalToolRequest(options));
|
|
3654
|
+
} catch (error) {
|
|
3655
|
+
return (0, import_neverthrow.err)(
|
|
3656
|
+
new MotifError(error instanceof Error ? error.message : String(error), 0)
|
|
3657
|
+
);
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
async function runTool(exec, options) {
|
|
3661
|
+
const request = buildToolRequest(options);
|
|
3662
|
+
if (request.isErr()) {
|
|
3663
|
+
return (0, import_neverthrow.err)(request.error);
|
|
3664
|
+
}
|
|
3665
|
+
const response = await exec.request(
|
|
3666
|
+
`${FAL_BASE_URL}/${request.value.endpoint}`,
|
|
3667
|
+
{
|
|
3668
|
+
body: JSON.stringify(request.value.body),
|
|
3669
|
+
method: "POST"
|
|
3670
|
+
}
|
|
3671
|
+
);
|
|
3672
|
+
if (response.isErr()) {
|
|
3673
|
+
return (0, import_neverthrow.err)(response.error);
|
|
3674
|
+
}
|
|
3675
|
+
const data = await response.value.json();
|
|
3676
|
+
return (0, import_neverthrow.ok)(isRecord(data) ? data : {});
|
|
3677
|
+
}
|
|
3678
|
+
async function submitTool(exec, options) {
|
|
3679
|
+
const request = buildToolRequest(options);
|
|
3680
|
+
if (request.isErr()) {
|
|
3681
|
+
return (0, import_neverthrow.err)(request.error);
|
|
3682
|
+
}
|
|
3683
|
+
const response = await exec.request(
|
|
3684
|
+
`${FAL_QUEUE_URL}/${request.value.endpoint}`,
|
|
3685
|
+
{
|
|
3686
|
+
body: JSON.stringify(request.value.body),
|
|
3687
|
+
method: "POST"
|
|
3688
|
+
}
|
|
3689
|
+
);
|
|
3690
|
+
if (response.isErr()) {
|
|
3691
|
+
return (0, import_neverthrow.err)(response.error);
|
|
3692
|
+
}
|
|
3693
|
+
const data = await response.value.json();
|
|
3694
|
+
const submission = parseQueueSubmission(data);
|
|
3695
|
+
return (0, import_neverthrow.ok)({
|
|
3696
|
+
endpoint: endpointFromQueueUrl(
|
|
3697
|
+
submission.responseUrl,
|
|
3698
|
+
request.value.endpoint
|
|
3699
|
+
),
|
|
3700
|
+
requestId: submission.requestId
|
|
3701
|
+
});
|
|
3702
|
+
}
|
|
3703
|
+
async function checkToolStatus(exec, job) {
|
|
3704
|
+
return await exec.getJobStatus(job.endpoint, job.requestId);
|
|
3705
|
+
}
|
|
3706
|
+
async function getToolResult(exec, job) {
|
|
3707
|
+
const url = `${FAL_QUEUE_URL}/${job.endpoint}/requests/${job.requestId}`;
|
|
3708
|
+
const response = await exec.request(url);
|
|
3709
|
+
if (response.isErr()) {
|
|
3710
|
+
return (0, import_neverthrow.err)(response.error);
|
|
3711
|
+
}
|
|
3712
|
+
const data = await response.value.json();
|
|
3713
|
+
return (0, import_neverthrow.ok)(isRecord(data) ? data : {});
|
|
3714
|
+
}
|
|
3715
|
+
async function runToolQueued(exec, options, onProgress) {
|
|
3716
|
+
const job = await submitTool(exec, options);
|
|
3717
|
+
if (job.isErr()) {
|
|
3718
|
+
return (0, import_neverthrow.err)(job.error);
|
|
3719
|
+
}
|
|
3720
|
+
for (let attempt = 0; attempt < MAX_POLL_ATTEMPTS; attempt++) {
|
|
3721
|
+
const status = await checkToolStatus(exec, job.value);
|
|
3722
|
+
if (status.isErr()) {
|
|
3723
|
+
return (0, import_neverthrow.err)(status.error);
|
|
3724
|
+
}
|
|
3725
|
+
onProgress?.(status.value.status, status.value.queuePosition);
|
|
3726
|
+
if (status.value.status === "completed") {
|
|
3727
|
+
return await getToolResult(exec, job.value);
|
|
3728
|
+
}
|
|
3729
|
+
if (status.value.status === "failed") {
|
|
3730
|
+
const message = status.value.error ?? "Queued tool run failed";
|
|
3731
|
+
return (0, import_neverthrow.err)(new MotifError(message, 0, void 0, job.value.requestId));
|
|
3732
|
+
}
|
|
3733
|
+
await new Promise((resolve) => {
|
|
3734
|
+
setTimeout(resolve, POLL_INTERVAL_MS);
|
|
3735
|
+
});
|
|
3736
|
+
}
|
|
3737
|
+
return (0, import_neverthrow.err)(
|
|
3738
|
+
new MotifError(
|
|
3739
|
+
"Queued tool run timed out",
|
|
3740
|
+
0,
|
|
3741
|
+
void 0,
|
|
3742
|
+
job.value.requestId
|
|
3743
|
+
)
|
|
3744
|
+
);
|
|
3745
|
+
}
|
|
3746
|
+
|
|
3747
|
+
// src/server.ts
|
|
3748
|
+
var FAL_BASE_URL2 = "https://fal.run";
|
|
3749
|
+
var FAL_QUEUE_URL2 = "https://queue.fal.run";
|
|
2745
3750
|
var FAL_API_URL = "https://api.fal.ai";
|
|
2746
3751
|
var FAL_REST_URL = "https://rest.alpha.fal.ai";
|
|
2747
3752
|
var FalClient = class {
|
|
@@ -2773,16 +3778,16 @@ var FalClient = class {
|
|
|
2773
3778
|
try {
|
|
2774
3779
|
built = buildGenerateBody(options);
|
|
2775
3780
|
} catch (error) {
|
|
2776
|
-
return (0,
|
|
3781
|
+
return (0, import_neverthrow2.err)(toMotifError(error));
|
|
2777
3782
|
}
|
|
2778
3783
|
const { endpoint, body } = built;
|
|
2779
|
-
const response = await this.request(`${
|
|
3784
|
+
const response = await this.request(`${FAL_BASE_URL2}/${endpoint}`, {
|
|
2780
3785
|
body: JSON.stringify(body),
|
|
2781
3786
|
headers: this.ephemeralHeaders(options),
|
|
2782
3787
|
method: "POST"
|
|
2783
3788
|
});
|
|
2784
3789
|
if (response.isErr()) {
|
|
2785
|
-
return (0,
|
|
3790
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2786
3791
|
}
|
|
2787
3792
|
const data = await response.value.json();
|
|
2788
3793
|
return this.normalizeResponse(data);
|
|
@@ -2790,7 +3795,7 @@ var FalClient = class {
|
|
|
2790
3795
|
async generateQueued(options) {
|
|
2791
3796
|
const job = await this.submitGeneration(options);
|
|
2792
3797
|
if (job.isErr()) {
|
|
2793
|
-
return (0,
|
|
3798
|
+
return (0, import_neverthrow2.err)(job.error);
|
|
2794
3799
|
}
|
|
2795
3800
|
const pollIntervalMs = 3e3;
|
|
2796
3801
|
const maxAttempts = 160;
|
|
@@ -2800,20 +3805,20 @@ var FalClient = class {
|
|
|
2800
3805
|
job.value.requestId
|
|
2801
3806
|
);
|
|
2802
3807
|
if (status.isErr()) {
|
|
2803
|
-
return (0,
|
|
3808
|
+
return (0, import_neverthrow2.err)(status.error);
|
|
2804
3809
|
}
|
|
2805
3810
|
if (status.value.status === "completed") {
|
|
2806
3811
|
return await this.getJobResult(job.value.endpoint, job.value.requestId);
|
|
2807
3812
|
}
|
|
2808
3813
|
if (status.value.status === "failed") {
|
|
2809
3814
|
const message = status.value.error ?? "Queued generation failed";
|
|
2810
|
-
return (0,
|
|
3815
|
+
return (0, import_neverthrow2.err)(new MotifError(message, 0, void 0, job.value.requestId));
|
|
2811
3816
|
}
|
|
2812
3817
|
await new Promise((resolve) => {
|
|
2813
3818
|
setTimeout(resolve, pollIntervalMs);
|
|
2814
3819
|
});
|
|
2815
3820
|
}
|
|
2816
|
-
return (0,
|
|
3821
|
+
return (0, import_neverthrow2.err)(new MotifError("Queued generation timed out", 0));
|
|
2817
3822
|
}
|
|
2818
3823
|
/** ─── Queue-Based Generation ──────────────────────────────── */
|
|
2819
3824
|
/** Submit a generation to the fal.ai queue (returns immediately). */
|
|
@@ -2822,20 +3827,20 @@ var FalClient = class {
|
|
|
2822
3827
|
try {
|
|
2823
3828
|
built = buildGenerateBody(options);
|
|
2824
3829
|
} catch (error) {
|
|
2825
|
-
return (0,
|
|
3830
|
+
return (0, import_neverthrow2.err)(toMotifError(error));
|
|
2826
3831
|
}
|
|
2827
3832
|
const { endpoint, body } = built;
|
|
2828
|
-
const response = await this.request(`${
|
|
3833
|
+
const response = await this.request(`${FAL_QUEUE_URL2}/${endpoint}`, {
|
|
2829
3834
|
body: JSON.stringify(body),
|
|
2830
3835
|
headers: this.ephemeralHeaders(options),
|
|
2831
3836
|
method: "POST"
|
|
2832
3837
|
});
|
|
2833
3838
|
if (response.isErr()) {
|
|
2834
|
-
return (0,
|
|
3839
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2835
3840
|
}
|
|
2836
3841
|
const data = await response.value.json();
|
|
2837
3842
|
const submission = parseQueueSubmission(data);
|
|
2838
|
-
return (0,
|
|
3843
|
+
return (0, import_neverthrow2.ok)({
|
|
2839
3844
|
endpoint: endpointFromQueueUrl(submission.responseUrl, endpoint),
|
|
2840
3845
|
estimatedCost: estimateCost(
|
|
2841
3846
|
options.model,
|
|
@@ -2847,10 +3852,10 @@ var FalClient = class {
|
|
|
2847
3852
|
}
|
|
2848
3853
|
/** Check the status of a queued generation. */
|
|
2849
3854
|
async getJobStatus(endpoint, requestId) {
|
|
2850
|
-
const url = `${
|
|
3855
|
+
const url = `${FAL_QUEUE_URL2}/${endpoint}/requests/${requestId}/status?logs=1`;
|
|
2851
3856
|
const response = await this.request(url);
|
|
2852
3857
|
if (response.isErr()) {
|
|
2853
|
-
return (0,
|
|
3858
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2854
3859
|
}
|
|
2855
3860
|
const data = await response.value.json();
|
|
2856
3861
|
const record = isRecord(data) ? data : {};
|
|
@@ -2865,9 +3870,9 @@ var FalClient = class {
|
|
|
2865
3870
|
} else if (rawStatus === "FAILED" || rawStatus === "ERROR" || rawStatus === "CANCELED") {
|
|
2866
3871
|
status = "failed";
|
|
2867
3872
|
} else {
|
|
2868
|
-
return (0,
|
|
3873
|
+
return (0, import_neverthrow2.err)(new MotifError(`Unknown job status: ${rawStatus}`, 0));
|
|
2869
3874
|
}
|
|
2870
|
-
return (0,
|
|
3875
|
+
return (0, import_neverthrow2.ok)({
|
|
2871
3876
|
error: asString(record.error) ?? asString(record.detail),
|
|
2872
3877
|
logs: parseLogs(record.logs),
|
|
2873
3878
|
queuePosition: asNumber(record.queue_position),
|
|
@@ -2876,10 +3881,10 @@ var FalClient = class {
|
|
|
2876
3881
|
}
|
|
2877
3882
|
/** Fetch the completed result from the queue. */
|
|
2878
3883
|
async getJobResult(endpoint, requestId) {
|
|
2879
|
-
const url = `${
|
|
3884
|
+
const url = `${FAL_QUEUE_URL2}/${endpoint}/requests/${requestId}`;
|
|
2880
3885
|
const response = await this.request(url);
|
|
2881
3886
|
if (response.isErr()) {
|
|
2882
|
-
return (0,
|
|
3887
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2883
3888
|
}
|
|
2884
3889
|
const data = await response.value.json();
|
|
2885
3890
|
return this.normalizeResponse(data, requestId);
|
|
@@ -2900,7 +3905,7 @@ var FalClient = class {
|
|
|
2900
3905
|
} = options;
|
|
2901
3906
|
const config = MODELS[model];
|
|
2902
3907
|
if (!config || config.type !== "utility") {
|
|
2903
|
-
return (0,
|
|
3908
|
+
return (0, import_neverthrow2.err)(new MotifError(`Invalid upscale model: ${model}`, 0));
|
|
2904
3909
|
}
|
|
2905
3910
|
const body = { image_url: imageUrl };
|
|
2906
3911
|
if (model === "crystal") {
|
|
@@ -2933,12 +3938,12 @@ var FalClient = class {
|
|
|
2933
3938
|
body.guidance_scale = guidanceScale;
|
|
2934
3939
|
}
|
|
2935
3940
|
}
|
|
2936
|
-
const response = await this.request(`${
|
|
3941
|
+
const response = await this.request(`${FAL_BASE_URL2}/${config.endpoint}`, {
|
|
2937
3942
|
body: JSON.stringify(body),
|
|
2938
3943
|
method: "POST"
|
|
2939
3944
|
});
|
|
2940
3945
|
if (response.isErr()) {
|
|
2941
|
-
return (0,
|
|
3946
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2942
3947
|
}
|
|
2943
3948
|
const data = await response.value.json();
|
|
2944
3949
|
return this.normalizeResponse(data);
|
|
@@ -2956,7 +3961,7 @@ var FalClient = class {
|
|
|
2956
3961
|
} = options;
|
|
2957
3962
|
const config = MODELS[model];
|
|
2958
3963
|
if (!config) {
|
|
2959
|
-
return (0,
|
|
3964
|
+
return (0, import_neverthrow2.err)(
|
|
2960
3965
|
new MotifError(`Invalid background removal model: ${model}`, 0)
|
|
2961
3966
|
);
|
|
2962
3967
|
}
|
|
@@ -2978,12 +3983,12 @@ var FalClient = class {
|
|
|
2978
3983
|
rbBody.output_mask = outputMask;
|
|
2979
3984
|
}
|
|
2980
3985
|
}
|
|
2981
|
-
const response = await this.request(`${
|
|
3986
|
+
const response = await this.request(`${FAL_BASE_URL2}/${config.endpoint}`, {
|
|
2982
3987
|
body: JSON.stringify(rbBody),
|
|
2983
3988
|
method: "POST"
|
|
2984
3989
|
});
|
|
2985
3990
|
if (response.isErr()) {
|
|
2986
|
-
return (0,
|
|
3991
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
2987
3992
|
}
|
|
2988
3993
|
const data = await response.value.json();
|
|
2989
3994
|
return this.normalizeResponse(data);
|
|
@@ -3006,7 +4011,7 @@ var FalClient = class {
|
|
|
3006
4011
|
} = options;
|
|
3007
4012
|
const config = MODELS.kling;
|
|
3008
4013
|
if (!config) {
|
|
3009
|
-
return (0,
|
|
4014
|
+
return (0, import_neverthrow2.err)(new MotifError("Kling video model not found", 0));
|
|
3010
4015
|
}
|
|
3011
4016
|
const body = {
|
|
3012
4017
|
duration: String(duration),
|
|
@@ -3023,16 +4028,16 @@ var FalClient = class {
|
|
|
3023
4028
|
if (cfgScale !== void 0) {
|
|
3024
4029
|
body.cfg_scale = cfgScale;
|
|
3025
4030
|
}
|
|
3026
|
-
const response = await this.request(`${
|
|
4031
|
+
const response = await this.request(`${FAL_QUEUE_URL2}/${config.endpoint}`, {
|
|
3027
4032
|
body: JSON.stringify(body),
|
|
3028
4033
|
method: "POST"
|
|
3029
4034
|
});
|
|
3030
4035
|
if (response.isErr()) {
|
|
3031
|
-
return (0,
|
|
4036
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
3032
4037
|
}
|
|
3033
4038
|
const data = await response.value.json();
|
|
3034
4039
|
const submission = parseQueueSubmission(data);
|
|
3035
|
-
return (0,
|
|
4040
|
+
return (0, import_neverthrow2.ok)({
|
|
3036
4041
|
endpoint: endpointFromQueueUrl(submission.responseUrl, config.endpoint),
|
|
3037
4042
|
estimatedCost: estimateVideoCost(duration, generateAudio),
|
|
3038
4043
|
requestId: submission.requestId
|
|
@@ -3040,17 +4045,17 @@ var FalClient = class {
|
|
|
3040
4045
|
}
|
|
3041
4046
|
/** Fetch the completed video result from the queue. */
|
|
3042
4047
|
async getVideoResult(endpoint, requestId) {
|
|
3043
|
-
const url = `${
|
|
4048
|
+
const url = `${FAL_QUEUE_URL2}/${endpoint}/requests/${requestId}`;
|
|
3044
4049
|
const response = await this.request(url);
|
|
3045
4050
|
if (response.isErr()) {
|
|
3046
|
-
return (0,
|
|
4051
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
3047
4052
|
}
|
|
3048
4053
|
const data = await response.value.json();
|
|
3049
4054
|
const video = isRecord(data) && isRecord(data.video) ? data.video : void 0;
|
|
3050
4055
|
if (video === void 0) {
|
|
3051
|
-
return (0,
|
|
4056
|
+
return (0, import_neverthrow2.err)(new MotifError("No video in response", 0));
|
|
3052
4057
|
}
|
|
3053
|
-
return (0,
|
|
4058
|
+
return (0, import_neverthrow2.ok)({
|
|
3054
4059
|
contentType: asString(video.content_type) ?? "",
|
|
3055
4060
|
fileName: asString(video.file_name) ?? "",
|
|
3056
4061
|
fileSize: asNumber(video.file_size) ?? 0,
|
|
@@ -3074,13 +4079,13 @@ var FalClient = class {
|
|
|
3074
4079
|
}
|
|
3075
4080
|
);
|
|
3076
4081
|
if (initiateResponse.isErr()) {
|
|
3077
|
-
return (0,
|
|
4082
|
+
return (0, import_neverthrow2.err)(initiateResponse.error);
|
|
3078
4083
|
}
|
|
3079
4084
|
const initiateData = await initiateResponse.value.json();
|
|
3080
4085
|
const fileUrl = isRecord(initiateData) ? asString(initiateData.file_url) ?? "" : "";
|
|
3081
4086
|
const uploadUrl = isRecord(initiateData) ? asString(initiateData.upload_url) : void 0;
|
|
3082
4087
|
if (uploadUrl === void 0 || uploadUrl === "") {
|
|
3083
|
-
return (0,
|
|
4088
|
+
return (0, import_neverthrow2.err)(
|
|
3084
4089
|
new MotifError("Upload initiate response missing upload_url", 0)
|
|
3085
4090
|
);
|
|
3086
4091
|
}
|
|
@@ -3095,7 +4100,7 @@ var FalClient = class {
|
|
|
3095
4100
|
method: "PUT"
|
|
3096
4101
|
});
|
|
3097
4102
|
} catch (error) {
|
|
3098
|
-
return (0,
|
|
4103
|
+
return (0, import_neverthrow2.err)(
|
|
3099
4104
|
new MotifError(
|
|
3100
4105
|
`Upload PUT failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
3101
4106
|
0
|
|
@@ -3103,38 +4108,45 @@ var FalClient = class {
|
|
|
3103
4108
|
);
|
|
3104
4109
|
}
|
|
3105
4110
|
if (!putResponse.ok) {
|
|
3106
|
-
return (0,
|
|
4111
|
+
return (0, import_neverthrow2.err)(
|
|
3107
4112
|
new MotifError(
|
|
3108
4113
|
`Upload PUT failed: ${putResponse.status}`,
|
|
3109
4114
|
putResponse.status
|
|
3110
4115
|
)
|
|
3111
4116
|
);
|
|
3112
4117
|
}
|
|
3113
|
-
return (0,
|
|
4118
|
+
return (0, import_neverthrow2.ok)(fileUrl);
|
|
3114
4119
|
}
|
|
3115
4120
|
/** ─── Utilities ───────────────────────────────────────────── */
|
|
3116
4121
|
/** Run a registered fal utility/tool endpoint. */
|
|
3117
4122
|
async runTool(options) {
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
return (
|
|
4123
|
+
return await runTool(this.toolExecutor, options);
|
|
4124
|
+
}
|
|
4125
|
+
/** ─── Queue-Based Tools ───────────────────────────────────── */
|
|
4126
|
+
/**
|
|
4127
|
+
* Submit a tool run to the fal queue. Returns as soon as fal accepts it.
|
|
4128
|
+
*
|
|
4129
|
+
* The queued counterpart to `runTool`, for endpoints that outrun the
|
|
4130
|
+
* synchronous request timeout. Callers choose the path — neither one falls
|
|
4131
|
+
* back to the other.
|
|
4132
|
+
*/
|
|
4133
|
+
async submitTool(options) {
|
|
4134
|
+
return await submitTool(this.toolExecutor, options);
|
|
4135
|
+
}
|
|
4136
|
+
/** Poll one queued tool run. */
|
|
4137
|
+
async checkToolStatus(job) {
|
|
4138
|
+
return await checkToolStatus(this.toolExecutor, job);
|
|
4139
|
+
}
|
|
4140
|
+
/** Fetch the finished payload for a queued tool run. */
|
|
4141
|
+
async getToolResult(job) {
|
|
4142
|
+
return await getToolResult(this.toolExecutor, job);
|
|
4143
|
+
}
|
|
4144
|
+
/**
|
|
4145
|
+
* Submit, poll to completion, and return the result. The convenience path
|
|
4146
|
+
* for tools whose registry entry sets `queued`.
|
|
4147
|
+
*/
|
|
4148
|
+
async runToolQueued(options, onProgress) {
|
|
4149
|
+
return await runToolQueued(this.toolExecutor, options, onProgress);
|
|
3138
4150
|
}
|
|
3139
4151
|
/**
|
|
3140
4152
|
* Delete fal's stored IO payloads for a completed request.
|
|
@@ -3149,9 +4161,9 @@ var FalClient = class {
|
|
|
3149
4161
|
{ method: "DELETE" }
|
|
3150
4162
|
);
|
|
3151
4163
|
if (response.isErr()) {
|
|
3152
|
-
return (0,
|
|
4164
|
+
return (0, import_neverthrow2.err)(response.error);
|
|
3153
4165
|
}
|
|
3154
|
-
return (0,
|
|
4166
|
+
return (0, import_neverthrow2.ok)();
|
|
3155
4167
|
}
|
|
3156
4168
|
/** Estimate cost for a generation (no API call). */
|
|
3157
4169
|
estimateCost(model, resolution, numImages) {
|
|
@@ -3177,6 +4189,16 @@ var FalClient = class {
|
|
|
3177
4189
|
get tools() {
|
|
3178
4190
|
return FAL_TOOLS;
|
|
3179
4191
|
}
|
|
4192
|
+
/**
|
|
4193
|
+
* The seam `server-tools.ts` runs against — the client's authenticated fetch
|
|
4194
|
+
* and its queue status parser, exposed without widening the public surface.
|
|
4195
|
+
*/
|
|
4196
|
+
get toolExecutor() {
|
|
4197
|
+
return {
|
|
4198
|
+
getJobStatus: async (endpoint, requestId) => await this.getJobStatus(endpoint, requestId),
|
|
4199
|
+
request: async (url, init) => await this.request(url, init)
|
|
4200
|
+
};
|
|
4201
|
+
}
|
|
3180
4202
|
/** ─── Private ─────────────────────────────────────────────── */
|
|
3181
4203
|
/** Authenticated fetch to fal.ai APIs with retry logic. */
|
|
3182
4204
|
async request(url, options = {}) {
|
|
@@ -3208,15 +4230,15 @@ var FalClient = class {
|
|
|
3208
4230
|
const text = await response.text();
|
|
3209
4231
|
const message = `Request failed: ${response.status} ${text}`;
|
|
3210
4232
|
const requestId = response.headers.get("x-fal-request-id") ?? requestIdFromBody(text);
|
|
3211
|
-
return (0,
|
|
4233
|
+
return (0, import_neverthrow2.err)(
|
|
3212
4234
|
new MotifError(message, response.status, void 0, requestId)
|
|
3213
4235
|
);
|
|
3214
4236
|
}
|
|
3215
|
-
return (0,
|
|
4237
|
+
return (0, import_neverthrow2.ok)(response);
|
|
3216
4238
|
} catch (error) {
|
|
3217
4239
|
clearTimeout(timeoutId);
|
|
3218
4240
|
if (error instanceof MotifError) {
|
|
3219
|
-
return (0,
|
|
4241
|
+
return (0, import_neverthrow2.err)(error);
|
|
3220
4242
|
}
|
|
3221
4243
|
lastError = new MotifError(
|
|
3222
4244
|
error instanceof Error ? error.message : String(error),
|
|
@@ -3230,7 +4252,7 @@ var FalClient = class {
|
|
|
3230
4252
|
}
|
|
3231
4253
|
}
|
|
3232
4254
|
}
|
|
3233
|
-
return (0,
|
|
4255
|
+
return (0, import_neverthrow2.err)(lastError ?? new MotifError("Request failed after retries", 0));
|
|
3234
4256
|
}
|
|
3235
4257
|
ephemeralHeaders(options) {
|
|
3236
4258
|
return options.ephemeral === true ? { "X-Fal-Store-IO": "0" } : {};
|
|
@@ -3241,24 +4263,24 @@ var FalClient = class {
|
|
|
3241
4263
|
*/
|
|
3242
4264
|
normalizeResponse(data, fallbackRequestId) {
|
|
3243
4265
|
if (!isRecord(data)) {
|
|
3244
|
-
return (0,
|
|
4266
|
+
return (0, import_neverthrow2.err)(
|
|
3245
4267
|
new MotifError("Unexpected fal response shape", 0, "FAL_ERROR")
|
|
3246
4268
|
);
|
|
3247
4269
|
}
|
|
3248
4270
|
const obj = data;
|
|
3249
4271
|
const requestId = asString(obj.request_id) ?? asString(obj.requestId) ?? fallbackRequestId;
|
|
3250
4272
|
if ("detail" in obj) {
|
|
3251
|
-
return (0,
|
|
4273
|
+
return (0, import_neverthrow2.err)(new MotifError(asString(obj.detail) ?? "", 0, "FAL_ERROR"));
|
|
3252
4274
|
}
|
|
3253
4275
|
if ("image" in obj && !("images" in obj)) {
|
|
3254
|
-
return (0,
|
|
4276
|
+
return (0, import_neverthrow2.ok)({
|
|
3255
4277
|
images: [toMotifImage(obj.image)],
|
|
3256
4278
|
prompt: asString(obj.prompt),
|
|
3257
4279
|
requestId,
|
|
3258
4280
|
seed: asNumber(obj.seed)
|
|
3259
4281
|
});
|
|
3260
4282
|
}
|
|
3261
|
-
return (0,
|
|
4283
|
+
return (0, import_neverthrow2.ok)({
|
|
3262
4284
|
images: parseImages(obj.images),
|
|
3263
4285
|
prompt: asString(obj.prompt),
|
|
3264
4286
|
requestId,
|
|
@@ -3266,27 +4288,632 @@ var FalClient = class {
|
|
|
3266
4288
|
});
|
|
3267
4289
|
}
|
|
3268
4290
|
};
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
4291
|
+
|
|
4292
|
+
// src/tool-cost.ts
|
|
4293
|
+
var UNKNOWN = { basis: "unknown", usd: null };
|
|
4294
|
+
function totalMegapixels(outputs) {
|
|
4295
|
+
let pixels = 0;
|
|
4296
|
+
let measured = 0;
|
|
4297
|
+
for (const output of outputs) {
|
|
4298
|
+
if (output.width !== void 0 && output.height !== void 0) {
|
|
4299
|
+
pixels += output.width * output.height;
|
|
4300
|
+
measured += 1;
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4303
|
+
return measured === 0 ? null : pixels / 1e6;
|
|
4304
|
+
}
|
|
4305
|
+
function projectedToolCost(price) {
|
|
4306
|
+
return price.kind === "call" ? { basis: "projected", usd: price.usd } : UNKNOWN;
|
|
4307
|
+
}
|
|
4308
|
+
function measuredToolCost(price, outputs) {
|
|
4309
|
+
if (price.kind === "call") {
|
|
4310
|
+
return { basis: "measured", usd: price.usd };
|
|
4311
|
+
}
|
|
4312
|
+
if (price.kind === "megapixel") {
|
|
4313
|
+
const megapixels = totalMegapixels(outputs);
|
|
4314
|
+
return megapixels === null ? UNKNOWN : { basis: "measured", usd: price.usd * megapixels };
|
|
4315
|
+
}
|
|
4316
|
+
return UNKNOWN;
|
|
4317
|
+
}
|
|
4318
|
+
function formatCost(usd) {
|
|
4319
|
+
return usd === null ? "metered" : `$${usd.toFixed(3)}`;
|
|
4320
|
+
}
|
|
4321
|
+
function sumCosts(costs) {
|
|
4322
|
+
let known = 0;
|
|
4323
|
+
let unknown = 0;
|
|
4324
|
+
for (const cost of costs) {
|
|
4325
|
+
if (cost === null) {
|
|
4326
|
+
unknown += 1;
|
|
4327
|
+
} else {
|
|
4328
|
+
known += cost;
|
|
4329
|
+
}
|
|
3281
4330
|
}
|
|
4331
|
+
return { known, unknown };
|
|
4332
|
+
}
|
|
4333
|
+
|
|
4334
|
+
// src/tool-parameters.generated.ts
|
|
4335
|
+
var FAL_TOOL_PARAMETERS = {
|
|
4336
|
+
"ben-v2": [
|
|
4337
|
+
{ key: "seed", type: "integer" }
|
|
4338
|
+
],
|
|
4339
|
+
"birefnet": [
|
|
4340
|
+
{ key: "mask_only", type: "boolean", fallback: false },
|
|
4341
|
+
{ key: "model", type: "enum(General Use (Light)|General Use (Light 2K)|General Use (Heavy)|Matting|Portrait|General Use (Dynamic))", fallback: "General Use (Light)" },
|
|
4342
|
+
{ key: "operating_resolution", type: "enum(1024x1024|2048x2048|2304x2304)", fallback: "1024x1024" },
|
|
4343
|
+
{ key: "output_format", type: "enum(webp|png|gif)", fallback: "png" },
|
|
4344
|
+
{ key: "output_mask", type: "boolean", fallback: false },
|
|
4345
|
+
{ key: "refine_foreground", type: "boolean", fallback: true }
|
|
4346
|
+
],
|
|
4347
|
+
"bria-eraser": [
|
|
4348
|
+
{ key: "mask_type", type: "enum(manual|automatic)", fallback: "manual" },
|
|
4349
|
+
{ key: "preserve_alpha", type: "boolean", fallback: false }
|
|
4350
|
+
],
|
|
4351
|
+
"bria-expand": [
|
|
4352
|
+
{ key: "aspect_ratio", type: "enum(1:1|2:3|3:2|3:4|4:3|4:5|5:4|9:16|16:9)" },
|
|
4353
|
+
{ key: "canvas_size", type: "list[integer]", required: true },
|
|
4354
|
+
{ key: "negative_prompt", type: "string", fallback: "" },
|
|
4355
|
+
{ key: "original_image_location", type: "list[integer]" },
|
|
4356
|
+
{ key: "original_image_size", type: "list[integer]" },
|
|
4357
|
+
{ key: "prompt", type: "string", fallback: "" },
|
|
4358
|
+
{ key: "seed", type: "integer" }
|
|
4359
|
+
],
|
|
4360
|
+
"bria-genfill": [
|
|
4361
|
+
{ key: "negative_prompt", type: "string", fallback: "" },
|
|
4362
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4363
|
+
{ key: "prompt", type: "string", required: true },
|
|
4364
|
+
{ key: "seed", type: "integer" }
|
|
4365
|
+
],
|
|
4366
|
+
"bria-rmbg": [],
|
|
4367
|
+
"bria-video-rmbg": [
|
|
4368
|
+
{ key: "background_color", type: "enum(Transparent|Black|White|Gray|Red|Green|Blue|Yellow|Cyan|Magenta|Orange)", fallback: "Black" },
|
|
4369
|
+
{ key: "output_container_and_codec", type: "enum(mp4_h265|mp4_h264|webm_vp9|mov_h265|mov_proresks|mkv_h265|mkv_h264|mkv_vp9|gif)", fallback: "webm_vp9" },
|
|
4370
|
+
{ key: "preserve_audio", type: "boolean", fallback: true }
|
|
4371
|
+
],
|
|
4372
|
+
"ddcolor": [
|
|
4373
|
+
{ key: "seed", type: "integer" }
|
|
4374
|
+
],
|
|
4375
|
+
"depth-anything": [],
|
|
4376
|
+
"dwpose": [
|
|
4377
|
+
{ key: "draw_mode", type: "enum(full-pose|body-pose|face-pose|hand-pose|face-hand-mask|face-mask|hand-mask)", fallback: "body-pose" }
|
|
4378
|
+
],
|
|
4379
|
+
"finegrain-eraser": [
|
|
4380
|
+
{ key: "mode", type: "enum(express|standard|premium)", fallback: "standard" },
|
|
4381
|
+
{ key: "prompt", type: "string", required: true },
|
|
4382
|
+
{ key: "seed", type: "integer" }
|
|
4383
|
+
],
|
|
4384
|
+
"flux-outpaint": [
|
|
4385
|
+
{ key: "auto_crop", type: "boolean", fallback: false },
|
|
4386
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4387
|
+
{ key: "expand_bottom", type: "integer", fallback: 0 },
|
|
4388
|
+
{ key: "expand_left", type: "integer", fallback: 0 },
|
|
4389
|
+
{ key: "expand_right", type: "integer", fallback: 0 },
|
|
4390
|
+
{ key: "expand_top", type: "integer", fallback: 0 },
|
|
4391
|
+
{ key: "mode", type: "enum(high|fast)", fallback: "high" },
|
|
4392
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" }
|
|
4393
|
+
],
|
|
4394
|
+
"got-ocr": [
|
|
4395
|
+
{ key: "do_format", type: "boolean", fallback: false },
|
|
4396
|
+
{ key: "multi_page", type: "boolean", fallback: false }
|
|
4397
|
+
],
|
|
4398
|
+
"hed": [
|
|
4399
|
+
{ key: "safe", type: "boolean", fallback: false },
|
|
4400
|
+
{ key: "scribble", type: "boolean", fallback: false }
|
|
4401
|
+
],
|
|
4402
|
+
"hunyuan3d-v3": [
|
|
4403
|
+
{ key: "back_image_url", type: "string" },
|
|
4404
|
+
{ key: "enable_pbr", type: "boolean", fallback: false },
|
|
4405
|
+
{ key: "face_count", type: "integer", fallback: 5e5 },
|
|
4406
|
+
{ key: "generate_type", type: "enum(Normal|LowPoly|Geometry)", fallback: "Normal" },
|
|
4407
|
+
{ key: "left_image_url", type: "string" },
|
|
4408
|
+
{ key: "polygon_type", type: "enum(triangle|quadrilateral)", fallback: "triangle" },
|
|
4409
|
+
{ key: "right_image_url", type: "string" }
|
|
4410
|
+
],
|
|
4411
|
+
"iclight-v2": [
|
|
4412
|
+
{ key: "background_threshold", type: "number", fallback: 0.67 },
|
|
4413
|
+
{ key: "cfg", type: "number", fallback: 1 },
|
|
4414
|
+
{ key: "enable_hr_fix", type: "boolean", fallback: false },
|
|
4415
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4416
|
+
{ key: "guidance_scale", type: "number", fallback: 5 },
|
|
4417
|
+
{ key: "highres_denoise", type: "number", fallback: 0.95 },
|
|
4418
|
+
{ key: "hr_downscale", type: "number", fallback: 0.5 },
|
|
4419
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)" },
|
|
4420
|
+
{ key: "initial_latent", type: "enum(None|Left|Right|Top|Bottom)", fallback: "None" },
|
|
4421
|
+
{ key: "lowres_denoise", type: "number", fallback: 0.98 },
|
|
4422
|
+
{ key: "mask_image_url", type: "string" },
|
|
4423
|
+
{ key: "negative_prompt", type: "string", fallback: "" },
|
|
4424
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4425
|
+
{ key: "num_inference_steps", type: "integer", fallback: 28 },
|
|
4426
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4427
|
+
{ key: "prompt", type: "string", required: true },
|
|
4428
|
+
{ key: "seed", type: "integer" }
|
|
4429
|
+
],
|
|
4430
|
+
"ideogram-layerize-text": [
|
|
4431
|
+
{ key: "font_file_body_url", type: "string" },
|
|
4432
|
+
{ key: "font_file_h1_url", type: "string" },
|
|
4433
|
+
{ key: "font_file_h2_url", type: "string" },
|
|
4434
|
+
{ key: "font_file_small_url", type: "string" },
|
|
4435
|
+
{ key: "font_name_body", type: "string" },
|
|
4436
|
+
{ key: "font_name_h1", type: "string" },
|
|
4437
|
+
{ key: "font_name_h2", type: "string" },
|
|
4438
|
+
{ key: "font_name_small", type: "string" },
|
|
4439
|
+
{ key: "prompt", type: "string" },
|
|
4440
|
+
{ key: "seed", type: "integer" }
|
|
4441
|
+
],
|
|
4442
|
+
"ideogram-reframe": [
|
|
4443
|
+
{ key: "color_palette", type: "object" },
|
|
4444
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)", required: true },
|
|
4445
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4446
|
+
{ key: "rendering_speed", type: "enum(TURBO|BALANCED|QUALITY)", fallback: "BALANCED" },
|
|
4447
|
+
{ key: "seed", type: "integer" },
|
|
4448
|
+
{ key: "style", type: "enum(AUTO|GENERAL|REALISTIC|DESIGN)" },
|
|
4449
|
+
{ key: "style_codes", type: "list[string]" },
|
|
4450
|
+
{ key: "style_preset", type: "enum(80S_ILLUSTRATION|90S_NOSTALGIA|ABSTRACT_ORGANIC|ANALOG_NOSTALGIA|ART_BRUT|ART_DECO|ART_POSTER|AURA|AVANT_GARDE|BAUHAUS|BLUEPRINT|BLURRY_MOTION|BRIGHT_ART|C4D_CARTOON|CHILDRENS_BOOK|COLLAGE|COLORING_BOOK_I|COLORING_BOOK_II|CUBISM|DARK_AURA|DOODLE|DOUBLE_EXPOSURE|DRAMATIC_CINEMA|EDITORIAL|EMOTIONAL_MINIMAL|ETHEREAL_PARTY|EXPIRED_FILM|FLAT_ART|FLAT_VECTOR|FOREST_REVERIE|GEO_MINIMALIST|GLASS_PRISM|GOLDEN_HOUR|GRAFFITI_I|GRAFFITI_II|HALFTONE_PRINT|HIGH_CONTRAST|HIPPIE_ERA|ICONIC|JAPANDI_FUSION|JAZZY|LONG_EXPOSURE|MAGAZINE_EDITORIAL|MINIMAL_ILLUSTRATION|MIXED_MEDIA|MONOCHROME|NIGHTLIFE|OIL_PAINTING|OLD_CARTOONS|PAINT_GESTURE|POP_ART|RETRO_ETCHING|RIVIERA_POP|SPOTLIGHT_80S|STYLIZED_RED|SURREAL_COLLAGE|TRAVEL_POSTER|VINTAGE_GEO|VINTAGE_POSTER|WATERCOLOR|WEIRD|WOODBLOCK_PRINT)" }
|
|
4451
|
+
],
|
|
4452
|
+
"ideogram-tiling": [
|
|
4453
|
+
{ key: "acceleration", type: "enum(none|low|regular|high)", fallback: "none" },
|
|
4454
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4455
|
+
{ key: "expansion_model", type: "enum(None|Medium|Large)", fallback: "Medium" },
|
|
4456
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)", fallback: "square_hd" },
|
|
4457
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4458
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4459
|
+
{ key: "prompt", type: "string", required: true },
|
|
4460
|
+
{ key: "rendering_speed", type: "enum(TURBO|BALANCED|QUALITY)", fallback: "BALANCED" },
|
|
4461
|
+
{ key: "seed", type: "integer" },
|
|
4462
|
+
{ key: "strength", type: "number", fallback: 0.8 },
|
|
4463
|
+
{ key: "tiling_mode", type: "enum(both|horizontal|vertical)", fallback: "both" }
|
|
4464
|
+
],
|
|
4465
|
+
"image2svg": [
|
|
4466
|
+
{ key: "color_precision", type: "integer", fallback: 6 },
|
|
4467
|
+
{ key: "colormode", type: "enum(color|binary)", fallback: "color" },
|
|
4468
|
+
{ key: "corner_threshold", type: "integer", fallback: 60 },
|
|
4469
|
+
{ key: "filter_speckle", type: "integer", fallback: 4 },
|
|
4470
|
+
{ key: "hierarchical", type: "enum(stacked|cutout)", fallback: "stacked" },
|
|
4471
|
+
{ key: "layer_difference", type: "integer", fallback: 16 },
|
|
4472
|
+
{ key: "length_threshold", type: "number", fallback: 4 },
|
|
4473
|
+
{ key: "max_iterations", type: "integer", fallback: 10 },
|
|
4474
|
+
{ key: "mode", type: "enum(spline|polygon)", fallback: "spline" },
|
|
4475
|
+
{ key: "path_precision", type: "integer", fallback: 3 },
|
|
4476
|
+
{ key: "splice_threshold", type: "integer", fallback: 45 }
|
|
4477
|
+
],
|
|
4478
|
+
"lighting-restoration": [
|
|
4479
|
+
{ key: "acceleration", type: "enum(none|regular)", fallback: "regular" },
|
|
4480
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4481
|
+
{ key: "guidance_scale", type: "number", fallback: 1 },
|
|
4482
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)" },
|
|
4483
|
+
{ key: "negative_prompt", type: "string", fallback: " " },
|
|
4484
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4485
|
+
{ key: "num_inference_steps", type: "integer", fallback: 6 },
|
|
4486
|
+
{ key: "output_format", type: "enum(png|jpeg|webp)", fallback: "png" },
|
|
4487
|
+
{ key: "seed", type: "integer" }
|
|
4488
|
+
],
|
|
4489
|
+
"lineart": [
|
|
4490
|
+
{ key: "coarse", type: "boolean", fallback: false }
|
|
4491
|
+
],
|
|
4492
|
+
"marigold-depth": [
|
|
4493
|
+
{ key: "ensemble_size", type: "integer", fallback: 10 },
|
|
4494
|
+
{ key: "num_inference_steps", type: "integer", fallback: 10 },
|
|
4495
|
+
{ key: "processing_res", type: "integer", fallback: 0 }
|
|
4496
|
+
],
|
|
4497
|
+
"midas-depth": [
|
|
4498
|
+
{ key: "a", type: "number", fallback: 6.283185307179586 },
|
|
4499
|
+
{ key: "bg_th", type: "number", fallback: 0.1 },
|
|
4500
|
+
{ key: "depth_and_normal", type: "boolean", fallback: false }
|
|
4501
|
+
],
|
|
4502
|
+
"midas-preprocessor": [
|
|
4503
|
+
{ key: "a", type: "number", fallback: 6.283185307179586 },
|
|
4504
|
+
{ key: "background_threshold", type: "number", fallback: 0.1 }
|
|
4505
|
+
],
|
|
4506
|
+
"mlsd": [
|
|
4507
|
+
{ key: "distance_threshold", type: "number", fallback: 0.1 },
|
|
4508
|
+
{ key: "score_threshold", type: "number", fallback: 0.1 }
|
|
4509
|
+
],
|
|
4510
|
+
"moondream-caption": [
|
|
4511
|
+
{ key: "length", type: "enum(short|normal|long)", fallback: "normal" },
|
|
4512
|
+
{ key: "temperature", type: "number" },
|
|
4513
|
+
{ key: "top_p", type: "number" }
|
|
4514
|
+
],
|
|
4515
|
+
"moondream-detect": [
|
|
4516
|
+
{ key: "preview", type: "boolean", fallback: false },
|
|
4517
|
+
{ key: "prompt", type: "string", required: true }
|
|
4518
|
+
],
|
|
4519
|
+
"moondream-point": [
|
|
4520
|
+
{ key: "preview", type: "boolean", fallback: false },
|
|
4521
|
+
{ key: "prompt", type: "string", required: true }
|
|
4522
|
+
],
|
|
4523
|
+
"moondream-query": [
|
|
4524
|
+
{ key: "prompt", type: "string", required: true },
|
|
4525
|
+
{ key: "reasoning", type: "boolean", fallback: true },
|
|
4526
|
+
{ key: "temperature", type: "number" },
|
|
4527
|
+
{ key: "top_p", type: "number" }
|
|
4528
|
+
],
|
|
4529
|
+
"nsfw": [],
|
|
4530
|
+
"object-removal": [
|
|
4531
|
+
{ key: "mask_expansion", type: "integer", fallback: 15 },
|
|
4532
|
+
{ key: "model", type: "enum(low_quality|medium_quality|high_quality|best_quality)", fallback: "best_quality" },
|
|
4533
|
+
{ key: "prompt", type: "string", required: true }
|
|
4534
|
+
],
|
|
4535
|
+
"object-removal-bbox": [
|
|
4536
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4537
|
+
{ key: "mask_expansion", type: "integer", fallback: 15 },
|
|
4538
|
+
{ key: "model", type: "enum(low_quality|medium_quality|high_quality|best_quality)", fallback: "best_quality" }
|
|
4539
|
+
],
|
|
4540
|
+
"object-removal-mask": [
|
|
4541
|
+
{ key: "mask_expansion", type: "integer", fallback: 15 },
|
|
4542
|
+
{ key: "model", type: "enum(low_quality|medium_quality|high_quality|best_quality)", fallback: "best_quality" }
|
|
4543
|
+
],
|
|
4544
|
+
"patina": [
|
|
4545
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4546
|
+
{ key: "maps", type: "list[enum(basecolor|normal|roughness|metalness|height)]", fallback: ["basecolor", "normal", "roughness", "metalness", "height"] },
|
|
4547
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4548
|
+
{ key: "seed", type: "integer" }
|
|
4549
|
+
],
|
|
4550
|
+
"patina-extract": [
|
|
4551
|
+
{ key: "enable_prompt_expansion", type: "boolean", fallback: true },
|
|
4552
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4553
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)", fallback: "square_hd" },
|
|
4554
|
+
{ key: "maps", type: "list[enum(basecolor|normal|roughness|metalness|height)]", fallback: ["basecolor", "normal", "roughness", "metalness", "height"] },
|
|
4555
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4556
|
+
{ key: "num_inference_steps", type: "integer", fallback: 8 },
|
|
4557
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4558
|
+
{ key: "prompt", type: "string", required: true },
|
|
4559
|
+
{ key: "seed", type: "integer" },
|
|
4560
|
+
{ key: "strength", type: "number", fallback: 0.6 },
|
|
4561
|
+
{ key: "tile_size", type: "integer", fallback: 128 },
|
|
4562
|
+
{ key: "tile_stride", type: "integer", fallback: 64 },
|
|
4563
|
+
{ key: "tiling_mode", type: "enum(both|horizontal|vertical)", fallback: "both" },
|
|
4564
|
+
{ key: "upscale_factor", type: "enum(0|2|4)", fallback: 0 }
|
|
4565
|
+
],
|
|
4566
|
+
"pidi": [
|
|
4567
|
+
{ key: "apply_filter", type: "boolean", fallback: false },
|
|
4568
|
+
{ key: "safe", type: "boolean", fallback: false },
|
|
4569
|
+
{ key: "scribble", type: "boolean", fallback: false }
|
|
4570
|
+
],
|
|
4571
|
+
"qwen-layered": [
|
|
4572
|
+
{ key: "acceleration", type: "enum(none|regular|high)", fallback: "regular" },
|
|
4573
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4574
|
+
{ key: "guidance_scale", type: "number", fallback: 5 },
|
|
4575
|
+
{ key: "negative_prompt", type: "string", fallback: "" },
|
|
4576
|
+
{ key: "num_inference_steps", type: "integer", fallback: 28 },
|
|
4577
|
+
{ key: "num_layers", type: "integer", fallback: 4 },
|
|
4578
|
+
{ key: "output_format", type: "enum(png|webp)", fallback: "png" },
|
|
4579
|
+
{ key: "prompt", type: "string" },
|
|
4580
|
+
{ key: "seed", type: "integer" }
|
|
4581
|
+
],
|
|
4582
|
+
"recraft-vectorize": [],
|
|
4583
|
+
"rembg": [
|
|
4584
|
+
{ key: "crop_to_bbox", type: "boolean", fallback: false }
|
|
4585
|
+
],
|
|
4586
|
+
"remove-lighting": [
|
|
4587
|
+
{ key: "acceleration", type: "enum(none|regular)", fallback: "regular" },
|
|
4588
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4589
|
+
{ key: "guidance_scale", type: "number", fallback: 1 },
|
|
4590
|
+
{ key: "image_size", type: "object|enum(square_hd|square|portrait_4_3|portrait_16_9|landscape_4_3|landscape_16_9)" },
|
|
4591
|
+
{ key: "negative_prompt", type: "string", fallback: " " },
|
|
4592
|
+
{ key: "num_images", type: "integer", fallback: 1 },
|
|
4593
|
+
{ key: "num_inference_steps", type: "integer", fallback: 6 },
|
|
4594
|
+
{ key: "output_format", type: "enum(png|jpeg|webp)", fallback: "png" },
|
|
4595
|
+
{ key: "seed", type: "integer" }
|
|
4596
|
+
],
|
|
4597
|
+
"sam-preprocessor": [],
|
|
4598
|
+
"sam2-auto": [
|
|
4599
|
+
{ key: "min_mask_region_area", type: "integer", fallback: 100 },
|
|
4600
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "png" },
|
|
4601
|
+
{ key: "points_per_side", type: "integer", fallback: 32 },
|
|
4602
|
+
{ key: "pred_iou_thresh", type: "number", fallback: 0.88 },
|
|
4603
|
+
{ key: "stability_score_thresh", type: "number", fallback: 0.95 }
|
|
4604
|
+
],
|
|
4605
|
+
"sam3-1-image": [
|
|
4606
|
+
{ key: "apply_mask", type: "boolean", fallback: true },
|
|
4607
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4608
|
+
{ key: "include_boxes", type: "boolean", fallback: false },
|
|
4609
|
+
{ key: "include_scores", type: "boolean", fallback: false },
|
|
4610
|
+
{ key: "max_masks", type: "integer", fallback: 3 },
|
|
4611
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4612
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4613
|
+
{ key: "prompt", type: "string", fallback: "wheel" },
|
|
4614
|
+
{ key: "return_multiple_masks", type: "boolean", fallback: false }
|
|
4615
|
+
],
|
|
4616
|
+
"sam3-1-video": [
|
|
4617
|
+
{ key: "apply_mask", type: "boolean", fallback: true },
|
|
4618
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4619
|
+
{ key: "detection_threshold", type: "number", fallback: 0.5 },
|
|
4620
|
+
{ key: "max_num_objects", type: "integer", fallback: 16 },
|
|
4621
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4622
|
+
{ key: "prompt", type: "string", fallback: "" },
|
|
4623
|
+
{ key: "video_output_type", type: "enum(X264 (.mp4)|VP9 (.webm))", fallback: "X264 (.mp4)" }
|
|
4624
|
+
],
|
|
4625
|
+
"sam3-3d-align": [
|
|
4626
|
+
{ key: "body_mask_url", type: "string" },
|
|
4627
|
+
{ key: "body_mesh_url", type: "string", required: true },
|
|
4628
|
+
{ key: "focal_length", type: "number" },
|
|
4629
|
+
{ key: "object_mesh_url", type: "string" }
|
|
4630
|
+
],
|
|
4631
|
+
"sam3-3d-body": [
|
|
4632
|
+
{ key: "export_meshes", type: "boolean", fallback: true },
|
|
4633
|
+
{ key: "include_3d_keypoints", type: "boolean", fallback: true },
|
|
4634
|
+
{ key: "include_mhr_params", type: "boolean", fallback: true }
|
|
4635
|
+
],
|
|
4636
|
+
"sam3-3d-objects": [
|
|
4637
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4638
|
+
{ key: "detection_threshold", type: "number" },
|
|
4639
|
+
{ key: "export_textured_glb", type: "boolean", fallback: false },
|
|
4640
|
+
{ key: "mask_urls", type: "list[string]" },
|
|
4641
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4642
|
+
{ key: "pointmap_url", type: "string" },
|
|
4643
|
+
{ key: "prompt", type: "string", fallback: "car" },
|
|
4644
|
+
{ key: "seed", type: "integer" }
|
|
4645
|
+
],
|
|
4646
|
+
"sam3-image": [
|
|
4647
|
+
{ key: "apply_mask", type: "boolean", fallback: true },
|
|
4648
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4649
|
+
{ key: "include_boxes", type: "boolean", fallback: false },
|
|
4650
|
+
{ key: "include_scores", type: "boolean", fallback: false },
|
|
4651
|
+
{ key: "max_masks", type: "integer", fallback: 3 },
|
|
4652
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4653
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4654
|
+
{ key: "prompt", type: "string", fallback: "wheel" },
|
|
4655
|
+
{ key: "return_multiple_masks", type: "boolean", fallback: false },
|
|
4656
|
+
{ key: "text_prompt", type: "string" }
|
|
4657
|
+
],
|
|
4658
|
+
"sam3-image-rle": [
|
|
4659
|
+
{ key: "apply_mask", type: "boolean", fallback: true },
|
|
4660
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4661
|
+
{ key: "include_boxes", type: "boolean", fallback: false },
|
|
4662
|
+
{ key: "include_scores", type: "boolean", fallback: false },
|
|
4663
|
+
{ key: "max_masks", type: "integer", fallback: 3 },
|
|
4664
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4665
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4666
|
+
{ key: "prompt", type: "string", fallback: "wheel" },
|
|
4667
|
+
{ key: "return_multiple_masks", type: "boolean", fallback: false },
|
|
4668
|
+
{ key: "text_prompt", type: "string" }
|
|
4669
|
+
],
|
|
4670
|
+
"sam3-video": [
|
|
4671
|
+
{ key: "apply_mask", type: "boolean", fallback: true },
|
|
4672
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4673
|
+
{ key: "detection_threshold", type: "number", fallback: 0.5 },
|
|
4674
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4675
|
+
{ key: "prompt", type: "string", fallback: "" },
|
|
4676
|
+
{ key: "text_prompt", type: "string" },
|
|
4677
|
+
{ key: "video_output_type", type: "enum(X264 (.mp4)|VP9 (.webm))", fallback: "X264 (.mp4)" }
|
|
4678
|
+
],
|
|
4679
|
+
"sam3-video-rle": [
|
|
4680
|
+
{ key: "apply_mask", type: "boolean", fallback: false },
|
|
4681
|
+
{ key: "boundingbox_zip", type: "boolean", fallback: false },
|
|
4682
|
+
{ key: "box_prompts", type: "list[object]", fallback: [] },
|
|
4683
|
+
{ key: "detection_threshold", type: "number", fallback: 0.5 },
|
|
4684
|
+
{ key: "frame_index", type: "integer", fallback: 0 },
|
|
4685
|
+
{ key: "point_prompts", type: "list[object]", fallback: [] },
|
|
4686
|
+
{ key: "prompt", type: "string", fallback: "" }
|
|
4687
|
+
],
|
|
4688
|
+
"scribble": [
|
|
4689
|
+
{ key: "model", type: "enum(HED|PiDi)", fallback: "HED" },
|
|
4690
|
+
{ key: "safe", type: "boolean", fallback: false }
|
|
4691
|
+
],
|
|
4692
|
+
"seedream-layerize": [
|
|
4693
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4694
|
+
{ key: "enhance_prompt_mode", type: "enum(standard|fast)", fallback: "standard" },
|
|
4695
|
+
{ key: "image_size", type: "enum(auto|auto_1K|auto_1.5K|auto_2K)", fallback: "auto" },
|
|
4696
|
+
{ key: "prompt", type: "string", fallback: "" }
|
|
4697
|
+
],
|
|
4698
|
+
"seedvr-seamless": [
|
|
4699
|
+
{ key: "enable_safety_checker", type: "boolean", fallback: true },
|
|
4700
|
+
{ key: "noise_scale", type: "number", fallback: 0.1 },
|
|
4701
|
+
{ key: "output_format", type: "enum(png|jpeg|webp)", fallback: "png" },
|
|
4702
|
+
{ key: "seed", type: "integer" },
|
|
4703
|
+
{ key: "target_resolution", type: "enum(720p|1080p|1440p|2160p)", fallback: "1080p" },
|
|
4704
|
+
{ key: "upscale_factor", type: "number", fallback: 2 },
|
|
4705
|
+
{ key: "upscale_mode", type: "enum(target|factor)", fallback: "factor" }
|
|
4706
|
+
],
|
|
4707
|
+
"seedvr-upscale": [
|
|
4708
|
+
{ key: "noise_scale", type: "number", fallback: 0.1 },
|
|
4709
|
+
{ key: "output_format", type: "enum(png|jpg|webp)", fallback: "jpg" },
|
|
4710
|
+
{ key: "seed", type: "integer" },
|
|
4711
|
+
{ key: "target_resolution", type: "enum(720p|1080p|1440p|2160p)", fallback: "1080p" },
|
|
4712
|
+
{ key: "upscale_factor", type: "number", fallback: 2 },
|
|
4713
|
+
{ key: "upscale_mode", type: "enum(target|factor)", fallback: "factor" }
|
|
4714
|
+
],
|
|
4715
|
+
"smart-resize": [
|
|
4716
|
+
{ key: "num_images_per_size", type: "integer", fallback: 1 },
|
|
4717
|
+
{ key: "output_format", type: "enum(jpeg|png|webp)", fallback: "png" },
|
|
4718
|
+
{ key: "prompt", type: "string", fallback: "" },
|
|
4719
|
+
{ key: "resolution", type: "enum(1K|2K|4K)", fallback: "1K" },
|
|
4720
|
+
{ key: "safety_tolerance", type: "enum(1|2|3|4|5|6)", fallback: "4" },
|
|
4721
|
+
{ key: "seed", type: "integer" },
|
|
4722
|
+
{ key: "target_sizes", type: "list[string]", required: true }
|
|
4723
|
+
],
|
|
4724
|
+
"teed": [],
|
|
4725
|
+
"text-removal": [
|
|
4726
|
+
{ key: "aspect_ratio", type: "enum(21:9|16:9|4:3|3:2|1:1|2:3|3:4|9:16|9:21)" },
|
|
4727
|
+
{ key: "guidance_scale", type: "number", fallback: 3.5 },
|
|
4728
|
+
{ key: "num_inference_steps", type: "integer", fallback: 30 },
|
|
4729
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4730
|
+
{ key: "safety_tolerance", type: "enum(1|2|3|4|5|6)", fallback: "2" },
|
|
4731
|
+
{ key: "seed", type: "integer" }
|
|
4732
|
+
],
|
|
4733
|
+
"topaz-adjust": [
|
|
4734
|
+
{ key: "model", type: "enum(Adjust V2|White Balance|Colorize)", fallback: "Adjust V2" },
|
|
4735
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" }
|
|
4736
|
+
],
|
|
4737
|
+
"topaz-creative": [
|
|
4738
|
+
{ key: "autoprompt", type: "boolean" },
|
|
4739
|
+
{ key: "color_preservation", type: "boolean" },
|
|
4740
|
+
{ key: "creativity", type: "integer" },
|
|
4741
|
+
{ key: "crop_to_fill", type: "boolean", fallback: false },
|
|
4742
|
+
{ key: "model", type: "enum(Bloom 2|Bloom|Bloom Realism)", fallback: "Bloom 2" },
|
|
4743
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4744
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4745
|
+
],
|
|
4746
|
+
"topaz-denoise": [
|
|
4747
|
+
{ key: "model", type: "enum(Normal|Strong|Extreme|Denoise Max)", fallback: "Normal" },
|
|
4748
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" }
|
|
4749
|
+
],
|
|
4750
|
+
"topaz-generative": [
|
|
4751
|
+
{ key: "autoprompt", type: "boolean" },
|
|
4752
|
+
{ key: "creativity", type: "integer" },
|
|
4753
|
+
{ key: "crop_to_fill", type: "boolean", fallback: false },
|
|
4754
|
+
{ key: "denoise", type: "number" },
|
|
4755
|
+
{ key: "detail", type: "number" },
|
|
4756
|
+
{ key: "enhancement_strength", type: "enum(low|medium|high)" },
|
|
4757
|
+
{ key: "face_enhancement", type: "boolean", fallback: true },
|
|
4758
|
+
{ key: "face_enhancement_creativity", type: "number", fallback: 0 },
|
|
4759
|
+
{ key: "face_enhancement_strength", type: "number", fallback: 0.8 },
|
|
4760
|
+
{ key: "model", type: "enum(Wonder 3.5|Wonder 3|Wonder 2|Wonder|Recover 3|Standard MAX|Redefine|Recovery V2|Recovery)", fallback: "Wonder 3" },
|
|
4761
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4762
|
+
{ key: "prompt", type: "string" },
|
|
4763
|
+
{ key: "sharpen", type: "number" },
|
|
4764
|
+
{ key: "subject_detection", type: "enum(All|Foreground|Background)", fallback: "All" },
|
|
4765
|
+
{ key: "texture", type: "integer" },
|
|
4766
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4767
|
+
],
|
|
4768
|
+
"topaz-image": [
|
|
4769
|
+
{ key: "autoprompt", type: "boolean" },
|
|
4770
|
+
{ key: "creativity", type: "integer" },
|
|
4771
|
+
{ key: "crop_to_fill", type: "boolean", fallback: false },
|
|
4772
|
+
{ key: "denoise", type: "number" },
|
|
4773
|
+
{ key: "detail", type: "number" },
|
|
4774
|
+
{ key: "enhancement_strength", type: "enum(low|medium|high)" },
|
|
4775
|
+
{ key: "face_enhancement", type: "boolean", fallback: true },
|
|
4776
|
+
{ key: "face_enhancement_creativity", type: "number", fallback: 0 },
|
|
4777
|
+
{ key: "face_enhancement_strength", type: "number", fallback: 0.8 },
|
|
4778
|
+
{ key: "fix_compression", type: "number" },
|
|
4779
|
+
{ key: "model", type: "enum(Standard V2|High Fidelity V2|Low Resolution V2|CGI|Text Refine|Wonder 3|Wonder|Standard MAX|Redefine|Recovery V2|Recovery)", fallback: "Standard V2" },
|
|
4780
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4781
|
+
{ key: "prompt", type: "string" },
|
|
4782
|
+
{ key: "sharpen", type: "number" },
|
|
4783
|
+
{ key: "strength", type: "number" },
|
|
4784
|
+
{ key: "subject_detection", type: "enum(All|Foreground|Background)", fallback: "All" },
|
|
4785
|
+
{ key: "texture", type: "integer" },
|
|
4786
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4787
|
+
],
|
|
4788
|
+
"topaz-precision": [
|
|
4789
|
+
{ key: "crop_to_fill", type: "boolean", fallback: false },
|
|
4790
|
+
{ key: "denoise", type: "number" },
|
|
4791
|
+
{ key: "face_enhancement", type: "boolean", fallback: true },
|
|
4792
|
+
{ key: "face_enhancement_creativity", type: "number", fallback: 0 },
|
|
4793
|
+
{ key: "face_enhancement_strength", type: "number", fallback: 0.8 },
|
|
4794
|
+
{ key: "fix_compression", type: "number" },
|
|
4795
|
+
{ key: "model", type: "enum(Standard V2|High Fidelity V3|High Fidelity V2|Low Resolution V2|CGI|Text Refine)", fallback: "Standard V2" },
|
|
4796
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" },
|
|
4797
|
+
{ key: "sharpen", type: "number" },
|
|
4798
|
+
{ key: "strength", type: "number" },
|
|
4799
|
+
{ key: "subject_detection", type: "enum(All|Foreground|Background)", fallback: "All" },
|
|
4800
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4801
|
+
],
|
|
4802
|
+
"topaz-restore": [
|
|
4803
|
+
{ key: "model", type: "enum(Recover 3|Dust-Scratch V2)", fallback: "Recover 3" },
|
|
4804
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" }
|
|
4805
|
+
],
|
|
4806
|
+
"topaz-sharpen": [
|
|
4807
|
+
{ key: "model", type: "enum(Standard|Strong|Lens Blur V2|Motion Blur|Natural|Refocus|Wildlife|Portrait|Auto Sharpen|Super Focus V3|Super Focus V2)", fallback: "Standard" },
|
|
4808
|
+
{ key: "output_format", type: "enum(jpeg|png)", fallback: "jpeg" }
|
|
4809
|
+
],
|
|
4810
|
+
"topaz-transparent": [
|
|
4811
|
+
{ key: "output_format", type: "string", fallback: "png" },
|
|
4812
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4813
|
+
],
|
|
4814
|
+
"topaz-video": [
|
|
4815
|
+
{ key: "compression", type: "number" },
|
|
4816
|
+
{ key: "grain", type: "number" },
|
|
4817
|
+
{ key: "H264_output", type: "boolean", fallback: false },
|
|
4818
|
+
{ key: "halo", type: "number" },
|
|
4819
|
+
{ key: "model", type: "enum(Proteus|Artemis HQ|Artemis MQ|Artemis LQ|Gaia HQ|Gaia CG|Gaia 2|Nyx|Nyx Fast|Nyx XL|Nyx HF|Starlight Precise 2.5|Starlight HQ|Starlight Mini|Starlight Sharp|Starlight Fast 2|Starlight Precise 1|Starlight Precise 2|Starlight Fast 1)", fallback: "Proteus" },
|
|
4820
|
+
{ key: "noise", type: "number" },
|
|
4821
|
+
{ key: "recover_detail", type: "number" },
|
|
4822
|
+
{ key: "target_fps", type: "integer" },
|
|
4823
|
+
{ key: "upscale_factor", type: "number", fallback: 2 }
|
|
4824
|
+
],
|
|
4825
|
+
"trellis-2": [
|
|
4826
|
+
{ key: "decimation_target", type: "integer", fallback: 5e5 },
|
|
4827
|
+
{ key: "remesh", type: "boolean", fallback: true },
|
|
4828
|
+
{ key: "remesh_band", type: "number", fallback: 1 },
|
|
4829
|
+
{ key: "remesh_project", type: "number", fallback: 0 },
|
|
4830
|
+
{ key: "resolution", type: "enum(512|1024|1536)", fallback: 1024 },
|
|
4831
|
+
{ key: "seed", type: "integer" },
|
|
4832
|
+
{ key: "shape_slat_guidance_interval_end", type: "number", fallback: 1 },
|
|
4833
|
+
{ key: "shape_slat_guidance_interval_start", type: "number", fallback: 0.6 },
|
|
4834
|
+
{ key: "shape_slat_guidance_rescale", type: "number", fallback: 0.5 },
|
|
4835
|
+
{ key: "shape_slat_guidance_strength", type: "number", fallback: 7.5 },
|
|
4836
|
+
{ key: "shape_slat_rescale_t", type: "number", fallback: 3 },
|
|
4837
|
+
{ key: "shape_slat_sampling_steps", type: "integer", fallback: 12 },
|
|
4838
|
+
{ key: "ss_guidance_interval_end", type: "number", fallback: 1 },
|
|
4839
|
+
{ key: "ss_guidance_interval_start", type: "number", fallback: 0.6 },
|
|
4840
|
+
{ key: "ss_guidance_rescale", type: "number", fallback: 0.7 },
|
|
4841
|
+
{ key: "ss_guidance_strength", type: "number", fallback: 7.5 },
|
|
4842
|
+
{ key: "ss_rescale_t", type: "number", fallback: 5 },
|
|
4843
|
+
{ key: "ss_sampling_steps", type: "integer", fallback: 12 },
|
|
4844
|
+
{ key: "tex_slat_guidance_interval_end", type: "number", fallback: 0.9 },
|
|
4845
|
+
{ key: "tex_slat_guidance_interval_start", type: "number", fallback: 0.6 },
|
|
4846
|
+
{ key: "tex_slat_guidance_rescale", type: "number", fallback: 0 },
|
|
4847
|
+
{ key: "tex_slat_guidance_strength", type: "number", fallback: 1 },
|
|
4848
|
+
{ key: "tex_slat_rescale_t", type: "number", fallback: 3 },
|
|
4849
|
+
{ key: "tex_slat_sampling_steps", type: "integer", fallback: 12 },
|
|
4850
|
+
{ key: "texture_size", type: "enum(1024|2048|4096)", fallback: 2048 },
|
|
4851
|
+
{ key: "uv_unwrap_angle_threshold_deg", type: "number", fallback: 90 },
|
|
4852
|
+
{ key: "uv_unwrap_global_iterations", type: "integer", fallback: 1 },
|
|
4853
|
+
{ key: "uv_unwrap_refine_iterations", type: "integer", fallback: 0 },
|
|
4854
|
+
{ key: "uv_unwrap_smooth_strength", type: "number", fallback: 1 }
|
|
4855
|
+
],
|
|
4856
|
+
"zoe-depth": []
|
|
3282
4857
|
};
|
|
3283
|
-
function
|
|
3284
|
-
|
|
3285
|
-
|
|
4858
|
+
function falToolParameters(tool) {
|
|
4859
|
+
return FAL_TOOL_PARAMETERS[tool] ?? [];
|
|
4860
|
+
}
|
|
4861
|
+
|
|
4862
|
+
// src/model-output.generated.ts
|
|
4863
|
+
var MODEL_OUTPUT = {
|
|
4864
|
+
"banana": { container: "png", lossless: true, bitDepth: 8 },
|
|
4865
|
+
"banana2": { container: "png", lossless: true, bitDepth: 8 },
|
|
4866
|
+
"flux": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4867
|
+
"flux-fast": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4868
|
+
"flux2-dev": { container: "png", lossless: true, bitDepth: 8 },
|
|
4869
|
+
"flux2-flex": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4870
|
+
"flux2-max": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4871
|
+
"flux2-pro": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4872
|
+
"flux2-turbo": { container: "png", lossless: true, bitDepth: 8 },
|
|
4873
|
+
"gemini": { container: "png", lossless: true, bitDepth: 8 },
|
|
4874
|
+
"gemini3": { container: "png", lossless: true, bitDepth: 8 },
|
|
4875
|
+
"gpt": { container: "png", lossless: true, bitDepth: 8 },
|
|
4876
|
+
"gpt2": { container: "png", lossless: true, bitDepth: 8 },
|
|
4877
|
+
"grok-image": { container: "png", lossless: true, bitDepth: 8 },
|
|
4878
|
+
"ideogram": { container: "png", lossless: true, bitDepth: 8 },
|
|
4879
|
+
"ideogram4": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4880
|
+
"qwen": { container: "png", lossless: true, bitDepth: 8 },
|
|
4881
|
+
"qwen3": { container: "png", lossless: true, bitDepth: 8 },
|
|
4882
|
+
"recraft": { container: "webp (lossless)", lossless: true, hasAlpha: true, bitDepth: 8 },
|
|
4883
|
+
"recraft4": { container: "webp (lossless)", lossless: true, hasAlpha: true, bitDepth: 8 },
|
|
4884
|
+
"seedream4": { container: "jpeg", subsampling: "4:4:4", lossless: false, bitDepth: 8 },
|
|
4885
|
+
"seedream45": { container: "jpeg", subsampling: "4:2:0", lossless: false, bitDepth: 8 },
|
|
4886
|
+
"seedream5": { container: "jpeg", subsampling: "4:2:0", lossless: false, bitDepth: 8 },
|
|
4887
|
+
"seedream5-lite": { container: "jpeg", subsampling: "4:2:0", lossless: false, bitDepth: 8 }
|
|
4888
|
+
};
|
|
4889
|
+
|
|
4890
|
+
// src/model-output.ts
|
|
4891
|
+
function modelOutput(model) {
|
|
4892
|
+
return MODEL_OUTPUT[model];
|
|
4893
|
+
}
|
|
4894
|
+
function losslessAvailability(model) {
|
|
4895
|
+
const shape = MODEL_OUTPUT[model];
|
|
4896
|
+
if (shape === void 0) {
|
|
4897
|
+
return "unknown";
|
|
3286
4898
|
}
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
4899
|
+
if (shape.lossless) {
|
|
4900
|
+
return "default";
|
|
4901
|
+
}
|
|
4902
|
+
return MODELS[model]?.supportsOutputFormat === true ? "on-request" : "unavailable";
|
|
4903
|
+
}
|
|
4904
|
+
function describeModelOutput(model) {
|
|
4905
|
+
const shape = MODEL_OUTPUT[model];
|
|
4906
|
+
if (shape === void 0) {
|
|
4907
|
+
return "not measured";
|
|
4908
|
+
}
|
|
4909
|
+
const base = shape.subsampling === void 0 || shape.subsampling === "" ? shape.container : `${shape.container} ${shape.subsampling}`;
|
|
4910
|
+
const suffix = {
|
|
4911
|
+
default: "lossless",
|
|
4912
|
+
"on-request": "lossless on request",
|
|
4913
|
+
unavailable: "no lossless route",
|
|
4914
|
+
unknown: "lossless route not measured"
|
|
4915
|
+
};
|
|
4916
|
+
return `${base}, ${suffix[losslessAvailability(model)]}`;
|
|
3290
4917
|
}
|
|
3291
4918
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3292
4919
|
0 && (module.exports = {
|
|
@@ -3298,6 +4925,7 @@ function toMotifError(error) {
|
|
|
3298
4925
|
FAL_TOOLS,
|
|
3299
4926
|
FAL_TOOLS_CHECKED_AT,
|
|
3300
4927
|
FAL_TOOL_IDS,
|
|
4928
|
+
FAL_TOOL_PARAMETERS,
|
|
3301
4929
|
FORMAT_PRESETS,
|
|
3302
4930
|
FalClient,
|
|
3303
4931
|
GENERATION_MODELS,
|
|
@@ -3305,6 +4933,7 @@ function toMotifError(error) {
|
|
|
3305
4933
|
IMAGE_EDITING_TOP_20,
|
|
3306
4934
|
IMAGE_TEXT_TO_IMAGE_TOP_20,
|
|
3307
4935
|
MODELS,
|
|
4936
|
+
MODEL_OUTPUT,
|
|
3308
4937
|
MotifError,
|
|
3309
4938
|
RECRAFT_STYLES,
|
|
3310
4939
|
RESOLUTIONS,
|
|
@@ -3316,14 +4945,22 @@ function toMotifError(error) {
|
|
|
3316
4945
|
aspectToGptSize,
|
|
3317
4946
|
buildFalToolRequest,
|
|
3318
4947
|
buildGenerateBody,
|
|
4948
|
+
describeModelOutput,
|
|
3319
4949
|
enrichPrompt,
|
|
3320
4950
|
err,
|
|
3321
4951
|
estimateCost,
|
|
3322
4952
|
estimateVideoCost,
|
|
4953
|
+
falToolParameters,
|
|
4954
|
+
formatCost,
|
|
3323
4955
|
getFalKeyFromEnv,
|
|
3324
4956
|
isFalToolId,
|
|
4957
|
+
losslessAvailability,
|
|
4958
|
+
measuredToolCost,
|
|
4959
|
+
modelOutput,
|
|
3325
4960
|
motifEnvSchema,
|
|
3326
4961
|
ok,
|
|
3327
4962
|
parseMotifEnv,
|
|
3328
|
-
|
|
4963
|
+
projectedToolCost,
|
|
4964
|
+
sanitizePrompt,
|
|
4965
|
+
sumCosts
|
|
3329
4966
|
});
|