@howells/motif-sdk 5.1.0 → 5.2.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/index.js CHANGED
@@ -706,7 +706,7 @@ function getOpenAiKeyFromEnv(input = process.env) {
706
706
  }
707
707
  //#endregion
708
708
  //#region src/models.ts
709
- const AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-08-23";
709
+ const AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-10-07";
710
710
  const AA_IMAGE_SOURCES = ["https://artificialanalysis.ai/image/leaderboard/text-to-image", "https://artificialanalysis.ai/image/leaderboard/editing"];
711
711
  const FAL_PRICING_CHECKED_AT = "2026-05-12";
712
712
  const FAL_PRICING_CHECKED_JUL_2026 = "2026-07-11";
@@ -714,6 +714,22 @@ const FAL_PRICING_CHECKED_AUG_2026 = "2026-08-23";
714
714
  const FAL_PRICING_CHECKED_SEP_2026 = "2026-09-16";
715
715
  const MODELS = {
716
716
  flare: {
717
+ benchmark: {
718
+ artificialAnalysis: {
719
+ editing: {
720
+ elo: 1163,
721
+ rank: 2
722
+ },
723
+ snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
724
+ sourceUrls: AA_IMAGE_SOURCES,
725
+ textToImage: {
726
+ elo: 1191,
727
+ rank: 2
728
+ }
729
+ },
730
+ useCase: "Frontier generation and editing, evaluated at max quality"
731
+ },
732
+ defaultQuality: "max",
717
733
  customImageSize: {
718
734
  maxEdge: 3840,
719
735
  maxPixels: 8294400,
@@ -750,6 +766,22 @@ const MODELS = {
750
766
  useQueue: true
751
767
  },
752
768
  sunburst: {
769
+ benchmark: {
770
+ artificialAnalysis: {
771
+ editing: {
772
+ elo: 1183,
773
+ rank: 1
774
+ },
775
+ snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
776
+ sourceUrls: AA_IMAGE_SOURCES,
777
+ textToImage: {
778
+ elo: 1198,
779
+ rank: 1
780
+ }
781
+ },
782
+ useCase: "Frontier generation and editing, evaluated at max quality"
783
+ },
784
+ defaultQuality: "max",
753
785
  customImageSize: {
754
786
  maxEdge: 3840,
755
787
  maxPixels: 8294400,
@@ -789,14 +821,14 @@ const MODELS = {
789
821
  benchmark: {
790
822
  artificialAnalysis: {
791
823
  editing: {
792
- elo: 1256,
793
- rank: 3
824
+ elo: 1125,
825
+ rank: 5
794
826
  },
795
827
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
796
828
  sourceUrls: AA_IMAGE_SOURCES,
797
829
  textToImage: {
798
- elo: 1369,
799
- rank: 1
830
+ elo: 1172,
831
+ rank: 3
800
832
  }
801
833
  },
802
834
  speed: {
@@ -809,7 +841,7 @@ const MODELS = {
809
841
  quality: "frontier",
810
842
  speed: "very_slow"
811
843
  },
812
- useCase: "Highest-ranked text-to-image quality and transparent PNGs"
844
+ useCase: "Established frontier generation and transparent PNGs"
813
845
  },
814
846
  customImageSize: {
815
847
  maxEdge: 3840,
@@ -860,14 +892,14 @@ const MODELS = {
860
892
  benchmark: {
861
893
  artificialAnalysis: {
862
894
  editing: {
863
- elo: 1250,
864
- rank: 5
895
+ elo: 1103,
896
+ rank: 12
865
897
  },
866
898
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
867
899
  sourceUrls: AA_IMAGE_SOURCES,
868
900
  textToImage: {
869
- elo: 1310,
870
- rank: 4
901
+ elo: 1107,
902
+ rank: 8
871
903
  }
872
904
  },
873
905
  speed: {
@@ -880,7 +912,7 @@ const MODELS = {
880
912
  quality: "frontier",
881
913
  speed: "slow"
882
914
  },
883
- useCase: "Best OpenAI edit quality with transparent PNG support"
915
+ useCase: "Established OpenAI editor with transparent PNG support"
884
916
  },
885
917
  editEndpoint: "fal-ai/gpt-image-1.5/edit",
886
918
  endpoint: "fal-ai/gpt-image-1.5",
@@ -913,18 +945,103 @@ const MODELS = {
913
945
  supportsSyncMode: true,
914
946
  type: "generation"
915
947
  },
916
- banana2: {
948
+ banana21: {
949
+ benchmark: { useCase: "Efficient generation and reference editing; Arena #5 generation / #6 editing, preliminary 2026-10-06" },
950
+ editEndpoint: "google/nano-banana-2.1/edit",
951
+ endpoint: "google/nano-banana-2.1",
952
+ maxReferenceImages: 14,
953
+ name: "Nano Banana 2.1",
954
+ pricePerImageUsd: null,
955
+ pricing: "Token-based: input $1.764/M, text/thinking output $8.823/M, image output $35.294/M; ~ $0.040 / $0.059 / $0.134 at 1K / 2K / 4K plus variable usage",
956
+ sizeMode: "aspect_ratio",
957
+ supportedAspects: [
958
+ "auto",
959
+ "21:9",
960
+ "16:9",
961
+ "3:2",
962
+ "4:3",
963
+ "5:4",
964
+ "1:1",
965
+ "4:5",
966
+ "3:4",
967
+ "2:3",
968
+ "9:16",
969
+ "4:1",
970
+ "1:4",
971
+ "8:1",
972
+ "1:8"
973
+ ],
974
+ supportedResolutions: [
975
+ "1K",
976
+ "2K",
977
+ "4K"
978
+ ],
979
+ supportsAspect: true,
980
+ supportsEdit: true,
981
+ supportsLimitGenerations: true,
982
+ supportsNumImages: true,
983
+ supportsOutputFormat: true,
984
+ supportsResolution: true,
985
+ supportsSafetyTolerance: true,
986
+ supportsSeed: true,
987
+ supportsSyncMode: true,
988
+ supportsThinkingLevel: true,
989
+ supportsWebSearch: true,
990
+ type: "generation"
991
+ },
992
+ "mai-image-2.5": {
917
993
  benchmark: {
918
994
  artificialAnalysis: {
919
995
  editing: {
920
- elo: 1249,
996
+ elo: 1114,
921
997
  rank: 7
922
998
  },
923
999
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
924
1000
  sourceUrls: AA_IMAGE_SOURCES,
925
1001
  textToImage: {
926
- elo: 1320,
927
- rank: 3
1002
+ elo: 1104,
1003
+ rank: 10
1004
+ }
1005
+ },
1006
+ useCase: "Strong single-reference editing at a lower price than MAI 2.5 Pro"
1007
+ },
1008
+ editEndpoint: "microsoft/mai-image-2.5/edit",
1009
+ endpoint: "microsoft/mai-image-2.5",
1010
+ maxReferenceImages: 1,
1011
+ name: "MAI Image 2.5",
1012
+ pricePerImageUsd: null,
1013
+ pricing: "Token-based: text input $5/M, image input $8/M; ~$0.05 image output plus input",
1014
+ sizeMode: "aspect_ratio",
1015
+ supportedAspects: [
1016
+ "auto",
1017
+ "1:1",
1018
+ "4:3",
1019
+ "3:4",
1020
+ "16:9",
1021
+ "9:16",
1022
+ "3:2",
1023
+ "2:3"
1024
+ ],
1025
+ supportsAspect: true,
1026
+ supportsEdit: true,
1027
+ supportsNumImages: true,
1028
+ supportsOutputFormat: true,
1029
+ supportsResolution: false,
1030
+ supportsSyncMode: true,
1031
+ type: "generation"
1032
+ },
1033
+ banana2: {
1034
+ benchmark: {
1035
+ artificialAnalysis: {
1036
+ editing: {
1037
+ elo: 1110,
1038
+ rank: 9
1039
+ },
1040
+ snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1041
+ sourceUrls: AA_IMAGE_SOURCES,
1042
+ textToImage: {
1043
+ elo: 1126,
1044
+ rank: 6
928
1045
  }
929
1046
  },
930
1047
  tiers: {
@@ -932,7 +1049,7 @@ const MODELS = {
932
1049
  quality: "frontier",
933
1050
  speed: "unknown"
934
1051
  },
935
- useCase: "Best balance of quality, edit support, web search, and cost"
1052
+ useCase: "Previous-generation Gemini workhorse; retains 0.5K output"
936
1053
  },
937
1054
  editEndpoint: "fal-ai/nano-banana-2/edit",
938
1055
  endpoint: "fal-ai/nano-banana-2",
@@ -968,14 +1085,14 @@ const MODELS = {
968
1085
  benchmark: {
969
1086
  artificialAnalysis: {
970
1087
  editing: {
971
- elo: 1245,
972
- rank: 9
1088
+ elo: 1101,
1089
+ rank: 13
973
1090
  },
974
1091
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
975
1092
  sourceUrls: AA_IMAGE_SOURCES,
976
1093
  textToImage: {
977
- elo: 1297,
978
- rank: 6
1094
+ elo: 1102,
1095
+ rank: 11
979
1096
  }
980
1097
  },
981
1098
  speed: {
@@ -1040,11 +1157,15 @@ const MODELS = {
1040
1157
  gemini: {
1041
1158
  benchmark: { artificialAnalysis: {
1042
1159
  editing: {
1043
- elo: 1180,
1044
- rank: 29
1160
+ elo: 987,
1161
+ rank: 50
1045
1162
  },
1046
1163
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1047
- sourceUrls: AA_IMAGE_SOURCES
1164
+ sourceUrls: AA_IMAGE_SOURCES,
1165
+ textToImage: {
1166
+ elo: 985,
1167
+ rank: 60
1168
+ }
1048
1169
  } },
1049
1170
  editEndpoint: "fal-ai/gemini-25-flash-image/edit",
1050
1171
  endpoint: "fal-ai/gemini-25-flash-image",
@@ -1085,18 +1206,6 @@ const MODELS = {
1085
1206
  type: "generation"
1086
1207
  },
1087
1208
  gemini3: {
1088
- benchmark: { artificialAnalysis: {
1089
- editing: {
1090
- elo: 1245,
1091
- rank: 9
1092
- },
1093
- snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1094
- sourceUrls: AA_IMAGE_SOURCES,
1095
- textToImage: {
1096
- elo: 1297,
1097
- rank: 6
1098
- }
1099
- } },
1100
1209
  editEndpoint: "fal-ai/gemini-3-pro-image-preview/edit",
1101
1210
  endpoint: "fal-ai/gemini-3-pro-image-preview",
1102
1211
  falPricing: {
@@ -1146,14 +1255,14 @@ const MODELS = {
1146
1255
  benchmark: {
1147
1256
  artificialAnalysis: {
1148
1257
  editing: {
1149
- elo: 1185,
1150
- rank: 28
1258
+ elo: 1015,
1259
+ rank: 36
1151
1260
  },
1152
1261
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1153
1262
  sourceUrls: AA_IMAGE_SOURCES,
1154
1263
  textToImage: {
1155
- elo: 1226,
1156
- rank: 16
1264
+ elo: 1030,
1265
+ rank: 21
1157
1266
  }
1158
1267
  },
1159
1268
  speed: {
@@ -1166,7 +1275,7 @@ const MODELS = {
1166
1275
  quality: "best",
1167
1276
  speed: "balanced"
1168
1277
  },
1169
- useCase: "High-ranked budget generation and large multi-reference edits"
1278
+ useCase: "Legacy budget generation and large multi-reference edits"
1170
1279
  },
1171
1280
  customImageSize: {
1172
1281
  maxPixels: 16777216,
@@ -1200,14 +1309,14 @@ const MODELS = {
1200
1309
  benchmark: {
1201
1310
  artificialAnalysis: {
1202
1311
  editing: {
1203
- elo: 1186,
1204
- rank: 26
1312
+ elo: 1037,
1313
+ rank: 32
1205
1314
  },
1206
1315
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1207
1316
  sourceUrls: AA_IMAGE_SOURCES,
1208
1317
  textToImage: {
1209
- elo: 1203,
1210
- rank: 32
1318
+ elo: 1022,
1319
+ rank: 26
1211
1320
  }
1212
1321
  },
1213
1322
  speed: {
@@ -1253,14 +1362,14 @@ const MODELS = {
1253
1362
  seedream5: {
1254
1363
  benchmark: { artificialAnalysis: {
1255
1364
  editing: {
1256
- elo: 1248,
1257
- rank: 8
1365
+ elo: 1108,
1366
+ rank: 11
1258
1367
  },
1259
1368
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1260
1369
  sourceUrls: AA_IMAGE_SOURCES,
1261
1370
  textToImage: {
1262
- elo: 1279,
1263
- rank: 10
1371
+ elo: 1081,
1372
+ rank: 15
1264
1373
  }
1265
1374
  } },
1266
1375
  customImageSize: {
@@ -1295,11 +1404,15 @@ const MODELS = {
1295
1404
  "seedream5-lite": {
1296
1405
  benchmark: { artificialAnalysis: {
1297
1406
  editing: {
1298
- elo: 1169,
1299
- rank: 32
1407
+ elo: 1057,
1408
+ rank: 24
1300
1409
  },
1301
1410
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1302
- sourceUrls: AA_IMAGE_SOURCES
1411
+ sourceUrls: AA_IMAGE_SOURCES,
1412
+ textToImage: {
1413
+ elo: 1012,
1414
+ rank: 36
1415
+ }
1303
1416
  } },
1304
1417
  customImageSize: {
1305
1418
  maxPixels: 16777216,
@@ -1333,14 +1446,14 @@ const MODELS = {
1333
1446
  benchmark: {
1334
1447
  artificialAnalysis: {
1335
1448
  editing: {
1336
- elo: 1201,
1337
- rank: 19
1449
+ elo: 997,
1450
+ rank: 49
1338
1451
  },
1339
1452
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1340
1453
  sourceUrls: AA_IMAGE_SOURCES,
1341
1454
  textToImage: {
1342
- elo: 1225,
1343
- rank: 17
1455
+ elo: 1020,
1456
+ rank: 28
1344
1457
  }
1345
1458
  },
1346
1459
  speed: {
@@ -1392,14 +1505,14 @@ const MODELS = {
1392
1505
  benchmark: {
1393
1506
  artificialAnalysis: {
1394
1507
  editing: {
1395
- elo: 1170,
1396
- rank: 31
1508
+ elo: 1007,
1509
+ rank: 41
1397
1510
  },
1398
1511
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1399
1512
  sourceUrls: AA_IMAGE_SOURCES,
1400
1513
  textToImage: {
1401
- elo: 1207,
1402
- rank: 30
1514
+ elo: 1004,
1515
+ rank: 41
1403
1516
  }
1404
1517
  },
1405
1518
  speed: {
@@ -1450,11 +1563,15 @@ const MODELS = {
1450
1563
  "flux2-flex": {
1451
1564
  benchmark: {
1452
1565
  artificialAnalysis: {
1566
+ editing: {
1567
+ elo: 1007,
1568
+ rank: 42
1569
+ },
1453
1570
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1454
1571
  sourceUrls: AA_IMAGE_SOURCES,
1455
1572
  textToImage: {
1456
- elo: 1223,
1457
- rank: 18
1573
+ elo: 1027,
1574
+ rank: 22
1458
1575
  }
1459
1576
  },
1460
1577
  speed: {
@@ -1508,8 +1625,16 @@ const MODELS = {
1508
1625
  "flux2-dev": {
1509
1626
  benchmark: {
1510
1627
  artificialAnalysis: {
1628
+ editing: {
1629
+ elo: 1e3,
1630
+ rank: 45
1631
+ },
1511
1632
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1512
- sourceUrls: AA_IMAGE_SOURCES
1633
+ sourceUrls: AA_IMAGE_SOURCES,
1634
+ textToImage: {
1635
+ elo: 1e3,
1636
+ rank: 42
1637
+ }
1513
1638
  },
1514
1639
  speed: {
1515
1640
  medianSeconds: 4.6,
@@ -1672,24 +1797,12 @@ const MODELS = {
1672
1797
  },
1673
1798
  reve: {
1674
1799
  benchmark: {
1675
- artificialAnalysis: {
1676
- editing: {
1677
- elo: 1263,
1678
- rank: 2
1679
- },
1680
- snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1681
- sourceUrls: AA_IMAGE_SOURCES,
1682
- textToImage: {
1683
- elo: 1322,
1684
- rank: 2
1685
- }
1686
- },
1687
1800
  tiers: {
1688
1801
  price: "premium",
1689
1802
  quality: "frontier",
1690
1803
  speed: "unknown"
1691
1804
  },
1692
- useCase: "Highest-ranked editor reachable on fal; strong prompt adherence and text rendering"
1805
+ useCase: "Historical Reve route; not currently verified on fal"
1693
1806
  },
1694
1807
  editEndpoint: "fal-ai/reve/edit",
1695
1808
  endpoint: "fal-ai/reve/text-to-image",
@@ -1730,8 +1843,8 @@ const MODELS = {
1730
1843
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1731
1844
  sourceUrls: AA_IMAGE_SOURCES,
1732
1845
  textToImage: {
1733
- elo: 1215,
1734
- rank: 25
1846
+ elo: 984,
1847
+ rank: 62
1735
1848
  }
1736
1849
  } },
1737
1850
  customImageSize: {},
@@ -1789,8 +1902,8 @@ const MODELS = {
1789
1902
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1790
1903
  sourceUrls: AA_IMAGE_SOURCES,
1791
1904
  textToImage: {
1792
- elo: 1220,
1793
- rank: 19
1905
+ elo: 1004,
1906
+ rank: 40
1794
1907
  }
1795
1908
  } },
1796
1909
  customImageSize: {
@@ -1828,14 +1941,14 @@ const MODELS = {
1828
1941
  benchmark: {
1829
1942
  artificialAnalysis: {
1830
1943
  editing: {
1831
- elo: 1214,
1832
- rank: 16
1944
+ elo: 1073,
1945
+ rank: 19
1833
1946
  },
1834
1947
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1835
1948
  sourceUrls: AA_IMAGE_SOURCES,
1836
1949
  textToImage: {
1837
- elo: 1216,
1838
- rank: 23
1950
+ elo: 1019,
1951
+ rank: 30
1839
1952
  }
1840
1953
  },
1841
1954
  speed: {
@@ -1888,7 +2001,11 @@ const MODELS = {
1888
2001
  benchmark: {
1889
2002
  artificialAnalysis: {
1890
2003
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1891
- sourceUrls: AA_IMAGE_SOURCES
2004
+ sourceUrls: AA_IMAGE_SOURCES,
2005
+ textToImage: {
2006
+ elo: 890,
2007
+ rank: 106
2008
+ }
1892
2009
  },
1893
2010
  speed: {
1894
2011
  medianSeconds: 23.3,
@@ -1930,14 +2047,14 @@ const MODELS = {
1930
2047
  benchmark: {
1931
2048
  artificialAnalysis: {
1932
2049
  editing: {
1933
- elo: 1218,
1934
- rank: 15
2050
+ elo: 1056,
2051
+ rank: 25
1935
2052
  },
1936
2053
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1937
2054
  sourceUrls: AA_IMAGE_SOURCES,
1938
2055
  textToImage: {
1939
- elo: 1272,
1940
- rank: 11
2056
+ elo: 1075,
2057
+ rank: 16
1941
2058
  }
1942
2059
  },
1943
2060
  tiers: {
@@ -1945,7 +2062,7 @@ const MODELS = {
1945
2062
  quality: "better",
1946
2063
  speed: "unknown"
1947
2064
  },
1948
- useCase: "Strong quality per dollar - 11th on text-to-image at $30/1k"
2065
+ useCase: "Strong generation with negative-prompt and seed controls"
1949
2066
  },
1950
2067
  customImageSize: {
1951
2068
  maxPixels: 4194304,
@@ -1979,17 +2096,17 @@ const MODELS = {
1979
2096
  benchmark: {
1980
2097
  artificialAnalysis: {
1981
2098
  editing: {
1982
- elo: 1272,
1983
- rank: 1
2099
+ elo: 1110,
2100
+ rank: 10
1984
2101
  },
1985
2102
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
1986
2103
  sourceUrls: AA_IMAGE_SOURCES,
1987
2104
  textToImage: {
1988
- elo: 1293,
1989
- rank: 7
2105
+ elo: 1100,
2106
+ rank: 12
1990
2107
  }
1991
2108
  },
1992
- useCase: "Highest-ranked image editor, single reference image"
2109
+ useCase: "Strong single-reference editor; MAI 2.5 ranks higher on the current editing board"
1993
2110
  },
1994
2111
  editEndpoint: "microsoft/mai-image-2.5-pro/edit",
1995
2112
  editImagesField: "image_url",
@@ -2028,20 +2145,26 @@ const MODELS = {
2028
2145
  },
2029
2146
  "banana2-lite": {
2030
2147
  benchmark: { artificialAnalysis: {
2148
+ editing: {
2149
+ elo: 1046,
2150
+ rank: 26
2151
+ },
2031
2152
  snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
2032
2153
  sourceUrls: AA_IMAGE_SOURCES,
2033
2154
  textToImage: {
2034
- elo: 1289,
2035
- rank: 8
2155
+ elo: 1095,
2156
+ rank: 13
2036
2157
  }
2037
2158
  } },
2159
+ editEndpoint: "google/nano-banana-2-lite/edit",
2160
+ maxReferenceImages: 14,
2038
2161
  endpoint: "google/nano-banana-2-lite",
2039
2162
  name: "Nano Banana 2 Lite",
2040
- pricing: "Token-based: text $0.3125/M input, $1.875/M output; image $0.3125/M input, $37.50/M output; fixed 1K output (~$0.048)",
2041
- pricePerImageUsd: .048,
2163
+ pricing: "Token-based: text $0.3125/M input, $1.875/M output; image $0.3125/M input, $37.50/M output; fixed 1K output (~$0.042 image output, plus input/thinking)",
2164
+ pricePerImageUsd: null,
2042
2165
  sizeMode: "aspect_ratio",
2043
2166
  supportsAspect: true,
2044
- supportsEdit: false,
2167
+ supportsEdit: true,
2045
2168
  supportsLimitGenerations: true,
2046
2169
  supportsNumImages: true,
2047
2170
  supportsOutputFormat: true,
@@ -2114,6 +2237,21 @@ const MODELS = {
2114
2237
  type: "generation"
2115
2238
  },
2116
2239
  "grok-image-2": {
2240
+ benchmark: {
2241
+ artificialAnalysis: {
2242
+ editing: {
2243
+ elo: 1110,
2244
+ rank: 8
2245
+ },
2246
+ snapshotDate: AA_IMAGE_LEADERBOARD_SNAPSHOT,
2247
+ sourceUrls: AA_IMAGE_SOURCES,
2248
+ textToImage: {
2249
+ elo: 1156,
2250
+ rank: 4
2251
+ }
2252
+ },
2253
+ useCase: "Strong generation and editing with predictable per-image billing"
2254
+ },
2117
2255
  editEndpoint: "xai/grok-imagine-image/v2.0/edit",
2118
2256
  endpoint: "xai/grok-imagine-image/v2.0/text-to-image",
2119
2257
  falPricing: {
@@ -2211,38 +2349,44 @@ const MODELS = {
2211
2349
  type: "utility"
2212
2350
  }
2213
2351
  };
2352
+ /** Curated generation choices; predecessor routes are explicit-only. */
2214
2353
  const GENERATION_MODELS = [
2215
- "flare",
2216
2354
  "sunburst",
2355
+ "flare",
2217
2356
  "gpt2",
2218
2357
  "gpt",
2358
+ "banana21",
2219
2359
  "banana2",
2220
2360
  "banana",
2361
+ "mai-image-2.5",
2362
+ "mai-image-2.5-pro",
2363
+ "seedream5",
2364
+ "qwen3",
2365
+ "banana2-lite",
2366
+ "grok-image-2",
2367
+ "grok-image",
2368
+ "flux2-flex",
2369
+ "flux2-pro",
2370
+ "flux2-turbo",
2371
+ "seedream5-lite",
2372
+ "ideogram4",
2373
+ "ideogram3-transparent",
2374
+ "recraft41"
2375
+ ];
2376
+ /** Retained for old pins, explicit overrides and tuned Looks, never auto-selected. */
2377
+ const LEGACY_GENERATION_MODELS = [
2221
2378
  "gemini",
2222
2379
  "gemini3",
2223
2380
  "seedream4",
2224
2381
  "seedream45",
2225
- "seedream5",
2226
- "seedream5-lite",
2227
2382
  "flux2-max",
2228
- "flux2-pro",
2229
- "flux2-flex",
2230
2383
  "flux2-dev",
2231
- "flux2-turbo",
2232
2384
  "flux",
2233
2385
  "flux-fast",
2234
2386
  "recraft",
2235
2387
  "recraft4",
2236
2388
  "ideogram",
2237
- "ideogram4",
2238
- "grok-image",
2239
- "grok-image-2",
2240
- "qwen",
2241
- "qwen3",
2242
- "mai-image-2.5-pro",
2243
- "banana2-lite",
2244
- "ideogram3-transparent",
2245
- "recraft41"
2389
+ "qwen"
2246
2390
  ];
2247
2391
  GENERATION_MODELS.filter((id) => MODELS[id]?.supportsEdit === true);
2248
2392
  const UTILITY_MODELS = [
@@ -2343,6 +2487,16 @@ function endpointFromQueueUrl(url, fallback) {
2343
2487
  return fallback;
2344
2488
  }
2345
2489
  }
2490
+ /**
2491
+ * The queue path a submitted run is read back from: fal's app id, its owner and
2492
+ * app, without any route below it. `fal-ai/nano-banana-pro/edit` is submitted
2493
+ * there but read at `fal-ai/nano-banana-pro/requests/<id>`; the full path
2494
+ * answers 405. A live submit learns this from `response_url`; a resume has
2495
+ * only the id, so it derives it.
2496
+ */
2497
+ function queueAppPath(endpoint) {
2498
+ return endpoint.split("/").slice(0, 2).join("/");
2499
+ }
2346
2500
  function parseQueueSubmission(data) {
2347
2501
  if (!isRecord$4(data)) return { requestId: "" };
2348
2502
  return {
@@ -2609,7 +2763,7 @@ function buildGenerateBody(options) {
2609
2763
  if (config.supportsAspect) body.aspect_ratio = aspect;
2610
2764
  if (config.supportsResolution) body.resolution = model === "grok-image" || model === "grok-image-2" ? resolution.toLowerCase() : resolution;
2611
2765
  }
2612
- if (config.supportsQuality === true) body.quality = quality ?? "high";
2766
+ if (config.supportsQuality === true) body.quality = quality ?? config.defaultQuality ?? "high";
2613
2767
  if (config.supportsBackground === true && background) body.background = background;
2614
2768
  if (config.supportsBackground === true && transparent === true) body.background = "transparent";
2615
2769
  if (transparent === true && config.supportsOutputFormat === true) body.output_format = "png";
@@ -5037,134 +5191,7 @@ const TIERS = [
5037
5191
  ];
5038
5192
  const DEFAULT_TIER = "balanced";
5039
5193
  const HAND_RANKED_AT = "2026-09-16";
5040
- const GENERATION_MODELS_RANKED = [
5041
- {
5042
- model: "gpt2",
5043
- tier: "quality"
5044
- },
5045
- {
5046
- model: "banana2",
5047
- tier: "quality"
5048
- },
5049
- {
5050
- model: "gpt",
5051
- tier: "quality"
5052
- },
5053
- {
5054
- model: "sunburst",
5055
- tier: "quality"
5056
- },
5057
- {
5058
- model: "gemini3",
5059
- tier: "quality"
5060
- },
5061
- {
5062
- model: "mai-image-2.5-pro",
5063
- tier: "quality"
5064
- },
5065
- {
5066
- model: "seedream5",
5067
- tier: "quality"
5068
- },
5069
- {
5070
- model: "flux2-max",
5071
- tier: "quality"
5072
- },
5073
- {
5074
- model: "banana",
5075
- tier: "balanced"
5076
- },
5077
- {
5078
- model: "ideogram3-transparent",
5079
- requires: ["transparency"],
5080
- supports: ["transparency"],
5081
- tier: "balanced"
5082
- },
5083
- {
5084
- model: "flare",
5085
- tier: "balanced"
5086
- },
5087
- {
5088
- model: "banana2-lite",
5089
- tier: "balanced"
5090
- },
5091
- {
5092
- model: "qwen3",
5093
- tier: "balanced"
5094
- },
5095
- {
5096
- model: "seedream4",
5097
- tier: "balanced"
5098
- },
5099
- {
5100
- model: "flux2-flex",
5101
- tier: "balanced"
5102
- },
5103
- {
5104
- model: "ideogram4",
5105
- tier: "balanced"
5106
- },
5107
- {
5108
- model: "grok-image",
5109
- tier: "balanced"
5110
- },
5111
- {
5112
- model: "recraft4",
5113
- tier: "balanced"
5114
- },
5115
- {
5116
- model: "flux2-pro",
5117
- tier: "balanced"
5118
- },
5119
- {
5120
- model: "seedream45",
5121
- tier: "balanced"
5122
- },
5123
- {
5124
- model: "grok-image-2",
5125
- tier: "balanced"
5126
- },
5127
- {
5128
- model: "recraft41",
5129
- tier: "balanced"
5130
- },
5131
- {
5132
- model: "flux2-turbo",
5133
- tier: "fast"
5134
- },
5135
- {
5136
- model: "flux2-dev",
5137
- tier: "fast"
5138
- },
5139
- {
5140
- model: "flux-fast",
5141
- tier: "fast"
5142
- },
5143
- {
5144
- model: "seedream5-lite",
5145
- tier: "fast"
5146
- },
5147
- {
5148
- model: "gemini",
5149
- tier: "fast"
5150
- },
5151
- {
5152
- model: "qwen",
5153
- tier: "fast"
5154
- },
5155
- {
5156
- model: "ideogram",
5157
- tier: "fast"
5158
- },
5159
- {
5160
- model: "recraft",
5161
- tier: "fast"
5162
- },
5163
- {
5164
- model: "flux",
5165
- tier: "fast"
5166
- }
5167
- ];
5194
+ const IMAGE_RANKED_AT = "2026-10-07";
5168
5195
  /** Every Task with a Model. A Task is absent here until it has at least one Model. */
5169
5196
  const TASKS = {
5170
5197
  animate: {
@@ -5335,10 +5362,97 @@ const TASKS = {
5335
5362
  summary: "Remove an object, person, text or clutter from an image and fill the gap."
5336
5363
  },
5337
5364
  generate: {
5338
- basis: "Hand-ranked. Tiers set by fal price per image (quality ≥ $0.07, balanced $0.02-$0.15 with edit quality, fast ≤ $0.04); order within a tier by Artificial Analysis text-to-image Elo, snapshot 2026-08-23, unranked models last. banana leads balanced because it is the house default the looks are tuned on. Ideogram V3 Transparent follows it but is chosen only for a transparent request, so transparency needs no OpenAI key at balanced; token-metered Nano Banana 2 Lite sits in balanced by its Elo.",
5339
- models: GENERATION_MODELS_RANKED,
5365
+ basis: "Curated from Artificial Analysis v2, captured 2026-10-07, and Arena 2026-10-06. Sunburst and Flare lead quality at the benchmarked max setting. Nano Banana 2.1 leads balanced on preliminary Arena evidence and lower representative cost; Grok Image 2 and MAI 2.5 are established alternatives. Fast keeps Nano Banana 2 Lite, budget Grok and Seedream 5 Lite, and FLUX.2 Turbo. Design, transparency and tuned Look routes are capability exceptions. Generation with References uses the separate editing ranking. Older routes are explicit/pin/Look-only.",
5366
+ models: [
5367
+ {
5368
+ model: "sunburst",
5369
+ tier: "quality"
5370
+ },
5371
+ {
5372
+ model: "flare",
5373
+ tier: "quality"
5374
+ },
5375
+ {
5376
+ model: "gpt2",
5377
+ tier: "quality"
5378
+ },
5379
+ {
5380
+ model: "gpt",
5381
+ tier: "quality"
5382
+ },
5383
+ {
5384
+ model: "mai-image-2.5-pro",
5385
+ tier: "quality"
5386
+ },
5387
+ {
5388
+ model: "seedream5",
5389
+ tier: "quality"
5390
+ },
5391
+ {
5392
+ model: "banana21",
5393
+ tier: "balanced"
5394
+ },
5395
+ {
5396
+ model: "grok-image-2",
5397
+ tier: "balanced"
5398
+ },
5399
+ {
5400
+ model: "banana2",
5401
+ tier: "balanced"
5402
+ },
5403
+ {
5404
+ model: "mai-image-2.5",
5405
+ tier: "balanced"
5406
+ },
5407
+ {
5408
+ model: "banana",
5409
+ tier: "balanced"
5410
+ },
5411
+ {
5412
+ model: "qwen3",
5413
+ tier: "balanced"
5414
+ },
5415
+ {
5416
+ model: "flux2-flex",
5417
+ tier: "balanced"
5418
+ },
5419
+ {
5420
+ model: "flux2-pro",
5421
+ tier: "balanced"
5422
+ },
5423
+ {
5424
+ model: "ideogram4",
5425
+ tier: "balanced"
5426
+ },
5427
+ {
5428
+ model: "recraft41",
5429
+ tier: "balanced"
5430
+ },
5431
+ {
5432
+ model: "ideogram3-transparent",
5433
+ requires: ["transparency"],
5434
+ supports: ["transparency"],
5435
+ tier: "balanced"
5436
+ },
5437
+ {
5438
+ model: "banana2-lite",
5439
+ tier: "fast"
5440
+ },
5441
+ {
5442
+ model: "grok-image",
5443
+ tier: "fast"
5444
+ },
5445
+ {
5446
+ model: "seedream5-lite",
5447
+ tier: "fast"
5448
+ },
5449
+ {
5450
+ model: "flux2-turbo",
5451
+ tier: "fast"
5452
+ }
5453
+ ],
5340
5454
  notFor: "Variations of an image you already have (vary), or a consistent set of images (series run).",
5341
- rankedAt: HAND_RANKED_AT,
5455
+ rankedAt: IMAGE_RANKED_AT,
5342
5456
  rankedFrom: "hand",
5343
5457
  summary: "Make an image from a prompt, or change an image you pass as a reference."
5344
5458
  },
@@ -5823,10 +5937,75 @@ const TASKS = {
5823
5937
  summary: "Trace a raster image to a clean SVG."
5824
5938
  },
5825
5939
  vary: {
5826
- basis: "The generate ranking, filtered to Models that can edit. vary reuses the Model of the image it varies while Motif still offers it.",
5827
- models: GENERATION_MODELS_RANKED.filter(({ model }) => MODELS[model]?.supportsEdit === true),
5940
+ basis: "Curated from Artificial Analysis v2 editing, captured 2026-10-07, and preliminary Arena 2026-10-06 evidence for Nano Banana 2.1. Editing order differs from generation: MAI 2.5 outranks Grok Image 2, and Seedream 5 Pro outranks GPT Image 1.5. Sunburst and Flare use max quality. vary reuses a previously chosen Model when explicitly supplied, including retained legacy routes.",
5941
+ models: [
5942
+ {
5943
+ model: "sunburst",
5944
+ tier: "quality"
5945
+ },
5946
+ {
5947
+ model: "flare",
5948
+ tier: "quality"
5949
+ },
5950
+ {
5951
+ model: "gpt2",
5952
+ tier: "quality"
5953
+ },
5954
+ {
5955
+ model: "mai-image-2.5-pro",
5956
+ tier: "quality"
5957
+ },
5958
+ {
5959
+ model: "seedream5",
5960
+ tier: "quality"
5961
+ },
5962
+ {
5963
+ model: "gpt",
5964
+ tier: "quality"
5965
+ },
5966
+ {
5967
+ model: "banana21",
5968
+ tier: "balanced"
5969
+ },
5970
+ {
5971
+ model: "mai-image-2.5",
5972
+ tier: "balanced"
5973
+ },
5974
+ {
5975
+ model: "grok-image-2",
5976
+ tier: "balanced"
5977
+ },
5978
+ {
5979
+ model: "banana2",
5980
+ tier: "balanced"
5981
+ },
5982
+ {
5983
+ model: "banana",
5984
+ tier: "balanced"
5985
+ },
5986
+ {
5987
+ model: "flux2-pro",
5988
+ tier: "balanced"
5989
+ },
5990
+ {
5991
+ model: "flux2-flex",
5992
+ tier: "balanced"
5993
+ },
5994
+ {
5995
+ model: "grok-image",
5996
+ tier: "fast"
5997
+ },
5998
+ {
5999
+ model: "seedream5-lite",
6000
+ tier: "fast"
6001
+ },
6002
+ {
6003
+ model: "banana2-lite",
6004
+ tier: "fast"
6005
+ }
6006
+ ],
5828
6007
  notFor: "A specific change to an image described in words (generate with a reference), or a set of different scenes in one style (series run).",
5829
- rankedAt: HAND_RANKED_AT,
6008
+ rankedAt: IMAGE_RANKED_AT,
5830
6009
  rankedFrom: "hand",
5831
6010
  summary: "Make variations of an image you already have."
5832
6011
  }
@@ -8211,7 +8390,7 @@ function resolveFixed(task, fixed, request, needed, keys) {
8211
8390
  const { chosenBy, model } = fixed;
8212
8391
  const tier = request.tier ?? "balanced";
8213
8392
  const entries = TASKS[task].models;
8214
- const entry = entries.find((candidate) => candidate.model === model && candidate.mode === request.mode);
8393
+ const entry = entries.find((candidate) => candidate.model === model && candidate.mode === request.mode) ?? legacyEntry(task, model, request.mode, tier);
8215
8394
  const profile = modelProfile(model);
8216
8395
  if (entry === void 0 || profile === void 0) {
8217
8396
  const servesTask = entries.some((candidate) => candidate.model === model);
@@ -8224,6 +8403,14 @@ function resolveFixed(task, fixed, request, needed, keys) {
8224
8403
  unblockers.push(unblockerFor(result));
8225
8404
  return unresolved(task, result.blockedBy, unblockers, `${model} (${chosenBy}) ${describeBlock(result.blockedBy, result.missingKey, result.missingInput)}.`, result.missingKey);
8226
8405
  }
8406
+ /** Old pins and tuned Looks remain usable without recommending predecessors. */
8407
+ function legacyEntry(task, model, mode, tier) {
8408
+ if (mode !== void 0 || task !== "generate" && task !== "vary" || !LEGACY_GENERATION_MODELS.some((id) => id === model) || task === "vary" && MODELS[model]?.supportsEdit !== true) return;
8409
+ return {
8410
+ model,
8411
+ tier
8412
+ };
8413
+ }
8227
8414
  function unknownForMode(task, model, mode, entries) {
8228
8415
  const otherModes = entries.filter((candidate) => candidate.model === model).map((candidate) => candidate.mode ?? "no mode");
8229
8416
  const inMode = [...new Set(entries.filter((candidate) => candidate.mode === mode).map((candidate) => candidate.model))];
@@ -8240,7 +8427,7 @@ function resolveRanked(task, request, needed, keys) {
8240
8427
  const qualifying = /* @__PURE__ */ new Map();
8241
8428
  let firstBlock;
8242
8429
  let keyBlock;
8243
- const definition = TASKS[task];
8430
+ const definition = task === "generate" && (request.references ?? 0) > 0 ? TASKS.vary : TASKS[task];
8244
8431
  for (const entry of definition.models) {
8245
8432
  if (entry.mode !== request.mode) continue;
8246
8433
  const { model, tier: modelTier } = entry;
@@ -10524,7 +10711,7 @@ function createMotif(config = {}) {
10524
10711
  const client = falClient();
10525
10712
  if (client.isErr()) return err$1(client.error);
10526
10713
  return (await awaitQueuedRequest(falRequestExecutor(client.value), {
10527
- endpoint: chosen.endpoint,
10714
+ endpoint: queueAppPath(chosen.endpoint),
10528
10715
  requestId
10529
10716
  }, input.onProgress)).map((value) => falOutput(chosen, value));
10530
10717
  }