egaki 0.5.0 → 0.7.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.
Files changed (280) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/dist/cli/cache-utils.d.ts +33 -0
  3. package/dist/cli/cache-utils.d.ts.map +1 -0
  4. package/dist/cli/cache-utils.js +157 -0
  5. package/dist/cli/cached-generate.d.ts +105 -0
  6. package/dist/cli/cached-generate.d.ts.map +1 -0
  7. package/dist/cli/cached-generate.js +208 -0
  8. package/dist/cli/cached-generate.test.d.ts +11 -0
  9. package/dist/cli/cached-generate.test.d.ts.map +1 -0
  10. package/dist/cli/cached-generate.test.js +431 -0
  11. package/dist/cli/cartesia-provider.d.ts +16 -0
  12. package/dist/cli/cartesia-provider.d.ts.map +1 -0
  13. package/dist/cli/cartesia-provider.js +184 -0
  14. package/dist/cli/chatgpt-auth.d.ts.map +1 -0
  15. package/dist/cli/cli.d.ts +4 -0
  16. package/dist/cli/cli.d.ts.map +1 -0
  17. package/dist/cli/cli.js +1329 -0
  18. package/dist/cli/clone-generate.d.ts +26 -0
  19. package/dist/cli/clone-generate.d.ts.map +1 -0
  20. package/dist/cli/clone-generate.js +148 -0
  21. package/dist/{credentials.d.ts → cli/credentials.d.ts} +11 -2
  22. package/dist/cli/credentials.d.ts.map +1 -0
  23. package/dist/{credentials.js → cli/credentials.js} +88 -5
  24. package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
  25. package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
  26. package/dist/cli/elevenlabs-speech-provider.js +199 -0
  27. package/dist/cli/generate.d.ts +140 -0
  28. package/dist/cli/generate.d.ts.map +1 -0
  29. package/dist/cli/generate.js +604 -0
  30. package/dist/cli/generate.test.d.ts +2 -0
  31. package/dist/cli/generate.test.d.ts.map +1 -0
  32. package/dist/cli/generate.test.js +131 -0
  33. package/dist/cli/login.d.ts.map +1 -0
  34. package/dist/{login.js → cli/login.js} +45 -4
  35. package/dist/cli/main.d.ts +3 -0
  36. package/dist/cli/main.d.ts.map +1 -0
  37. package/dist/cli/main.js +7 -0
  38. package/dist/cli/model-catalog.d.ts +141 -0
  39. package/dist/cli/model-catalog.d.ts.map +1 -0
  40. package/dist/cli/model-catalog.js +2135 -0
  41. package/dist/{models.d.ts → cli/models.d.ts} +16 -9
  42. package/dist/cli/models.d.ts.map +1 -0
  43. package/dist/cli/models.js +313 -0
  44. package/dist/cli/open-browser.d.ts.map +1 -0
  45. package/dist/cli/openai-speech-provider.d.ts +3 -0
  46. package/dist/cli/openai-speech-provider.d.ts.map +1 -0
  47. package/dist/cli/openai-speech-provider.js +28 -0
  48. package/dist/cli/separation-generate.d.ts +34 -0
  49. package/dist/cli/separation-generate.d.ts.map +1 -0
  50. package/dist/cli/separation-generate.js +117 -0
  51. package/dist/cli/speech-catalog.d.ts +35 -0
  52. package/dist/cli/speech-catalog.d.ts.map +1 -0
  53. package/dist/cli/speech-catalog.js +195 -0
  54. package/dist/cli/speech-generate.d.ts +86 -0
  55. package/dist/cli/speech-generate.d.ts.map +1 -0
  56. package/dist/cli/speech-generate.js +156 -0
  57. package/dist/cli/speech-models.d.ts +8 -0
  58. package/dist/cli/speech-models.d.ts.map +1 -0
  59. package/dist/cli/speech-models.js +109 -0
  60. package/dist/cli/speech-provider.test.d.ts +2 -0
  61. package/dist/cli/speech-provider.test.d.ts.map +1 -0
  62. package/dist/cli/speech-provider.test.js +197 -0
  63. package/dist/cli/subscription.d.ts.map +1 -0
  64. package/dist/cli/transcription-catalog.d.ts +35 -0
  65. package/dist/cli/transcription-catalog.d.ts.map +1 -0
  66. package/dist/cli/transcription-catalog.js +192 -0
  67. package/dist/cli/transcription-generate.d.ts +62 -0
  68. package/dist/cli/transcription-generate.d.ts.map +1 -0
  69. package/dist/cli/transcription-generate.js +144 -0
  70. package/dist/cli/transcription-models.d.ts +9 -0
  71. package/dist/cli/transcription-models.d.ts.map +1 -0
  72. package/dist/cli/transcription-models.js +100 -0
  73. package/dist/cli/transcription-providers.d.ts +22 -0
  74. package/dist/cli/transcription-providers.d.ts.map +1 -0
  75. package/dist/cli/transcription-providers.js +290 -0
  76. package/dist/cli/video-model-catalog.d.ts +2 -0
  77. package/dist/cli/video-model-catalog.d.ts.map +1 -0
  78. package/dist/cli/video-model-catalog.js +5 -0
  79. package/dist/cli/xai-auth.d.ts +29 -0
  80. package/dist/cli/xai-auth.d.ts.map +1 -0
  81. package/dist/cli/xai-auth.js +325 -0
  82. package/dist/vite/angled-screen.d.ts +57 -0
  83. package/dist/vite/angled-screen.d.ts.map +1 -0
  84. package/dist/vite/angled-screen.js +115 -0
  85. package/dist/vite/app.d.ts +51 -0
  86. package/dist/vite/app.d.ts.map +1 -0
  87. package/dist/vite/app.js +150 -0
  88. package/dist/vite/bands-shader.d.ts +47 -0
  89. package/dist/vite/bands-shader.d.ts.map +1 -0
  90. package/dist/vite/bands-shader.js +267 -0
  91. package/dist/vite/code-block.d.ts +107 -0
  92. package/dist/vite/code-block.d.ts.map +1 -0
  93. package/dist/vite/code-block.js +641 -0
  94. package/dist/vite/components.d.ts +36 -0
  95. package/dist/vite/components.d.ts.map +1 -0
  96. package/dist/vite/components.js +113 -0
  97. package/dist/vite/dispersion-rings-shader.d.ts +44 -0
  98. package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
  99. package/dist/vite/dispersion-rings-shader.js +282 -0
  100. package/dist/vite/easing-curves.d.ts +129 -0
  101. package/dist/vite/easing-curves.d.ts.map +1 -0
  102. package/dist/vite/easing-curves.js +584 -0
  103. package/dist/vite/easing-curves.test.d.ts +2 -0
  104. package/dist/vite/easing-curves.test.d.ts.map +1 -0
  105. package/dist/vite/easing-curves.test.js +200 -0
  106. package/dist/vite/generated-media-client.d.ts +35 -0
  107. package/dist/vite/generated-media-client.d.ts.map +1 -0
  108. package/dist/vite/generated-media-client.js +76 -0
  109. package/dist/vite/keyframes.d.ts +129 -0
  110. package/dist/vite/keyframes.d.ts.map +1 -0
  111. package/dist/vite/keyframes.js +194 -0
  112. package/dist/vite/layout-editor.d.ts +45 -0
  113. package/dist/vite/layout-editor.d.ts.map +1 -0
  114. package/dist/vite/layout-editor.js +587 -0
  115. package/dist/vite/layout-transition.d.ts +136 -0
  116. package/dist/vite/layout-transition.d.ts.map +1 -0
  117. package/dist/vite/layout-transition.js +581 -0
  118. package/dist/vite/liquid-gradient-shader.d.ts +62 -0
  119. package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
  120. package/dist/vite/liquid-gradient-shader.js +413 -0
  121. package/dist/vite/mdx-client.d.ts +15 -0
  122. package/dist/vite/mdx-client.d.ts.map +1 -0
  123. package/dist/vite/mdx-client.js +265 -0
  124. package/dist/vite/mdx-parse.d.ts +102 -0
  125. package/dist/vite/mdx-parse.d.ts.map +1 -0
  126. package/dist/vite/mdx-parse.js +251 -0
  127. package/dist/vite/mdx-provided-components.d.ts +18 -0
  128. package/dist/vite/mdx-provided-components.d.ts.map +1 -0
  129. package/dist/vite/mdx-provided-components.js +14 -0
  130. package/dist/vite/mdx-video.d.ts +327 -0
  131. package/dist/vite/mdx-video.d.ts.map +1 -0
  132. package/dist/vite/mdx-video.js +596 -0
  133. package/dist/vite/mdx-video.test.d.ts +9 -0
  134. package/dist/vite/mdx-video.test.d.ts.map +1 -0
  135. package/dist/vite/mdx-video.test.js +1945 -0
  136. package/dist/vite/media-components.d.ts +45 -0
  137. package/dist/vite/media-components.d.ts.map +1 -0
  138. package/dist/vite/media-components.js +355 -0
  139. package/dist/vite/media-duration-store.d.ts +66 -0
  140. package/dist/vite/media-duration-store.d.ts.map +1 -0
  141. package/dist/vite/media-duration-store.js +204 -0
  142. package/dist/vite/player-page.d.ts +35 -0
  143. package/dist/vite/player-page.d.ts.map +1 -0
  144. package/dist/vite/player-page.js +720 -0
  145. package/dist/vite/render-client.d.ts +18 -0
  146. package/dist/vite/render-client.d.ts.map +1 -0
  147. package/dist/vite/render-client.js +67 -0
  148. package/dist/vite/sdk.d.ts +221 -0
  149. package/dist/vite/sdk.d.ts.map +1 -0
  150. package/dist/vite/sdk.js +355 -0
  151. package/dist/vite/server-components.d.ts +55 -0
  152. package/dist/vite/server-components.d.ts.map +1 -0
  153. package/dist/vite/server-components.js +156 -0
  154. package/dist/vite/server-mdx.d.ts +74 -0
  155. package/dist/vite/server-mdx.d.ts.map +1 -0
  156. package/dist/vite/server-mdx.js +259 -0
  157. package/dist/vite/shader-renderer.d.ts +48 -0
  158. package/dist/vite/shader-renderer.d.ts.map +1 -0
  159. package/dist/vite/shader-renderer.js +411 -0
  160. package/dist/vite/store-hooks.d.ts +12 -0
  161. package/dist/vite/store-hooks.d.ts.map +1 -0
  162. package/dist/vite/store-hooks.js +93 -0
  163. package/dist/vite/store.d.ts +75 -0
  164. package/dist/vite/store.d.ts.map +1 -0
  165. package/dist/vite/store.js +52 -0
  166. package/dist/vite/store.test.d.ts +6 -0
  167. package/dist/vite/store.test.d.ts.map +1 -0
  168. package/dist/vite/store.test.js +172 -0
  169. package/dist/vite/tweakpane-hook.d.ts +94 -0
  170. package/dist/vite/tweakpane-hook.d.ts.map +1 -0
  171. package/dist/vite/tweakpane-hook.js +450 -0
  172. package/dist/vite/vite-plugin.d.ts +28 -0
  173. package/dist/vite/vite-plugin.d.ts.map +1 -0
  174. package/dist/vite/vite-plugin.js +538 -0
  175. package/dist/vite/wave-gradient-shader.d.ts +41 -0
  176. package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
  177. package/dist/vite/wave-gradient-shader.js +207 -0
  178. package/package.json +103 -25
  179. package/skills/egaki/SKILL.md +162 -1
  180. package/src/cli/cache-utils.ts +169 -0
  181. package/src/cli/cached-generate.test.ts +531 -0
  182. package/src/cli/cached-generate.ts +348 -0
  183. package/src/cli/cartesia-provider.ts +249 -0
  184. package/src/cli/cli.ts +1818 -0
  185. package/src/cli/clone-generate.ts +202 -0
  186. package/src/{credentials.ts → cli/credentials.ts} +90 -7
  187. package/src/cli/elevenlabs-speech-provider.ts +243 -0
  188. package/src/cli/generate.test.ts +166 -0
  189. package/src/cli/generate.ts +912 -0
  190. package/src/{login.ts → cli/login.ts} +48 -3
  191. package/src/cli/main.ts +8 -0
  192. package/src/cli/model-catalog.ts +2336 -0
  193. package/src/cli/models.ts +408 -0
  194. package/src/cli/openai-speech-provider.ts +34 -0
  195. package/src/cli/separation-generate.ts +187 -0
  196. package/src/cli/speech-catalog.ts +253 -0
  197. package/src/cli/speech-generate.ts +275 -0
  198. package/src/cli/speech-models.ts +146 -0
  199. package/src/cli/speech-provider.test.ts +226 -0
  200. package/src/cli/transcription-catalog.ts +250 -0
  201. package/src/cli/transcription-generate.ts +214 -0
  202. package/src/cli/transcription-models.ts +136 -0
  203. package/src/cli/transcription-providers.ts +427 -0
  204. package/src/cli/video-model-catalog.ts +14 -0
  205. package/src/cli/xai-auth.ts +396 -0
  206. package/src/vite/angled-screen.tsx +214 -0
  207. package/src/vite/app.tsx +197 -0
  208. package/src/vite/bands-shader.tsx +319 -0
  209. package/src/vite/code-block.tsx +939 -0
  210. package/src/vite/components.tsx +278 -0
  211. package/src/vite/dispersion-rings-shader.tsx +331 -0
  212. package/src/vite/easing-curves.test.ts +232 -0
  213. package/src/vite/easing-curves.ts +743 -0
  214. package/src/vite/generated-media-client.tsx +121 -0
  215. package/src/vite/keyframes.tsx +347 -0
  216. package/src/vite/layout-editor.tsx +709 -0
  217. package/src/vite/layout-transition.tsx +706 -0
  218. package/src/vite/liquid-gradient-shader.tsx +474 -0
  219. package/src/vite/mdx-client.tsx +420 -0
  220. package/src/vite/mdx-parse.ts +343 -0
  221. package/src/vite/mdx-provided-components.ts +19 -0
  222. package/src/vite/mdx-video.test.tsx +2219 -0
  223. package/src/vite/mdx-video.tsx +976 -0
  224. package/src/vite/media-components.tsx +473 -0
  225. package/src/vite/media-duration-store.ts +225 -0
  226. package/src/vite/motion-timing.ts +194 -0
  227. package/src/vite/player-page.tsx +1107 -0
  228. package/src/vite/render-client.ts +84 -0
  229. package/src/vite/sdk.ts +598 -0
  230. package/src/vite/server-components.tsx +241 -0
  231. package/src/vite/server-mdx.ts +285 -0
  232. package/src/vite/shader-renderer.tsx +535 -0
  233. package/src/vite/store-hooks.ts +117 -0
  234. package/src/vite/store.test.ts +202 -0
  235. package/src/vite/store.ts +115 -0
  236. package/src/vite/styles.css +21 -0
  237. package/src/vite/tweakpane-hook.tsx +593 -0
  238. package/src/vite/virtual-modules.d.ts +30 -0
  239. package/src/vite/vite-plugin.ts +584 -0
  240. package/src/vite/wave-gradient-shader.tsx +253 -0
  241. package/README.md +0 -266
  242. package/dist/antigravity-auth.d.ts +0 -15
  243. package/dist/antigravity-auth.d.ts.map +0 -1
  244. package/dist/antigravity-auth.js +0 -544
  245. package/dist/antigravity-image.d.ts +0 -11
  246. package/dist/antigravity-image.d.ts.map +0 -1
  247. package/dist/antigravity-image.js +0 -285
  248. package/dist/chatgpt-auth.d.ts.map +0 -1
  249. package/dist/cli.d.ts +0 -3
  250. package/dist/cli.d.ts.map +0 -1
  251. package/dist/cli.js +0 -968
  252. package/dist/credentials.d.ts.map +0 -1
  253. package/dist/gateway-model-candidates.generated.d.ts +0 -11
  254. package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
  255. package/dist/gateway-model-candidates.generated.js +0 -64
  256. package/dist/login.d.ts.map +0 -1
  257. package/dist/model-catalog.d.ts +0 -42
  258. package/dist/model-catalog.d.ts.map +0 -1
  259. package/dist/model-catalog.js +0 -1001
  260. package/dist/models.d.ts.map +0 -1
  261. package/dist/models.js +0 -246
  262. package/dist/open-browser.d.ts.map +0 -1
  263. package/dist/subscription.d.ts.map +0 -1
  264. package/dist/video-model-catalog.d.ts +0 -52
  265. package/dist/video-model-catalog.d.ts.map +0 -1
  266. package/dist/video-model-catalog.js +0 -306
  267. package/src/cli.ts +0 -1378
  268. package/src/model-catalog.ts +0 -1077
  269. package/src/models.ts +0 -309
  270. package/src/video-model-catalog.ts +0 -363
  271. /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
  272. /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
  273. /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
  274. /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
  275. /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
  276. /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
  277. /package/dist/{subscription.js → cli/subscription.js} +0 -0
  278. /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
  279. /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
  280. /package/src/{subscription.ts → cli/subscription.ts} +0 -0
@@ -0,0 +1,2336 @@
1
+ // Single source of truth for all image and video generation models.
2
+ // Every model's provider, pricing, features, and generation strategy lives here.
3
+ // Other modules derive their data from this catalog — no separate registries.
4
+ //
5
+ // To add a model: add an entry to CATALOG with the right shared fragment spread.
6
+ // To update pricing: change the cost field on the model entry.
7
+ // To add a provider: create a new shared fragment and add models using it.
8
+ //
9
+ // Provider option schemas are sourced from the @ai-sdk/* packages and upstream API docs.
10
+ // Each shared fragment has a URL comment pointing to the source of truth so options
11
+ // are easy to verify and update when providers change their APIs.
12
+ //
13
+ // Sources:
14
+ // xAI image: node_modules/@ai-sdk/xai/dist/index.d.ts → xaiImageModelOptions
15
+ // https://docs.x.ai/docs/api-reference#create-image
16
+ // xAI video: node_modules/@ai-sdk/xai/dist/index.d.ts → XaiVideoModelOptions
17
+ // https://docs.x.ai/docs/api-reference#create-video
18
+ // OpenAI: node_modules/@ai-sdk/openai/dist/index.d.ts → imageGeneration args
19
+ // https://platform.openai.com/docs/api-reference/images
20
+ // Fal image: https://ai-sdk.dev/providers/ai-sdk-providers/fal
21
+ // node_modules/@ai-sdk/fal/dist/index.d.ts → FalImageModelOptions
22
+ // Fal video: node_modules/@ai-sdk/fal/dist/index.d.ts → FalVideoModelOptions
23
+ // https://ai-sdk.dev/providers/ai-sdk-providers/fal
24
+
25
+ // ─── cost types ──────────────────────────────────────────────────────────────
26
+
27
+ export type PerImageCost = {
28
+ type: 'per-image'
29
+ /** USD per image at default quality/resolution */
30
+ perImage: number
31
+ }
32
+
33
+ export type PerTokenCost = {
34
+ type: 'per-token'
35
+ /** USD per million input tokens */
36
+ inputPerM: number
37
+ /** USD per million output tokens */
38
+ outputPerM: number
39
+ }
40
+
41
+ export type VideoDurationPricingTier = {
42
+ /** USD per second for this variant */
43
+ costPerSecond: number
44
+ /** Optional resolution discriminator (e.g. 720p, 1080p, 4k) */
45
+ resolution?: string
46
+ /** Optional mode discriminator (e.g. std, pro) */
47
+ mode?: string
48
+ /** Optional audio discriminator */
49
+ audio?: boolean
50
+ /** Optional discriminator for whether image/video input is present (i2v/r2v vs t2v) */
51
+ hasVideoInput?: boolean
52
+ }
53
+
54
+ export type PerVideoSecondCost = {
55
+ type: 'per-video-second'
56
+ /** Fallback duration when request does not specify one (seconds) */
57
+ defaultDurationSec: number
58
+ tiers: VideoDurationPricingTier[]
59
+ }
60
+
61
+ export type UnknownCost = {
62
+ type: 'unknown'
63
+ }
64
+
65
+ export type ModelCost = PerImageCost | PerTokenCost
66
+ export type VideoModelCost = PerVideoSecondCost | UnknownCost
67
+ export type AnyCost = ModelCost | VideoModelCost
68
+
69
+ // ─── provider option types ───────────────────────────────────────────────────
70
+ // Declares provider-specific options that can be passed via providerOptions.
71
+ // Lives in the catalog so CLI flag descriptions and validation are derived
72
+ // from a single source of truth.
73
+
74
+ export type ProviderOption = {
75
+ /** CLI flag name, e.g. 'quality', 'output-format' */
76
+ flag: string
77
+ /** The key sent to providerOptions.{provider}.{key} */
78
+ providerKey: string
79
+ /** Human description for --help */
80
+ description: string
81
+ /** Enum values if constrained, shown in flag description */
82
+ values?: string[]
83
+ /** Server-side default when not specified */
84
+ defaultValue?: string
85
+ /** Value type */
86
+ type: 'string' | 'number' | 'boolean'
87
+ /** Whether this flag accepts multiple values (array) */
88
+ array?: boolean
89
+ }
90
+
91
+ // ─── feature types ───────────────────────────────────────────────────────────
92
+
93
+ export type ModelFeatures = {
94
+ /** supports input images for editing */
95
+ editing: boolean
96
+ /** supports mask for inpainting */
97
+ inpainting: boolean
98
+ /** supported aspect ratios */
99
+ aspectRatios: string[]
100
+ /** supported WIDTHxHEIGHT sizes (OpenAI models) */
101
+ sizes?: string[]
102
+ /** supports deterministic seed */
103
+ seed: boolean
104
+ /** supports generating n > 1 images */
105
+ multipleImages: boolean
106
+ }
107
+
108
+ export type VideoModelFeatures = {
109
+ /** Supports text prompt to video generation */
110
+ textToVideo: boolean
111
+ /** Supports image-to-video prompt object ({ image, text }) */
112
+ imageToVideo: boolean
113
+ /** Optional capabilities exposed by provider */
114
+ capabilities: Array<'t2v' | 'i2v' | 'r2v' | 'motion-control' | 'editing' | 'extension'>
115
+ /** Optional supported aspect ratios */
116
+ aspectRatios?: string[]
117
+ /** Optional supported resolutions */
118
+ resolutions?: string[]
119
+ /** Optional duration range in seconds */
120
+ durationRangeSec?: { min: number; max: number }
121
+ seed: boolean
122
+ multipleVideos: boolean
123
+ }
124
+
125
+ // ─── entry types (discriminated union by strategy) ───────────────────────────
126
+
127
+ export type ImageModelEntry = {
128
+ id: string
129
+ name: string
130
+ description?: string
131
+ provider: string
132
+ strategy: 'image' | 'text'
133
+ /** Release date in YYYY-MM-DD or YYYY-MM format */
134
+ released: string
135
+ cost: ModelCost
136
+ features: ModelFeatures
137
+ /** Provider-specific options passable via providerOptions.{provider} */
138
+ providerOptions?: ProviderOption[]
139
+ }
140
+
141
+ export type VideoModelEntry = {
142
+ id: string
143
+ name: string
144
+ description?: string
145
+ provider: string
146
+ strategy: 'video'
147
+ released: string
148
+ cost: VideoModelCost
149
+ features: VideoModelFeatures
150
+ /** Provider-specific options passable via providerOptions.{provider} */
151
+ providerOptions?: ProviderOption[]
152
+ }
153
+
154
+ /** @deprecated Use ImageModelEntry instead */
155
+ export type ModelEntry = ImageModelEntry
156
+
157
+ export type { SpeechModelEntry } from './speech-catalog.js'
158
+
159
+ export type AnyModelEntry = ImageModelEntry | VideoModelEntry
160
+
161
+ // ─── shared fragments ────────────────────────────────────────────────────────
162
+ // Spread these into model entries to avoid repeating common fields.
163
+
164
+ const googleImagen = {
165
+ provider: 'google',
166
+ strategy: 'image' as const,
167
+ features: {
168
+ editing: true,
169
+ inpainting: true,
170
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
171
+ seed: true,
172
+ multipleImages: true,
173
+ },
174
+ }
175
+
176
+ const googleText = {
177
+ provider: 'google',
178
+ strategy: 'text' as const,
179
+ features: {
180
+ editing: true,
181
+ inpainting: false,
182
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '2:3', '3:2', '4:5', '5:4'],
183
+ seed: false,
184
+ multipleImages: false,
185
+ },
186
+ }
187
+
188
+ // Source: node_modules/@ai-sdk/openai/dist/index.d.ts → imageGeneration args
189
+ // Docs: https://platform.openai.com/docs/api-reference/images/create
190
+ const openaiImageProviderOptions: ProviderOption[] = [
191
+ { flag: 'quality', providerKey: 'quality', description: 'Image quality', values: ['auto', 'low', 'medium', 'high'], defaultValue: 'auto', type: 'string' },
192
+ { flag: 'output-format', providerKey: 'outputFormat', description: 'Output format', values: ['png', 'jpeg', 'webp'], defaultValue: 'png', type: 'string' },
193
+ ]
194
+
195
+ const openaiImage = {
196
+ provider: 'openai',
197
+ strategy: 'image' as const,
198
+ providerOptions: openaiImageProviderOptions,
199
+ }
200
+
201
+ const replicateImage = {
202
+ provider: 'replicate',
203
+ strategy: 'image' as const,
204
+ }
205
+
206
+ // Source: node_modules/@ai-sdk/fal/dist/index.d.ts → FalImageModelOptions (lazy passthrough)
207
+ // Docs: https://ai-sdk.dev/providers/ai-sdk-providers/fal#provider-options
208
+ const falImageProviderOptions: ProviderOption[] = [
209
+ { flag: 'output-format', providerKey: 'outputFormat', description: 'Output format', values: ['png', 'jpeg'], type: 'string' },
210
+ { flag: 'negative-prompt', providerKey: 'negativePrompt', description: 'What to avoid in the image', type: 'string' },
211
+ ]
212
+
213
+ const falImage = {
214
+ provider: 'fal',
215
+ strategy: 'image' as const,
216
+ providerOptions: falImageProviderOptions,
217
+ }
218
+
219
+ const bflImage = {
220
+ provider: 'bfl',
221
+ strategy: 'image' as const,
222
+ }
223
+
224
+ const recraftImage = {
225
+ provider: 'recraft',
226
+ strategy: 'image' as const,
227
+ }
228
+
229
+ // Source: node_modules/@ai-sdk/xai/dist/index.d.ts → xaiImageModelOptions
230
+ // Docs: https://docs.x.ai/docs/api-reference#create-image
231
+ const xaiImageProviderOptions: ProviderOption[] = [
232
+ { flag: 'quality', providerKey: 'quality', description: 'Image quality', values: ['low', 'medium', 'high'], defaultValue: 'medium', type: 'string' },
233
+ { flag: 'resolution', providerKey: 'resolution', description: 'Output resolution', values: ['1k', '2k'], defaultValue: '1k', type: 'string' },
234
+ { flag: 'output-format', providerKey: 'output_format', description: 'Output format', values: ['png', 'jpeg'], defaultValue: 'png', type: 'string' },
235
+ ]
236
+
237
+ const xaiImage = {
238
+ provider: 'xai',
239
+ strategy: 'image' as const,
240
+ providerOptions: xaiImageProviderOptions,
241
+ }
242
+
243
+ // Source: node_modules/@ai-sdk/xai/dist/index.d.ts → XaiVideoModelOptions
244
+ // Docs: https://docs.x.ai/docs/api-reference#create-video
245
+ const xaiVideoProviderOptions: ProviderOption[] = [
246
+ { flag: 'resolution', providerKey: 'resolution', description: 'Output resolution', values: ['480p', '720p'], defaultValue: '720p', type: 'string' },
247
+ { flag: 'mode', providerKey: 'mode', description: 'Video operation mode', values: ['edit-video', 'extend-video', 'reference-to-video'], type: 'string' },
248
+ // video-url is not a CLI flag; it's set internally from --input in edit/extend modes.
249
+ // Kept here so findProviderOption() can verify the model supports it and resolve the correct providerKey.
250
+ { flag: 'video-url', providerKey: 'videoUrl', description: 'Source video URL for editing or extension (internal)', type: 'string' },
251
+ { flag: 'reference-images', providerKey: 'referenceImageUrls', description: 'Reference images for R2V (1-7 files or URLs)', type: 'string', array: true },
252
+ ]
253
+
254
+ // Source: node_modules/@ai-sdk/bytedance/dist/index.d.ts → ByteDanceVideoProviderOptions
255
+ // Docs: https://sdk.vercel.ai/docs/providers/bytedance
256
+ const bytedanceVideoProviderOptions: ProviderOption[] = [
257
+ { flag: 'resolution', providerKey: 'resolution', description: 'Output resolution', values: ['480p', '720p', '1080p'], type: 'string' },
258
+ { flag: 'reference-images', providerKey: 'referenceImages', description: 'Reference images for R2V (1-9 files or URLs, use @Image1 etc. in prompt)', type: 'string', array: true },
259
+ { flag: 'watermark', providerKey: 'watermark', description: 'Add watermark to video', type: 'boolean' },
260
+ { flag: 'generate-audio', providerKey: 'generateAudio', description: 'Generate synchronized audio', type: 'boolean' },
261
+ ]
262
+
263
+ // Source: node_modules/@ai-sdk/fal/dist/index.d.ts → FalVideoModelOptions
264
+ // Docs: https://ai-sdk.dev/providers/ai-sdk-providers/fal
265
+ const falVideoProviderOptions: ProviderOption[] = [
266
+ { flag: 'negative-prompt', providerKey: 'negativePrompt', description: 'What to avoid in the video', type: 'string' },
267
+ ]
268
+
269
+ const vertexImagen = {
270
+ provider: 'vertex',
271
+ strategy: 'image' as const,
272
+ features: {
273
+ ...googleImagen.features,
274
+ },
275
+ }
276
+
277
+ const vertexText = {
278
+ provider: 'vertex',
279
+ strategy: 'text' as const,
280
+ features: {
281
+ ...googleText.features,
282
+ },
283
+ }
284
+
285
+ const fluxAspectRatios = ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9']
286
+
287
+ // ─── catalog ─────────────────────────────────────────────────────────────────
288
+
289
+ export const CATALOG: ModelEntry[] = [
290
+ // ── Google: Imagen ─────────────────────────────────────────────────────
291
+ {
292
+ id: 'imagen-4.0-generate-001',
293
+ name: 'Imagen 4',
294
+ released: '2025-08-15',
295
+ ...googleImagen,
296
+ cost: { type: 'per-image', perImage: 0.04 },
297
+ },
298
+ {
299
+ id: 'imagen-4.0-ultra-generate-001',
300
+ name: 'Imagen 4 Ultra',
301
+ released: '2025-08-15',
302
+ ...googleImagen,
303
+ cost: { type: 'per-image', perImage: 0.06 },
304
+ },
305
+ {
306
+ id: 'imagen-4.0-fast-generate-001',
307
+ name: 'Imagen 4 Fast',
308
+ released: '2025-08-15',
309
+ ...googleImagen,
310
+ cost: { type: 'per-image', perImage: 0.02 },
311
+ },
312
+
313
+ // ── Google: Gemini text+image ──────────────────────────────────────────
314
+ {
315
+ id: 'gemini-2.0-flash-exp-image-generation',
316
+ name: 'Gemini 2.0 Flash (Image)',
317
+ released: '2025-03',
318
+ ...googleText,
319
+ cost: { type: 'per-token', inputPerM: 0.1, outputPerM: 0.4 },
320
+ },
321
+ {
322
+ id: 'gemini-2.5-flash-image',
323
+ name: 'Gemini 2.5 Flash Image',
324
+ released: '2025-08-26',
325
+ ...googleText,
326
+ cost: { type: 'per-token', inputPerM: 0.3, outputPerM: 30 },
327
+ },
328
+ {
329
+ id: 'gemini-3-pro-image-preview',
330
+ name: 'Gemini 3 Pro Image',
331
+ released: '2025-11-20',
332
+ ...googleText,
333
+ cost: { type: 'per-token', inputPerM: 1.25, outputPerM: 10 },
334
+ },
335
+ {
336
+ id: 'nano-banana-pro-preview',
337
+ name: 'Nano Banana Pro',
338
+ description:
339
+ 'Nano Banana Pro — the high-fidelity variant in the Nano Banana line, built on the ' +
340
+ 'Gemini Pro backbone. Best for complex scenes requiring maximum quality at the expense ' +
341
+ 'of higher cost and slower speed. Still the best fit for specialized high-fidelity tasks ' +
342
+ 'where Nano Banana 2 trades off some quality for much faster, cheaper generation.',
343
+ released: '2025-11-20',
344
+ ...googleText,
345
+ cost: { type: 'per-token', inputPerM: 0.3, outputPerM: 30 },
346
+ },
347
+ {
348
+ id: 'gemini-3.1-flash-image-preview',
349
+ name: 'Gemini 3.1 Flash Image (Nano Banana 2)',
350
+ description:
351
+ 'Nano Banana 2 — high-efficiency successor in the Nano Banana line. Targets Pro-like ' +
352
+ 'quality with faster iteration and lower cost. Built on Gemini 3.1 Flash backbone. ' +
353
+ 'Key upgrades: consistent rendering of up to 5 characters per workflow, new native ' +
354
+ 'aspect ratios (4:1, 1:4, 8:1, 1:8), resolutions from 512px to 4K, improved text ' +
355
+ 'rendering and in-image localization. Nano Banana Pro remains the best fit for ' +
356
+ 'specialized high-fidelity tasks.',
357
+ released: '2026-02-26',
358
+ ...googleText,
359
+ features: {
360
+ ...googleText.features,
361
+ aspectRatios: [
362
+ ...googleText.features.aspectRatios,
363
+ '4:1',
364
+ '1:4',
365
+ '8:1',
366
+ '1:8',
367
+ ],
368
+ },
369
+ cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
370
+ },
371
+
372
+ // ── Vertex: Imagen ──────────────────────────────────────────────────────
373
+ // Same models as Google AI Studio but routed through Vertex AI / Google Cloud billing.
374
+ // Use `egaki login --provider vertex --key <key>` to configure.
375
+ {
376
+ id: 'vertex/imagen-4.0-generate-001',
377
+ name: 'Imagen 4 (Vertex)',
378
+ released: '2025-08-15',
379
+ ...vertexImagen,
380
+ cost: { type: 'per-image', perImage: 0.04 },
381
+ },
382
+ {
383
+ id: 'vertex/imagen-4.0-ultra-generate-001',
384
+ name: 'Imagen 4 Ultra (Vertex)',
385
+ released: '2025-08-15',
386
+ ...vertexImagen,
387
+ cost: { type: 'per-image', perImage: 0.06 },
388
+ },
389
+ {
390
+ id: 'vertex/imagen-4.0-fast-generate-001',
391
+ name: 'Imagen 4 Fast (Vertex)',
392
+ released: '2025-08-15',
393
+ ...vertexImagen,
394
+ cost: { type: 'per-image', perImage: 0.02 },
395
+ },
396
+
397
+ // ── Vertex: Gemini text+image ─────────────────────────────────────────
398
+ {
399
+ id: 'vertex/gemini-2.5-flash-image',
400
+ name: 'Gemini 2.5 Flash Image (Vertex)',
401
+ released: '2025-08-26',
402
+ ...vertexText,
403
+ cost: { type: 'per-token', inputPerM: 0.3, outputPerM: 30 },
404
+ },
405
+ {
406
+ id: 'vertex/gemini-3-pro-image-preview',
407
+ name: 'Gemini 3 Pro Image (Vertex)',
408
+ released: '2025-11-20',
409
+ ...vertexText,
410
+ cost: { type: 'per-token', inputPerM: 1.25, outputPerM: 10 },
411
+ },
412
+ {
413
+ id: 'vertex/gemini-3.1-flash-image-preview',
414
+ name: 'Gemini 3.1 Flash Image (Vertex)',
415
+ released: '2026-02-26',
416
+ ...vertexText,
417
+ features: {
418
+ ...vertexText.features,
419
+ aspectRatios: [
420
+ ...vertexText.features.aspectRatios,
421
+ '4:1',
422
+ '1:4',
423
+ '8:1',
424
+ '1:8',
425
+ ],
426
+ },
427
+ cost: { type: 'per-token', inputPerM: 0.5, outputPerM: 3.0 },
428
+ },
429
+
430
+ // ── BFL (AI Gateway) ───────────────────────────────────────────────────
431
+ {
432
+ id: 'flux-kontext-max',
433
+ name: 'FLUX Kontext Max',
434
+ released: '2025-06-12',
435
+ ...bflImage,
436
+ cost: { type: 'per-image', perImage: 0.08 },
437
+ features: {
438
+ editing: true,
439
+ inpainting: false,
440
+ aspectRatios: fluxAspectRatios,
441
+ seed: true,
442
+ multipleImages: false,
443
+ },
444
+ },
445
+ {
446
+ id: 'flux-kontext-pro',
447
+ name: 'FLUX Kontext Pro',
448
+ released: '2025-06-12',
449
+ ...bflImage,
450
+ cost: { type: 'per-image', perImage: 0.04 },
451
+ features: {
452
+ editing: true,
453
+ inpainting: false,
454
+ aspectRatios: fluxAspectRatios,
455
+ seed: true,
456
+ multipleImages: false,
457
+ },
458
+ },
459
+ {
460
+ id: 'flux-pro-1.0-fill',
461
+ name: 'FLUX Pro 1.0 Fill',
462
+ released: '2024-10-15',
463
+ ...bflImage,
464
+ cost: { type: 'per-image', perImage: 0.05 },
465
+ features: {
466
+ editing: true,
467
+ inpainting: true,
468
+ aspectRatios: fluxAspectRatios,
469
+ seed: true,
470
+ multipleImages: false,
471
+ },
472
+ },
473
+ {
474
+ id: 'flux-pro-1.1',
475
+ name: 'FLUX Pro 1.1',
476
+ released: '2024-10-01',
477
+ ...bflImage,
478
+ cost: { type: 'per-image', perImage: 0.04 },
479
+ features: {
480
+ editing: false,
481
+ inpainting: false,
482
+ aspectRatios: fluxAspectRatios,
483
+ seed: true,
484
+ multipleImages: false,
485
+ },
486
+ },
487
+ {
488
+ id: 'flux-pro-1.1-ultra',
489
+ name: 'FLUX Pro 1.1 Ultra',
490
+ released: '2024-11-06',
491
+ ...bflImage,
492
+ cost: { type: 'per-image', perImage: 0.06 },
493
+ features: {
494
+ editing: false,
495
+ inpainting: false,
496
+ aspectRatios: fluxAspectRatios,
497
+ seed: true,
498
+ multipleImages: false,
499
+ },
500
+ },
501
+
502
+ {
503
+ id: 'flux-2-pro',
504
+ name: 'FLUX.2 Pro',
505
+ released: '2025-12',
506
+ ...bflImage,
507
+ cost: { type: 'per-image', perImage: 0.03 },
508
+ features: {
509
+ editing: true,
510
+ inpainting: false,
511
+ aspectRatios: fluxAspectRatios,
512
+ seed: true,
513
+ multipleImages: false,
514
+ },
515
+ },
516
+ {
517
+ id: 'flux-2-max',
518
+ name: 'FLUX.2 Max',
519
+ released: '2025-12',
520
+ ...bflImage,
521
+ cost: { type: 'per-image', perImage: 0.07 },
522
+ features: {
523
+ editing: true,
524
+ inpainting: false,
525
+ aspectRatios: fluxAspectRatios,
526
+ seed: true,
527
+ multipleImages: false,
528
+ },
529
+ },
530
+ {
531
+ id: 'flux-2-flex',
532
+ name: 'FLUX.2 Flex',
533
+ released: '2025-12',
534
+ ...bflImage,
535
+ cost: { type: 'per-image', perImage: 0.05 },
536
+ features: {
537
+ editing: true,
538
+ inpainting: false,
539
+ aspectRatios: fluxAspectRatios,
540
+ seed: true,
541
+ multipleImages: false,
542
+ },
543
+ },
544
+ {
545
+ id: 'flux-2-klein-9b',
546
+ name: 'FLUX.2 Klein 9B',
547
+ released: '2025-12',
548
+ ...bflImage,
549
+ cost: { type: 'per-image', perImage: 0.015 },
550
+ features: {
551
+ editing: true,
552
+ inpainting: false,
553
+ aspectRatios: fluxAspectRatios,
554
+ seed: true,
555
+ multipleImages: false,
556
+ },
557
+ },
558
+ {
559
+ id: 'flux-2-klein-4b',
560
+ name: 'FLUX.2 Klein 4B',
561
+ released: '2025-12',
562
+ ...bflImage,
563
+ cost: { type: 'per-image', perImage: 0.014 },
564
+ features: {
565
+ editing: true,
566
+ inpainting: false,
567
+ aspectRatios: fluxAspectRatios,
568
+ seed: true,
569
+ multipleImages: false,
570
+ },
571
+ },
572
+
573
+ // ── Recraft (AI Gateway) ───────────────────────────────────────────────
574
+ {
575
+ id: 'recraft-v2',
576
+ name: 'Recraft v2',
577
+ released: '2024-08-19',
578
+ ...recraftImage,
579
+ cost: { type: 'per-image', perImage: 0.04 },
580
+ features: {
581
+ editing: false,
582
+ inpainting: false,
583
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
584
+ seed: false,
585
+ multipleImages: false,
586
+ },
587
+ },
588
+ {
589
+ id: 'recraft-v3',
590
+ name: 'Recraft v3 (AI Gateway)',
591
+ released: '2024-10-29',
592
+ ...recraftImage,
593
+ cost: { type: 'per-image', perImage: 0.04 },
594
+ features: {
595
+ editing: false,
596
+ inpainting: false,
597
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
598
+ seed: false,
599
+ multipleImages: false,
600
+ },
601
+ },
602
+ {
603
+ id: 'recraft-v4',
604
+ name: 'Recraft v4',
605
+ released: '2025-10-08',
606
+ ...recraftImage,
607
+ cost: { type: 'per-image', perImage: 0.04 },
608
+ features: {
609
+ editing: false,
610
+ inpainting: false,
611
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
612
+ seed: false,
613
+ multipleImages: false,
614
+ },
615
+ },
616
+ {
617
+ id: 'recraft-v4-pro',
618
+ name: 'Recraft v4 Pro',
619
+ released: '2025-10-08',
620
+ ...recraftImage,
621
+ cost: { type: 'per-image', perImage: 0.25 },
622
+ features: {
623
+ editing: false,
624
+ inpainting: false,
625
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
626
+ seed: false,
627
+ multipleImages: false,
628
+ },
629
+ },
630
+
631
+ {
632
+ id: 'recraft-v4.1',
633
+ name: 'Recraft v4.1',
634
+ released: '2026-05',
635
+ ...recraftImage,
636
+ cost: { type: 'per-image', perImage: 0.04 },
637
+ features: {
638
+ editing: false,
639
+ inpainting: false,
640
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
641
+ seed: false,
642
+ multipleImages: false,
643
+ },
644
+ },
645
+ {
646
+ id: 'recraft-v4.1-pro',
647
+ name: 'Recraft v4.1 Pro',
648
+ released: '2026-05',
649
+ ...recraftImage,
650
+ cost: { type: 'per-image', perImage: 0.25 },
651
+ features: {
652
+ editing: false,
653
+ inpainting: false,
654
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
655
+ seed: false,
656
+ multipleImages: false,
657
+ },
658
+ },
659
+ {
660
+ id: 'recraft-v4.1-utility',
661
+ name: 'Recraft v4.1 Utility',
662
+ released: '2026-05',
663
+ ...recraftImage,
664
+ cost: { type: 'per-image', perImage: 0.04 },
665
+ features: {
666
+ editing: false,
667
+ inpainting: false,
668
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
669
+ seed: false,
670
+ multipleImages: false,
671
+ },
672
+ },
673
+ {
674
+ id: 'recraft-v4.1-utility-pro',
675
+ name: 'Recraft v4.1 Utility Pro',
676
+ released: '2026-05',
677
+ ...recraftImage,
678
+ cost: { type: 'per-image', perImage: 0.25 },
679
+ features: {
680
+ editing: false,
681
+ inpainting: false,
682
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
683
+ seed: false,
684
+ multipleImages: false,
685
+ },
686
+ },
687
+
688
+ // ── ByteDance Seedream (AI Gateway) ────────────────────────────────────
689
+ {
690
+ id: 'seedream-5.0-lite',
691
+ name: 'Seedream 5.0 Lite',
692
+ released: '2026-01',
693
+ provider: 'bytedance',
694
+ strategy: 'image' as const,
695
+ cost: { type: 'per-image' as const, perImage: 0.035 },
696
+ features: {
697
+ editing: false,
698
+ inpainting: false,
699
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
700
+ seed: false,
701
+ multipleImages: false,
702
+ },
703
+ },
704
+ {
705
+ id: 'seedream-4.5',
706
+ name: 'Seedream 4.5',
707
+ released: '2025-11',
708
+ provider: 'bytedance',
709
+ strategy: 'image' as const,
710
+ cost: { type: 'per-image' as const, perImage: 0.04 },
711
+ features: {
712
+ editing: true,
713
+ inpainting: false,
714
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
715
+ seed: false,
716
+ multipleImages: false,
717
+ },
718
+ },
719
+ {
720
+ id: 'seedream-4.0',
721
+ name: 'Seedream 4.0',
722
+ released: '2025-08',
723
+ provider: 'bytedance',
724
+ strategy: 'image' as const,
725
+ cost: { type: 'per-image' as const, perImage: 0.03 },
726
+ features: {
727
+ editing: true,
728
+ inpainting: false,
729
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
730
+ seed: false,
731
+ multipleImages: false,
732
+ },
733
+ },
734
+
735
+ // ── xAI (AI Gateway) ────────────────────────────────────────────────────
736
+ {
737
+ id: 'grok-imagine-image',
738
+ name: 'Grok Imagine Image',
739
+ released: '2026-03',
740
+ ...xaiImage,
741
+ cost: { type: 'per-image', perImage: 0.02 },
742
+ features: {
743
+ editing: true,
744
+ inpainting: false,
745
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
746
+ seed: false,
747
+ multipleImages: true,
748
+ },
749
+ },
750
+ {
751
+ id: 'grok-imagine-image-quality',
752
+ name: 'Grok Imagine Image Quality',
753
+ released: '2026-04',
754
+ ...xaiImage,
755
+ cost: { type: 'per-image', perImage: 0.05 },
756
+ features: {
757
+ editing: true,
758
+ inpainting: false,
759
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
760
+ seed: false,
761
+ multipleImages: true,
762
+ },
763
+ },
764
+
765
+ // ── OpenAI ─────────────────────────────────────────────────────────────
766
+ {
767
+ id: 'dall-e-2',
768
+ name: 'DALL-E 2',
769
+ released: '2022-11-03',
770
+ ...openaiImage,
771
+ cost: { type: 'per-image', perImage: 0.02 },
772
+ features: {
773
+ editing: true,
774
+ inpainting: true,
775
+ aspectRatios: [],
776
+ sizes: ['256x256', '512x512', '1024x1024'],
777
+ seed: false,
778
+ multipleImages: true,
779
+ },
780
+ },
781
+ {
782
+ id: 'dall-e-3',
783
+ name: 'DALL-E 3',
784
+ released: '2023-10-03',
785
+ ...openaiImage,
786
+ cost: { type: 'per-image', perImage: 0.04 },
787
+ features: {
788
+ editing: false,
789
+ inpainting: false,
790
+ aspectRatios: [],
791
+ sizes: ['1024x1024', '1792x1024', '1024x1792'],
792
+ seed: false,
793
+ multipleImages: false,
794
+ },
795
+ },
796
+ {
797
+ id: 'gpt-image-1',
798
+ name: 'GPT Image 1',
799
+ released: '2025-04-23',
800
+ ...openaiImage,
801
+ cost: { type: 'per-image', perImage: 0.04 },
802
+ features: {
803
+ editing: true,
804
+ inpainting: true,
805
+ aspectRatios: [],
806
+ sizes: ['1024x1024', '1536x1024', '1024x1536'],
807
+ seed: false,
808
+ multipleImages: true,
809
+ },
810
+ },
811
+ {
812
+ id: 'gpt-image-1-mini',
813
+ name: 'GPT Image 1 Mini',
814
+ released: '2025-10-06',
815
+ ...openaiImage,
816
+ cost: { type: 'per-image', perImage: 0.009 },
817
+ features: {
818
+ editing: true,
819
+ inpainting: true,
820
+ aspectRatios: [],
821
+ sizes: ['1024x1024', '1536x1024', '1024x1536'],
822
+ seed: false,
823
+ multipleImages: true,
824
+ },
825
+ },
826
+ {
827
+ id: 'gpt-image-1.5',
828
+ name: 'GPT Image 1.5',
829
+ released: '2025-12-16',
830
+ ...openaiImage,
831
+ cost: { type: 'per-image', perImage: 0.034 },
832
+ features: {
833
+ editing: true,
834
+ inpainting: true,
835
+ aspectRatios: [],
836
+ sizes: ['1024x1024', '1536x1024', '1024x1536'],
837
+ seed: false,
838
+ multipleImages: true,
839
+ },
840
+ },
841
+ {
842
+ id: 'gpt-image-2',
843
+ name: 'GPT Image 2',
844
+ description:
845
+ 'State-of-the-art image generation model with token-based pricing. ' +
846
+ 'Cost varies by quality and size; $0.053 is the medium-quality 1024×1024 estimate.',
847
+ released: '2026-04-21',
848
+ ...openaiImage,
849
+ // Token-based pricing: $30/1M output image tokens. Medium quality 1024×1024 ≈ $0.053.
850
+ cost: { type: 'per-image', perImage: 0.053 },
851
+ features: {
852
+ editing: true,
853
+ inpainting: true,
854
+ aspectRatios: [],
855
+ sizes: ['1024x1024', '1536x1024', '1024x1536'],
856
+ seed: false,
857
+ multipleImages: true,
858
+ },
859
+ },
860
+ {
861
+ id: 'chatgpt-image-latest',
862
+ name: 'ChatGPT Image',
863
+ description:
864
+ 'Rolling-latest alias that tracks the newest ChatGPT image model. Currently points ' +
865
+ 'to gpt-image-2. Pricing may shift when the alias retargets to a newer model.',
866
+ released: '2026-01',
867
+ ...openaiImage,
868
+ // Matches gpt-image-2 medium quality 1024×1024 estimate.
869
+ cost: { type: 'per-image', perImage: 0.053 },
870
+ features: {
871
+ editing: true,
872
+ inpainting: true,
873
+ aspectRatios: [],
874
+ sizes: ['1024x1024', '1536x1024', '1024x1536'],
875
+ seed: false,
876
+ multipleImages: true,
877
+ },
878
+ },
879
+
880
+ // ── Replicate ──────────────────────────────────────────────────────────
881
+ {
882
+ id: 'black-forest-labs/flux-1.1-pro',
883
+ name: 'Flux 1.1 Pro',
884
+ released: '2024-10-01',
885
+ ...replicateImage,
886
+ cost: { type: 'per-image', perImage: 0.04 },
887
+ features: {
888
+ editing: false,
889
+ inpainting: false,
890
+ aspectRatios: fluxAspectRatios,
891
+ seed: true,
892
+ multipleImages: false,
893
+ },
894
+ },
895
+ {
896
+ id: 'black-forest-labs/flux-1.1-pro-ultra',
897
+ name: 'Flux 1.1 Pro Ultra',
898
+ released: '2024-11-06',
899
+ ...replicateImage,
900
+ cost: { type: 'per-image', perImage: 0.06 },
901
+ features: {
902
+ editing: false,
903
+ inpainting: false,
904
+ aspectRatios: fluxAspectRatios,
905
+ seed: true,
906
+ multipleImages: false,
907
+ },
908
+ },
909
+ {
910
+ id: 'black-forest-labs/flux-2-pro',
911
+ name: 'Flux 2 Pro',
912
+ released: '2025-11-25',
913
+ ...replicateImage,
914
+ cost: { type: 'per-image', perImage: 0.015 },
915
+ features: {
916
+ editing: false,
917
+ inpainting: false,
918
+ aspectRatios: fluxAspectRatios,
919
+ seed: true,
920
+ multipleImages: false,
921
+ },
922
+ },
923
+ {
924
+ id: 'black-forest-labs/flux-2-dev',
925
+ name: 'Flux 2 Dev',
926
+ released: '2025-11-25',
927
+ ...replicateImage,
928
+ cost: { type: 'per-image', perImage: 0.012 },
929
+ features: {
930
+ editing: false,
931
+ inpainting: false,
932
+ aspectRatios: fluxAspectRatios,
933
+ seed: true,
934
+ multipleImages: false,
935
+ },
936
+ },
937
+ {
938
+ id: 'black-forest-labs/flux-dev',
939
+ name: 'Flux Dev',
940
+ released: '2024-08-01',
941
+ ...replicateImage,
942
+ cost: { type: 'per-image', perImage: 0.025 },
943
+ features: {
944
+ editing: false,
945
+ inpainting: false,
946
+ aspectRatios: fluxAspectRatios,
947
+ seed: true,
948
+ multipleImages: false,
949
+ },
950
+ },
951
+ {
952
+ id: 'black-forest-labs/flux-pro',
953
+ name: 'Flux Pro',
954
+ released: '2024-08-01',
955
+ ...replicateImage,
956
+ cost: { type: 'per-image', perImage: 0.055 },
957
+ features: {
958
+ editing: false,
959
+ inpainting: false,
960
+ aspectRatios: fluxAspectRatios,
961
+ seed: true,
962
+ multipleImages: false,
963
+ },
964
+ },
965
+ {
966
+ id: 'black-forest-labs/flux-schnell',
967
+ name: 'Flux Schnell',
968
+ released: '2024-08-01',
969
+ ...replicateImage,
970
+ cost: { type: 'per-image', perImage: 0.003 },
971
+ features: {
972
+ editing: false,
973
+ inpainting: false,
974
+ aspectRatios: fluxAspectRatios,
975
+ seed: true,
976
+ multipleImages: false,
977
+ },
978
+ },
979
+ {
980
+ id: 'black-forest-labs/flux-fill-pro',
981
+ name: 'Flux Fill Pro',
982
+ released: '2024-10-15',
983
+ ...replicateImage,
984
+ cost: { type: 'per-image', perImage: 0.05 },
985
+ features: {
986
+ editing: true,
987
+ inpainting: true,
988
+ aspectRatios: fluxAspectRatios,
989
+ seed: true,
990
+ multipleImages: false,
991
+ },
992
+ },
993
+ {
994
+ id: 'black-forest-labs/flux-fill-dev',
995
+ name: 'Flux Fill Dev',
996
+ released: '2024-10-15',
997
+ ...replicateImage,
998
+ cost: { type: 'per-image', perImage: 0.04 },
999
+ features: {
1000
+ editing: true,
1001
+ inpainting: true,
1002
+ aspectRatios: fluxAspectRatios,
1003
+ seed: true,
1004
+ multipleImages: false,
1005
+ },
1006
+ },
1007
+ {
1008
+ id: 'ideogram-ai/ideogram-v2',
1009
+ name: 'Ideogram v2',
1010
+ released: '2024-08-19',
1011
+ ...replicateImage,
1012
+ cost: { type: 'per-image', perImage: 0.08 },
1013
+ features: {
1014
+ editing: false,
1015
+ inpainting: false,
1016
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1017
+ seed: true,
1018
+ multipleImages: false,
1019
+ },
1020
+ },
1021
+ {
1022
+ id: 'ideogram-ai/ideogram-v2-turbo',
1023
+ name: 'Ideogram v2 Turbo',
1024
+ released: '2024-08-19',
1025
+ ...replicateImage,
1026
+ cost: { type: 'per-image', perImage: 0.05 },
1027
+ features: {
1028
+ editing: false,
1029
+ inpainting: false,
1030
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1031
+ seed: true,
1032
+ multipleImages: false,
1033
+ },
1034
+ },
1035
+ {
1036
+ id: 'recraft-ai/recraft-v3',
1037
+ name: 'Recraft v3',
1038
+ released: '2024-10-29',
1039
+ ...replicateImage,
1040
+ cost: { type: 'per-image', perImage: 0.04 },
1041
+ features: {
1042
+ editing: false,
1043
+ inpainting: false,
1044
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1045
+ seed: true,
1046
+ multipleImages: false,
1047
+ },
1048
+ },
1049
+ {
1050
+ id: 'recraft-ai/recraft-v3-svg',
1051
+ name: 'Recraft v3 SVG',
1052
+ released: '2024-10-29',
1053
+ ...replicateImage,
1054
+ cost: { type: 'per-image', perImage: 0.08 },
1055
+ features: {
1056
+ editing: false,
1057
+ inpainting: false,
1058
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1059
+ seed: true,
1060
+ multipleImages: false,
1061
+ },
1062
+ },
1063
+ {
1064
+ id: 'stability-ai/stable-diffusion-3.5-large',
1065
+ name: 'SD 3.5 Large',
1066
+ released: '2024-10-22',
1067
+ ...replicateImage,
1068
+ cost: { type: 'per-image', perImage: 0.065 },
1069
+ features: {
1070
+ editing: false,
1071
+ inpainting: false,
1072
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'],
1073
+ seed: true,
1074
+ multipleImages: false,
1075
+ },
1076
+ },
1077
+ {
1078
+ id: 'stability-ai/stable-diffusion-3.5-large-turbo',
1079
+ name: 'SD 3.5 Large Turbo',
1080
+ released: '2024-10-22',
1081
+ ...replicateImage,
1082
+ cost: { type: 'per-image', perImage: 0.04 },
1083
+ features: {
1084
+ editing: false,
1085
+ inpainting: false,
1086
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'],
1087
+ seed: true,
1088
+ multipleImages: false,
1089
+ },
1090
+ },
1091
+ {
1092
+ id: 'stability-ai/stable-diffusion-3.5-medium',
1093
+ name: 'SD 3.5 Medium',
1094
+ released: '2024-10-29',
1095
+ ...replicateImage,
1096
+ cost: { type: 'per-image', perImage: 0.035 },
1097
+ features: {
1098
+ editing: false,
1099
+ inpainting: false,
1100
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'],
1101
+ seed: true,
1102
+ multipleImages: false,
1103
+ },
1104
+ },
1105
+ {
1106
+ id: 'luma/photon',
1107
+ name: 'Luma Photon',
1108
+ released: '2024-12-10',
1109
+ ...replicateImage,
1110
+ cost: { type: 'per-image', perImage: 0.03 },
1111
+ features: {
1112
+ editing: false,
1113
+ inpainting: false,
1114
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'],
1115
+ seed: true,
1116
+ multipleImages: false,
1117
+ },
1118
+ },
1119
+ {
1120
+ id: 'luma/photon-flash',
1121
+ name: 'Luma Photon Flash',
1122
+ released: '2024-12-10',
1123
+ ...replicateImage,
1124
+ cost: { type: 'per-image', perImage: 0.01 },
1125
+ features: {
1126
+ editing: false,
1127
+ inpainting: false,
1128
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9', '9:21', '21:9'],
1129
+ seed: true,
1130
+ multipleImages: false,
1131
+ },
1132
+ },
1133
+ {
1134
+ id: 'nvidia/sana',
1135
+ name: 'NVIDIA Sana',
1136
+ released: '2024-11-27',
1137
+ ...replicateImage,
1138
+ cost: { type: 'per-image', perImage: 0.01 },
1139
+ features: {
1140
+ editing: false,
1141
+ inpainting: false,
1142
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1143
+ seed: true,
1144
+ multipleImages: false,
1145
+ },
1146
+ },
1147
+
1148
+ // ── Fal ────────────────────────────────────────────────────────────────
1149
+ {
1150
+ id: 'fal-ai/flux/schnell',
1151
+ name: 'Flux Schnell',
1152
+ released: '2024-08-01',
1153
+ ...falImage,
1154
+ cost: { type: 'per-image', perImage: 0.003 },
1155
+ features: {
1156
+ editing: false,
1157
+ inpainting: false,
1158
+ aspectRatios: fluxAspectRatios,
1159
+ seed: true,
1160
+ multipleImages: true,
1161
+ },
1162
+ },
1163
+ {
1164
+ id: 'fal-ai/flux/dev',
1165
+ name: 'Flux Dev',
1166
+ released: '2024-08-01',
1167
+ ...falImage,
1168
+ cost: { type: 'per-image', perImage: 0.025 },
1169
+ features: {
1170
+ editing: false,
1171
+ inpainting: false,
1172
+ aspectRatios: fluxAspectRatios,
1173
+ seed: true,
1174
+ multipleImages: true,
1175
+ },
1176
+ },
1177
+ {
1178
+ id: 'fal-ai/flux-general',
1179
+ name: 'Flux General',
1180
+ released: '2025-01',
1181
+ ...falImage,
1182
+ cost: { type: 'per-image', perImage: 0.075 },
1183
+ features: {
1184
+ editing: true,
1185
+ inpainting: false,
1186
+ aspectRatios: fluxAspectRatios,
1187
+ seed: true,
1188
+ multipleImages: true,
1189
+ },
1190
+ },
1191
+ {
1192
+ id: 'fal-ai/flux-general/inpainting',
1193
+ name: 'Flux General Inpainting',
1194
+ released: '2025-01',
1195
+ ...falImage,
1196
+ cost: { type: 'per-image', perImage: 0.075 },
1197
+ features: {
1198
+ editing: true,
1199
+ inpainting: true,
1200
+ aspectRatios: fluxAspectRatios,
1201
+ seed: true,
1202
+ multipleImages: false,
1203
+ },
1204
+ },
1205
+ {
1206
+ id: 'fal-ai/flux-general/image-to-image',
1207
+ name: 'Flux General Image-to-Image',
1208
+ released: '2025-01',
1209
+ ...falImage,
1210
+ cost: { type: 'per-image', perImage: 0.075 },
1211
+ features: {
1212
+ editing: true,
1213
+ inpainting: false,
1214
+ aspectRatios: fluxAspectRatios,
1215
+ seed: true,
1216
+ multipleImages: false,
1217
+ },
1218
+ },
1219
+ {
1220
+ id: 'fal-ai/flux-pro/v1.1',
1221
+ name: 'Flux Pro 1.1',
1222
+ released: '2024-10-01',
1223
+ ...falImage,
1224
+ cost: { type: 'per-image', perImage: 0.04 },
1225
+ features: {
1226
+ editing: false,
1227
+ inpainting: false,
1228
+ aspectRatios: fluxAspectRatios,
1229
+ seed: true,
1230
+ multipleImages: false,
1231
+ },
1232
+ },
1233
+ {
1234
+ id: 'fal-ai/flux-pro/v1.1-ultra',
1235
+ name: 'Flux Pro 1.1 Ultra',
1236
+ released: '2024-11-06',
1237
+ ...falImage,
1238
+ cost: { type: 'per-image', perImage: 0.06 },
1239
+ features: {
1240
+ editing: false,
1241
+ inpainting: false,
1242
+ aspectRatios: fluxAspectRatios,
1243
+ seed: true,
1244
+ multipleImages: false,
1245
+ },
1246
+ },
1247
+ {
1248
+ id: 'fal-ai/flux-pro/kontext',
1249
+ name: 'Flux Kontext',
1250
+ released: '2025-06-12',
1251
+ ...falImage,
1252
+ cost: { type: 'per-image', perImage: 0.04 },
1253
+ features: {
1254
+ editing: true,
1255
+ inpainting: false,
1256
+ aspectRatios: fluxAspectRatios,
1257
+ seed: true,
1258
+ multipleImages: false,
1259
+ },
1260
+ },
1261
+ {
1262
+ id: 'fal-ai/flux-pro/kontext/max',
1263
+ name: 'Flux Kontext Max',
1264
+ released: '2025-06-12',
1265
+ ...falImage,
1266
+ cost: { type: 'per-image', perImage: 0.08 },
1267
+ features: {
1268
+ editing: true,
1269
+ inpainting: false,
1270
+ aspectRatios: fluxAspectRatios,
1271
+ seed: true,
1272
+ multipleImages: false,
1273
+ },
1274
+ },
1275
+ {
1276
+ id: 'fal-ai/flux-lora',
1277
+ name: 'Flux LoRA',
1278
+ released: '2024-09',
1279
+ ...falImage,
1280
+ cost: { type: 'per-image', perImage: 0.035 },
1281
+ features: {
1282
+ editing: false,
1283
+ inpainting: false,
1284
+ aspectRatios: fluxAspectRatios,
1285
+ seed: true,
1286
+ multipleImages: true,
1287
+ },
1288
+ },
1289
+ {
1290
+ id: 'fal-ai/recraft/v3/text-to-image',
1291
+ name: 'Recraft v3',
1292
+ released: '2024-10-29',
1293
+ ...falImage,
1294
+ cost: { type: 'per-image', perImage: 0.04 },
1295
+ features: {
1296
+ editing: false,
1297
+ inpainting: false,
1298
+ aspectRatios: fluxAspectRatios,
1299
+ seed: true,
1300
+ multipleImages: false,
1301
+ },
1302
+ },
1303
+ {
1304
+ id: 'fal-ai/recraft/v3/image-to-image',
1305
+ name: 'Recraft v3 Image-to-Image',
1306
+ released: '2024-10-29',
1307
+ ...falImage,
1308
+ cost: { type: 'per-image', perImage: 0.04 },
1309
+ features: {
1310
+ editing: true,
1311
+ inpainting: false,
1312
+ aspectRatios: fluxAspectRatios,
1313
+ seed: true,
1314
+ multipleImages: false,
1315
+ },
1316
+ },
1317
+ {
1318
+ id: 'fal-ai/ideogram/character',
1319
+ name: 'Ideogram Character',
1320
+ released: '2025-03',
1321
+ ...falImage,
1322
+ cost: { type: 'per-image', perImage: 0.10 },
1323
+ features: {
1324
+ editing: true,
1325
+ inpainting: true,
1326
+ aspectRatios: fluxAspectRatios,
1327
+ seed: true,
1328
+ multipleImages: false,
1329
+ },
1330
+ },
1331
+ {
1332
+ id: 'fal-ai/imagen4/preview',
1333
+ name: 'Imagen 4 (Fal)',
1334
+ released: '2025-08-15',
1335
+ ...falImage,
1336
+ cost: { type: 'per-image', perImage: 0.04 },
1337
+ features: {
1338
+ editing: false,
1339
+ inpainting: false,
1340
+ aspectRatios: ['1:1', '3:4', '4:3', '9:16', '16:9'],
1341
+ seed: true,
1342
+ multipleImages: false,
1343
+ },
1344
+ },
1345
+ {
1346
+ id: 'fal-ai/luma-photon',
1347
+ name: 'Luma Photon (Fal)',
1348
+ released: '2024-12-10',
1349
+ ...falImage,
1350
+ cost: { type: 'per-image', perImage: 0.019 },
1351
+ features: {
1352
+ editing: false,
1353
+ inpainting: false,
1354
+ aspectRatios: fluxAspectRatios,
1355
+ seed: false,
1356
+ multipleImages: false,
1357
+ },
1358
+ },
1359
+ {
1360
+ id: 'fal-ai/luma-photon/flash',
1361
+ name: 'Luma Photon Flash (Fal)',
1362
+ released: '2024-12-10',
1363
+ ...falImage,
1364
+ cost: { type: 'per-image', perImage: 0.005 },
1365
+ features: {
1366
+ editing: false,
1367
+ inpainting: false,
1368
+ aspectRatios: fluxAspectRatios,
1369
+ seed: false,
1370
+ multipleImages: false,
1371
+ },
1372
+ },
1373
+ {
1374
+ id: 'fal-ai/omnigen-v2',
1375
+ name: 'OmniGen v2',
1376
+ released: '2025-06',
1377
+ ...falImage,
1378
+ cost: { type: 'per-image', perImage: 0.03 },
1379
+ features: {
1380
+ editing: true,
1381
+ inpainting: false,
1382
+ aspectRatios: fluxAspectRatios,
1383
+ seed: true,
1384
+ multipleImages: false,
1385
+ },
1386
+ },
1387
+ {
1388
+ id: 'fal-ai/qwen-image',
1389
+ name: 'Qwen Image',
1390
+ released: '2025-06',
1391
+ ...falImage,
1392
+ cost: { type: 'per-image', perImage: 0.03 },
1393
+ features: {
1394
+ editing: false,
1395
+ inpainting: false,
1396
+ aspectRatios: fluxAspectRatios,
1397
+ seed: true,
1398
+ multipleImages: false,
1399
+ },
1400
+ },
1401
+ ]
1402
+
1403
+ // ─── video catalog ───────────────────────────────────────────────────────────
1404
+
1405
+ const commonVideoRatios = ['16:9', '9:16', '1:1', '4:3', '3:4']
1406
+
1407
+ export const VIDEO_CATALOG: VideoModelEntry[] = [
1408
+ {
1409
+ id: 'veo-3.1-generate-001',
1410
+ name: 'Veo 3.1',
1411
+ provider: 'google',
1412
+ strategy: 'video',
1413
+ released: '2026-01',
1414
+ cost: {
1415
+ type: 'per-video-second',
1416
+ defaultDurationSec: 8,
1417
+ tiers: [
1418
+ { resolution: '720p', audio: false, costPerSecond: 0.2 },
1419
+ { resolution: '720p', audio: true, costPerSecond: 0.4 },
1420
+ { resolution: '1080p', audio: false, costPerSecond: 0.2 },
1421
+ { resolution: '1080p', audio: true, costPerSecond: 0.4 },
1422
+ { resolution: '4k', audio: false, costPerSecond: 0.4 },
1423
+ { resolution: '4k', audio: true, costPerSecond: 0.6 },
1424
+ ],
1425
+ },
1426
+ features: {
1427
+ textToVideo: true,
1428
+ imageToVideo: false,
1429
+ capabilities: ['t2v'],
1430
+ aspectRatios: ['16:9', '9:16'],
1431
+ resolutions: ['720p', '1080p', '4k'],
1432
+ durationRangeSec: { min: 4, max: 8 },
1433
+ seed: true,
1434
+ multipleVideos: true,
1435
+ },
1436
+ },
1437
+ {
1438
+ id: 'veo-3.1-fast-generate-001',
1439
+ name: 'Veo 3.1 Fast',
1440
+ provider: 'google',
1441
+ strategy: 'video',
1442
+ released: '2026-01',
1443
+ cost: {
1444
+ type: 'per-video-second',
1445
+ defaultDurationSec: 8,
1446
+ tiers: [
1447
+ { resolution: '720p', audio: false, costPerSecond: 0.1 },
1448
+ { resolution: '720p', audio: true, costPerSecond: 0.15 },
1449
+ { resolution: '1080p', audio: false, costPerSecond: 0.1 },
1450
+ { resolution: '1080p', audio: true, costPerSecond: 0.15 },
1451
+ { resolution: '4k', audio: false, costPerSecond: 0.3 },
1452
+ { resolution: '4k', audio: true, costPerSecond: 0.35 },
1453
+ ],
1454
+ },
1455
+ features: {
1456
+ textToVideo: true,
1457
+ imageToVideo: false,
1458
+ capabilities: ['t2v'],
1459
+ aspectRatios: ['16:9', '9:16'],
1460
+ resolutions: ['720p', '1080p', '4k'],
1461
+ durationRangeSec: { min: 4, max: 8 },
1462
+ seed: true,
1463
+ multipleVideos: true,
1464
+ },
1465
+ },
1466
+ {
1467
+ id: 'veo-3.0-generate-001',
1468
+ name: 'Veo 3.0',
1469
+ provider: 'google',
1470
+ strategy: 'video',
1471
+ released: '2025-12',
1472
+ cost: {
1473
+ type: 'per-video-second',
1474
+ defaultDurationSec: 8,
1475
+ tiers: [
1476
+ { resolution: '720p', audio: false, costPerSecond: 0.2 },
1477
+ { resolution: '720p', audio: true, costPerSecond: 0.4 },
1478
+ { resolution: '1080p', audio: false, costPerSecond: 0.2 },
1479
+ { resolution: '1080p', audio: true, costPerSecond: 0.4 },
1480
+ ],
1481
+ },
1482
+ features: {
1483
+ textToVideo: true,
1484
+ imageToVideo: false,
1485
+ capabilities: ['t2v'],
1486
+ aspectRatios: ['16:9', '9:16'],
1487
+ resolutions: ['720p', '1080p'],
1488
+ durationRangeSec: { min: 4, max: 8 },
1489
+ seed: true,
1490
+ multipleVideos: true,
1491
+ },
1492
+ },
1493
+ {
1494
+ id: 'veo-3.0-fast-generate-001',
1495
+ name: 'Veo 3.0 Fast',
1496
+ provider: 'google',
1497
+ strategy: 'video',
1498
+ released: '2025-12',
1499
+ cost: {
1500
+ type: 'per-video-second',
1501
+ defaultDurationSec: 8,
1502
+ tiers: [
1503
+ { resolution: '720p', audio: false, costPerSecond: 0.1 },
1504
+ { resolution: '720p', audio: true, costPerSecond: 0.15 },
1505
+ { resolution: '1080p', audio: false, costPerSecond: 0.1 },
1506
+ { resolution: '1080p', audio: true, costPerSecond: 0.15 },
1507
+ ],
1508
+ },
1509
+ features: {
1510
+ textToVideo: true,
1511
+ imageToVideo: false,
1512
+ capabilities: ['t2v'],
1513
+ aspectRatios: ['16:9', '9:16'],
1514
+ resolutions: ['720p', '1080p'],
1515
+ durationRangeSec: { min: 4, max: 8 },
1516
+ seed: true,
1517
+ multipleVideos: true,
1518
+ },
1519
+ },
1520
+ // ── Vertex: Veo ──────────────────────────────────────────────────────
1521
+ {
1522
+ id: 'vertex/veo-3.1-generate-001',
1523
+ name: 'Veo 3.1 (Vertex)',
1524
+ provider: 'vertex',
1525
+ strategy: 'video',
1526
+ released: '2026-01',
1527
+ cost: {
1528
+ type: 'per-video-second',
1529
+ defaultDurationSec: 8,
1530
+ tiers: [
1531
+ { resolution: '720p', audio: false, costPerSecond: 0.2 },
1532
+ { resolution: '720p', audio: true, costPerSecond: 0.4 },
1533
+ { resolution: '1080p', audio: false, costPerSecond: 0.2 },
1534
+ { resolution: '1080p', audio: true, costPerSecond: 0.4 },
1535
+ { resolution: '4k', audio: false, costPerSecond: 0.4 },
1536
+ { resolution: '4k', audio: true, costPerSecond: 0.6 },
1537
+ ],
1538
+ },
1539
+ features: {
1540
+ textToVideo: true,
1541
+ imageToVideo: false,
1542
+ capabilities: ['t2v'],
1543
+ aspectRatios: ['16:9', '9:16'],
1544
+ resolutions: ['720p', '1080p', '4k'],
1545
+ durationRangeSec: { min: 4, max: 8 },
1546
+ seed: true,
1547
+ multipleVideos: true,
1548
+ },
1549
+ },
1550
+ {
1551
+ id: 'vertex/veo-3.1-fast-generate-001',
1552
+ name: 'Veo 3.1 Fast (Vertex)',
1553
+ provider: 'vertex',
1554
+ strategy: 'video',
1555
+ released: '2026-01',
1556
+ cost: {
1557
+ type: 'per-video-second',
1558
+ defaultDurationSec: 8,
1559
+ tiers: [
1560
+ { resolution: '720p', audio: false, costPerSecond: 0.1 },
1561
+ { resolution: '720p', audio: true, costPerSecond: 0.15 },
1562
+ { resolution: '1080p', audio: false, costPerSecond: 0.1 },
1563
+ { resolution: '1080p', audio: true, costPerSecond: 0.15 },
1564
+ { resolution: '4k', audio: false, costPerSecond: 0.3 },
1565
+ { resolution: '4k', audio: true, costPerSecond: 0.35 },
1566
+ ],
1567
+ },
1568
+ features: {
1569
+ textToVideo: true,
1570
+ imageToVideo: false,
1571
+ capabilities: ['t2v'],
1572
+ aspectRatios: ['16:9', '9:16'],
1573
+ resolutions: ['720p', '1080p', '4k'],
1574
+ durationRangeSec: { min: 4, max: 8 },
1575
+ seed: true,
1576
+ multipleVideos: true,
1577
+ },
1578
+ },
1579
+ {
1580
+ id: 'grok-imagine-video',
1581
+ name: 'Grok Imagine Video',
1582
+ provider: 'xai',
1583
+ strategy: 'video',
1584
+ released: '2026-03',
1585
+ cost: {
1586
+ type: 'per-video-second',
1587
+ defaultDurationSec: 5,
1588
+ tiers: [
1589
+ { resolution: '480p', costPerSecond: 0.05 },
1590
+ { resolution: '720p', costPerSecond: 0.07 },
1591
+ ],
1592
+ },
1593
+ features: {
1594
+ textToVideo: true,
1595
+ imageToVideo: true,
1596
+ capabilities: ['t2v', 'i2v', 'editing', 'extension', 'r2v'],
1597
+ aspectRatios: ['1:1', '16:9', '9:16', '4:3', '3:4', '3:2', '2:3'],
1598
+ resolutions: ['480p', '720p'],
1599
+ durationRangeSec: { min: 1, max: 15 },
1600
+ seed: false,
1601
+ multipleVideos: false,
1602
+ },
1603
+ providerOptions: xaiVideoProviderOptions,
1604
+ },
1605
+ {
1606
+ id: 'grok-imagine-video-1.5',
1607
+ name: 'Grok Imagine Video 1.5',
1608
+ provider: 'xai',
1609
+ strategy: 'video',
1610
+ released: '2026-05',
1611
+ cost: {
1612
+ type: 'per-video-second',
1613
+ defaultDurationSec: 5,
1614
+ tiers: [
1615
+ { resolution: '480p', costPerSecond: 0.08 },
1616
+ { resolution: '720p', costPerSecond: 0.14 },
1617
+ ],
1618
+ },
1619
+ features: {
1620
+ textToVideo: false,
1621
+ imageToVideo: true,
1622
+ capabilities: ['i2v'],
1623
+ aspectRatios: ['1:1', '16:9', '9:16', '4:3', '3:4', '3:2', '2:3'],
1624
+ resolutions: ['480p', '720p'],
1625
+ durationRangeSec: { min: 1, max: 15 },
1626
+ seed: false,
1627
+ multipleVideos: false,
1628
+ },
1629
+ providerOptions: xaiVideoProviderOptions,
1630
+ },
1631
+ // ── Kling (AI Gateway) ──────────────────────────────────────────────
1632
+ // Source: https://ai-gateway.vercel.sh/v1/models (klingai/* entries)
1633
+ {
1634
+ id: 'kling-v3.0-t2v',
1635
+ name: 'Kling v3.0 T2V',
1636
+ provider: 'klingai',
1637
+ strategy: 'video',
1638
+ released: '2026-02',
1639
+ cost: {
1640
+ type: 'per-video-second',
1641
+ defaultDurationSec: 5,
1642
+ tiers: [
1643
+ { mode: 'std', audio: false, costPerSecond: 0.168 },
1644
+ { mode: 'std', audio: true, costPerSecond: 0.308 },
1645
+ { mode: 'pro', audio: false, costPerSecond: 0.224 },
1646
+ { mode: 'pro', audio: true, costPerSecond: 0.392 },
1647
+ ],
1648
+ },
1649
+ features: {
1650
+ textToVideo: true,
1651
+ imageToVideo: false,
1652
+ capabilities: ['t2v'],
1653
+ aspectRatios: ['16:9', '9:16', '1:1'],
1654
+ resolutions: ['720p', '1080p', '4k'],
1655
+ durationRangeSec: { min: 3, max: 15 },
1656
+ seed: false,
1657
+ multipleVideos: false,
1658
+ },
1659
+ },
1660
+ {
1661
+ id: 'kling-v3.0-i2v',
1662
+ name: 'Kling v3.0 I2V',
1663
+ provider: 'klingai',
1664
+ strategy: 'video',
1665
+ released: '2026-02',
1666
+ cost: {
1667
+ type: 'per-video-second',
1668
+ defaultDurationSec: 5,
1669
+ tiers: [
1670
+ { mode: 'std', audio: false, costPerSecond: 0.168 },
1671
+ { mode: 'std', audio: true, costPerSecond: 0.308 },
1672
+ { mode: 'pro', audio: false, costPerSecond: 0.224 },
1673
+ { mode: 'pro', audio: true, costPerSecond: 0.392 },
1674
+ ],
1675
+ },
1676
+ features: {
1677
+ textToVideo: false,
1678
+ imageToVideo: true,
1679
+ capabilities: ['i2v', 'r2v'],
1680
+ aspectRatios: ['16:9', '9:16', '1:1'],
1681
+ resolutions: ['720p', '1080p', '4k'],
1682
+ durationRangeSec: { min: 3, max: 15 },
1683
+ seed: false,
1684
+ multipleVideos: false,
1685
+ },
1686
+ },
1687
+ {
1688
+ id: 'kling-v3.0-motion-control',
1689
+ name: 'Kling v3.0 Motion Control',
1690
+ provider: 'klingai',
1691
+ strategy: 'video',
1692
+ released: '2026-03',
1693
+ cost: {
1694
+ type: 'per-video-second',
1695
+ defaultDurationSec: 5,
1696
+ tiers: [
1697
+ { mode: 'std', costPerSecond: 0.126 },
1698
+ { mode: 'pro', costPerSecond: 0.168 },
1699
+ ],
1700
+ },
1701
+ features: {
1702
+ textToVideo: true,
1703
+ imageToVideo: false,
1704
+ capabilities: ['t2v', 'motion-control'],
1705
+ aspectRatios: ['16:9', '9:16', '1:1'],
1706
+ seed: false,
1707
+ multipleVideos: false,
1708
+ },
1709
+ },
1710
+ {
1711
+ id: 'kling-v2.6-t2v',
1712
+ name: 'Kling v2.6 T2V',
1713
+ provider: 'klingai',
1714
+ strategy: 'video',
1715
+ released: '2025-12',
1716
+ cost: {
1717
+ type: 'per-video-second',
1718
+ defaultDurationSec: 5,
1719
+ tiers: [
1720
+ { mode: 'std', costPerSecond: 0.042 },
1721
+ { mode: 'pro', audio: false, costPerSecond: 0.07 },
1722
+ { mode: 'pro', audio: true, costPerSecond: 0.14 },
1723
+ ],
1724
+ },
1725
+ features: {
1726
+ textToVideo: true,
1727
+ imageToVideo: false,
1728
+ capabilities: ['t2v'],
1729
+ aspectRatios: commonVideoRatios,
1730
+ durationRangeSec: { min: 5, max: 10 },
1731
+ seed: false,
1732
+ multipleVideos: false,
1733
+ },
1734
+ },
1735
+ {
1736
+ id: 'kling-v2.6-i2v',
1737
+ name: 'Kling v2.6 I2V',
1738
+ provider: 'klingai',
1739
+ strategy: 'video',
1740
+ released: '2025-12',
1741
+ cost: {
1742
+ type: 'per-video-second',
1743
+ defaultDurationSec: 5,
1744
+ tiers: [
1745
+ { mode: 'std', costPerSecond: 0.042 },
1746
+ { mode: 'pro', audio: false, costPerSecond: 0.07 },
1747
+ { mode: 'pro', audio: true, costPerSecond: 0.14 },
1748
+ ],
1749
+ },
1750
+ features: {
1751
+ textToVideo: false,
1752
+ imageToVideo: true,
1753
+ capabilities: ['i2v'],
1754
+ aspectRatios: ['16:9', '9:16', '1:1'],
1755
+ resolutions: ['720p', '1080p'],
1756
+ durationRangeSec: { min: 5, max: 10 },
1757
+ seed: false,
1758
+ multipleVideos: false,
1759
+ },
1760
+ },
1761
+ {
1762
+ id: 'kling-v2.6-motion-control',
1763
+ name: 'Kling v2.6 Motion Control',
1764
+ provider: 'klingai',
1765
+ strategy: 'video',
1766
+ released: '2025-12',
1767
+ cost: {
1768
+ type: 'per-video-second',
1769
+ defaultDurationSec: 5,
1770
+ tiers: [
1771
+ { mode: 'std', costPerSecond: 0.07 },
1772
+ { mode: 'pro', costPerSecond: 0.112 },
1773
+ ],
1774
+ },
1775
+ features: {
1776
+ textToVideo: true,
1777
+ imageToVideo: false,
1778
+ capabilities: ['t2v', 'motion-control'],
1779
+ aspectRatios: commonVideoRatios,
1780
+ seed: false,
1781
+ multipleVideos: false,
1782
+ },
1783
+ },
1784
+ {
1785
+ id: 'kling-v2.5-turbo-t2v',
1786
+ name: 'Kling v2.5 Turbo T2V',
1787
+ provider: 'klingai',
1788
+ strategy: 'video',
1789
+ released: '2025-09',
1790
+ cost: {
1791
+ type: 'per-video-second',
1792
+ defaultDurationSec: 5,
1793
+ tiers: [
1794
+ { mode: 'std', costPerSecond: 0.042 },
1795
+ { mode: 'pro', costPerSecond: 0.07 },
1796
+ ],
1797
+ },
1798
+ features: {
1799
+ textToVideo: true,
1800
+ imageToVideo: false,
1801
+ capabilities: ['t2v'],
1802
+ aspectRatios: commonVideoRatios,
1803
+ seed: false,
1804
+ multipleVideos: false,
1805
+ },
1806
+ },
1807
+ {
1808
+ id: 'kling-v2.5-turbo-i2v',
1809
+ name: 'Kling v2.5 Turbo I2V',
1810
+ provider: 'klingai',
1811
+ strategy: 'video',
1812
+ released: '2025-09',
1813
+ cost: {
1814
+ type: 'per-video-second',
1815
+ defaultDurationSec: 5,
1816
+ tiers: [
1817
+ { mode: 'std', costPerSecond: 0.042 },
1818
+ { mode: 'pro', costPerSecond: 0.07 },
1819
+ ],
1820
+ },
1821
+ features: {
1822
+ textToVideo: false,
1823
+ imageToVideo: true,
1824
+ capabilities: ['i2v'],
1825
+ aspectRatios: commonVideoRatios,
1826
+ seed: false,
1827
+ multipleVideos: false,
1828
+ },
1829
+ },
1830
+ // ── Alibaba Wan (AI Gateway) ──────────────────────────────────────────
1831
+ {
1832
+ id: 'wan-v2.6-t2v',
1833
+ name: 'Wan v2.6 T2V',
1834
+ provider: 'alibaba',
1835
+ strategy: 'video',
1836
+ released: '2026-01',
1837
+ cost: {
1838
+ type: 'per-video-second',
1839
+ defaultDurationSec: 5,
1840
+ tiers: [
1841
+ { resolution: '720p', costPerSecond: 0.1 },
1842
+ { resolution: '1080p', costPerSecond: 0.15 },
1843
+ ],
1844
+ },
1845
+ features: {
1846
+ textToVideo: true,
1847
+ imageToVideo: false,
1848
+ capabilities: ['t2v'],
1849
+ resolutions: ['720p', '1080p'],
1850
+ durationRangeSec: { min: 2, max: 15 },
1851
+ seed: false,
1852
+ multipleVideos: false,
1853
+ },
1854
+ },
1855
+ {
1856
+ id: 'wan-v2.6-i2v',
1857
+ name: 'Wan v2.6 I2V',
1858
+ provider: 'alibaba',
1859
+ strategy: 'video',
1860
+ released: '2025-12',
1861
+ cost: {
1862
+ type: 'per-video-second',
1863
+ defaultDurationSec: 5,
1864
+ tiers: [
1865
+ { resolution: '720p', costPerSecond: 0.1 },
1866
+ { resolution: '1080p', costPerSecond: 0.15 },
1867
+ ],
1868
+ },
1869
+ features: {
1870
+ textToVideo: false,
1871
+ imageToVideo: true,
1872
+ capabilities: ['i2v'],
1873
+ aspectRatios: commonVideoRatios,
1874
+ resolutions: ['720p', '1080p'],
1875
+ durationRangeSec: { min: 2, max: 15 },
1876
+ seed: false,
1877
+ multipleVideos: false,
1878
+ },
1879
+ },
1880
+ {
1881
+ id: 'wan-v2.6-i2v-flash',
1882
+ name: 'Wan v2.6 I2V Flash',
1883
+ provider: 'alibaba',
1884
+ strategy: 'video',
1885
+ released: '2025-12',
1886
+ cost: {
1887
+ type: 'per-video-second',
1888
+ defaultDurationSec: 5,
1889
+ tiers: [
1890
+ { resolution: '720p', costPerSecond: 0.05 },
1891
+ { resolution: '1080p', costPerSecond: 0.075 },
1892
+ ],
1893
+ },
1894
+ features: {
1895
+ textToVideo: false,
1896
+ imageToVideo: true,
1897
+ capabilities: ['i2v'],
1898
+ aspectRatios: commonVideoRatios,
1899
+ resolutions: ['720p', '1080p'],
1900
+ durationRangeSec: { min: 2, max: 15 },
1901
+ seed: false,
1902
+ multipleVideos: false,
1903
+ },
1904
+ },
1905
+ {
1906
+ id: 'wan-v2.6-r2v',
1907
+ name: 'Wan v2.6 R2V',
1908
+ provider: 'alibaba',
1909
+ strategy: 'video',
1910
+ released: '2025-12',
1911
+ cost: {
1912
+ type: 'per-video-second',
1913
+ defaultDurationSec: 5,
1914
+ tiers: [
1915
+ { resolution: '720p', costPerSecond: 0.1 },
1916
+ { resolution: '1080p', costPerSecond: 0.15 },
1917
+ ],
1918
+ },
1919
+ features: {
1920
+ textToVideo: false,
1921
+ imageToVideo: false,
1922
+ capabilities: ['r2v'],
1923
+ aspectRatios: commonVideoRatios,
1924
+ resolutions: ['720p', '1080p'],
1925
+ durationRangeSec: { min: 2, max: 10 },
1926
+ seed: false,
1927
+ multipleVideos: false,
1928
+ },
1929
+ },
1930
+ {
1931
+ id: 'wan-v2.6-r2v-flash',
1932
+ name: 'Wan v2.6 R2V Flash',
1933
+ provider: 'alibaba',
1934
+ strategy: 'video',
1935
+ released: '2025-12',
1936
+ cost: {
1937
+ type: 'per-video-second',
1938
+ defaultDurationSec: 5,
1939
+ tiers: [
1940
+ { resolution: '720p', costPerSecond: 0.05 },
1941
+ { resolution: '1080p', costPerSecond: 0.075 },
1942
+ ],
1943
+ },
1944
+ features: {
1945
+ textToVideo: false,
1946
+ imageToVideo: false,
1947
+ capabilities: ['r2v'],
1948
+ aspectRatios: commonVideoRatios,
1949
+ resolutions: ['720p', '1080p'],
1950
+ durationRangeSec: { min: 2, max: 10 },
1951
+ seed: false,
1952
+ multipleVideos: false,
1953
+ },
1954
+ },
1955
+ {
1956
+ id: 'wan-v2.5-t2v-preview',
1957
+ name: 'Wan v2.5 T2V Preview',
1958
+ provider: 'alibaba',
1959
+ strategy: 'video',
1960
+ released: '2025-09',
1961
+ cost: {
1962
+ type: 'per-video-second',
1963
+ defaultDurationSec: 5,
1964
+ tiers: [
1965
+ { resolution: '480p', costPerSecond: 0.05 },
1966
+ { resolution: '720p', costPerSecond: 0.1 },
1967
+ { resolution: '1080p', costPerSecond: 0.15 },
1968
+ ],
1969
+ },
1970
+ features: {
1971
+ textToVideo: true,
1972
+ imageToVideo: false,
1973
+ capabilities: ['t2v'],
1974
+ resolutions: ['480p', '720p', '1080p'],
1975
+ seed: false,
1976
+ multipleVideos: false,
1977
+ },
1978
+ },
1979
+ // ── ByteDance Seedance (AI Gateway) ─────────────────────────────────
1980
+ // Source: https://ai-gateway.vercel.sh/v1/models/bytedance/seedance-2.0/endpoints
1981
+ // Pricing from capabilities.pricing.variants (per-second, resolution-based).
1982
+ // Seedance 2.0 uses C-Dense unified multimodal architecture: text, image, audio, video inputs.
1983
+ // Reference images for r2v must be passed as URLs (max 9 images, 300-6000px, max 30MB each).
1984
+ // Reference images in prompts use @Image1, @Image2, etc. syntax.
1985
+ {
1986
+ id: 'seedance-2.0',
1987
+ name: 'Seedance 2.0',
1988
+ description:
1989
+ 'ByteDance C-Dense multimodal video model. Supports text, image, audio, and video inputs. ' +
1990
+ 'Native audio generation with lip-sync. Up to 720p, 4-15s.',
1991
+ provider: 'bytedance',
1992
+ strategy: 'video',
1993
+ released: '2026-04',
1994
+ cost: {
1995
+ type: 'per-video-second',
1996
+ defaultDurationSec: 8,
1997
+ tiers: [
1998
+ { resolution: '480p', hasVideoInput: false, costPerSecond: 0.07 },
1999
+ { resolution: '480p', hasVideoInput: true, costPerSecond: 0.12 },
2000
+ { resolution: '720p', hasVideoInput: false, costPerSecond: 0.15 },
2001
+ { resolution: '720p', hasVideoInput: true, costPerSecond: 0.26 },
2002
+ ],
2003
+ },
2004
+ features: {
2005
+ textToVideo: true,
2006
+ imageToVideo: true,
2007
+ capabilities: ['t2v', 'i2v', 'r2v'],
2008
+ aspectRatios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
2009
+ resolutions: ['480p', '720p'],
2010
+ durationRangeSec: { min: 4, max: 15 },
2011
+ seed: false,
2012
+ multipleVideos: false,
2013
+ },
2014
+ providerOptions: bytedanceVideoProviderOptions,
2015
+ },
2016
+ {
2017
+ id: 'seedance-2.0-fast',
2018
+ name: 'Seedance 2.0 Fast',
2019
+ description:
2020
+ 'Faster variant of Seedance 2.0 with same capabilities but lower latency and cost.',
2021
+ provider: 'bytedance',
2022
+ strategy: 'video',
2023
+ released: '2026-04',
2024
+ cost: {
2025
+ type: 'per-video-second',
2026
+ defaultDurationSec: 8,
2027
+ tiers: [
2028
+ { resolution: '480p', hasVideoInput: false, costPerSecond: 0.05 },
2029
+ { resolution: '480p', hasVideoInput: true, costPerSecond: 0.09 },
2030
+ { resolution: '720p', hasVideoInput: false, costPerSecond: 0.12 },
2031
+ { resolution: '720p', hasVideoInput: true, costPerSecond: 0.20 },
2032
+ ],
2033
+ },
2034
+ providerOptions: bytedanceVideoProviderOptions,
2035
+ features: {
2036
+ textToVideo: true,
2037
+ imageToVideo: true,
2038
+ capabilities: ['t2v', 'i2v', 'r2v'],
2039
+ aspectRatios: ['16:9', '4:3', '1:1', '3:4', '9:16', '21:9'],
2040
+ resolutions: ['480p', '720p'],
2041
+ durationRangeSec: { min: 4, max: 15 },
2042
+ seed: false,
2043
+ multipleVideos: false,
2044
+ },
2045
+ },
2046
+
2047
+ {
2048
+ id: 'seedance-v1.5-pro',
2049
+ name: 'Seedance v1.5 Pro',
2050
+ description:
2051
+ 'V2A native audio-video joint generation. Synchronized audio output for professional video creation.',
2052
+ provider: 'bytedance',
2053
+ strategy: 'video',
2054
+ released: '2025-12',
2055
+ cost: {
2056
+ type: 'per-video-second',
2057
+ defaultDurationSec: 5,
2058
+ tiers: [
2059
+ { resolution: '480p', audio: false, costPerSecond: 0.0121 },
2060
+ { resolution: '480p', audio: true, costPerSecond: 0.0241 },
2061
+ { resolution: '720p', audio: false, costPerSecond: 0.0259 },
2062
+ { resolution: '720p', audio: true, costPerSecond: 0.0518 },
2063
+ { resolution: '1080p', audio: false, costPerSecond: 0.0583 },
2064
+ { resolution: '1080p', audio: true, costPerSecond: 0.1166 },
2065
+ ],
2066
+ },
2067
+ features: {
2068
+ textToVideo: true,
2069
+ imageToVideo: true,
2070
+ capabilities: ['t2v', 'i2v'],
2071
+ aspectRatios: commonVideoRatios,
2072
+ resolutions: ['480p', '720p', '1080p'],
2073
+ seed: false,
2074
+ multipleVideos: false,
2075
+ },
2076
+ },
2077
+ {
2078
+ id: 'seedance-v1.0-pro',
2079
+ name: 'Seedance v1.0 Pro',
2080
+ description:
2081
+ 'Multi-shot storytelling model. Smooth, detailed, cinematic 1080p HD videos.',
2082
+ provider: 'bytedance',
2083
+ strategy: 'video',
2084
+ released: '2025-06',
2085
+ cost: {
2086
+ type: 'per-video-second',
2087
+ defaultDurationSec: 5,
2088
+ tiers: [
2089
+ { resolution: '480p', costPerSecond: 0.0243 },
2090
+ { resolution: '720p', costPerSecond: 0.0515 },
2091
+ { resolution: '1080p', costPerSecond: 0.1224 },
2092
+ ],
2093
+ },
2094
+ features: {
2095
+ textToVideo: true,
2096
+ imageToVideo: true,
2097
+ capabilities: ['t2v', 'i2v'],
2098
+ aspectRatios: commonVideoRatios,
2099
+ resolutions: ['480p', '720p', '1080p'],
2100
+ seed: false,
2101
+ multipleVideos: false,
2102
+ },
2103
+ },
2104
+ {
2105
+ id: 'seedance-v1.0-pro-fast',
2106
+ name: 'Seedance v1.0 Pro Fast',
2107
+ description:
2108
+ 'Cost-efficient fast variant of Seedance 1.0 Pro.',
2109
+ provider: 'bytedance',
2110
+ strategy: 'video',
2111
+ released: '2025-10',
2112
+ cost: {
2113
+ type: 'per-video-second',
2114
+ defaultDurationSec: 5,
2115
+ tiers: [
2116
+ { resolution: '480p', costPerSecond: 0.0097 },
2117
+ { resolution: '720p', costPerSecond: 0.0206 },
2118
+ { resolution: '1080p', costPerSecond: 0.049 },
2119
+ ],
2120
+ },
2121
+ features: {
2122
+ textToVideo: true,
2123
+ imageToVideo: true,
2124
+ capabilities: ['t2v', 'i2v'],
2125
+ aspectRatios: commonVideoRatios,
2126
+ resolutions: ['480p', '720p', '1080p'],
2127
+ seed: false,
2128
+ multipleVideos: false,
2129
+ },
2130
+ },
2131
+ {
2132
+ id: 'seedance-v1.0-lite-t2v',
2133
+ name: 'Seedance v1.0 Lite T2V',
2134
+ description:
2135
+ 'Lightweight text-to-video model. Balances quality and speed with strong semantic understanding.',
2136
+ provider: 'bytedance',
2137
+ strategy: 'video',
2138
+ released: '2025-06',
2139
+ cost: {
2140
+ type: 'per-video-second',
2141
+ defaultDurationSec: 5,
2142
+ tiers: [
2143
+ { resolution: '480p', costPerSecond: 0.0175 },
2144
+ { resolution: '720p', costPerSecond: 0.0371 },
2145
+ { resolution: '1080p', costPerSecond: 0.0881 },
2146
+ ],
2147
+ },
2148
+ features: {
2149
+ textToVideo: true,
2150
+ imageToVideo: false,
2151
+ capabilities: ['t2v'],
2152
+ aspectRatios: commonVideoRatios,
2153
+ resolutions: ['480p', '720p', '1080p'],
2154
+ durationRangeSec: { min: 3, max: 12 },
2155
+ seed: false,
2156
+ multipleVideos: false,
2157
+ },
2158
+ },
2159
+ {
2160
+ id: 'seedance-v1.0-lite-i2v',
2161
+ name: 'Seedance v1.0 Lite I2V',
2162
+ description:
2163
+ 'Lightweight image-to-video model. Generates video from image/text with reference image support.',
2164
+ provider: 'bytedance',
2165
+ strategy: 'video',
2166
+ released: '2025-06',
2167
+ cost: {
2168
+ type: 'per-video-second',
2169
+ defaultDurationSec: 5,
2170
+ tiers: [
2171
+ { resolution: '480p', costPerSecond: 0.0175 },
2172
+ { resolution: '720p', costPerSecond: 0.0371 },
2173
+ { resolution: '1080p', costPerSecond: 0.0881 },
2174
+ ],
2175
+ },
2176
+ features: {
2177
+ textToVideo: false,
2178
+ imageToVideo: true,
2179
+ capabilities: ['i2v', 'r2v'],
2180
+ aspectRatios: commonVideoRatios,
2181
+ resolutions: ['480p', '720p', '1080p'],
2182
+ durationRangeSec: { min: 3, max: 12 },
2183
+ seed: false,
2184
+ multipleVideos: false,
2185
+ },
2186
+ providerOptions: bytedanceVideoProviderOptions,
2187
+ },
2188
+ // ── Fal video models ─────────────────────────────────────────────────
2189
+ {
2190
+ id: 'luma-ray-2',
2191
+ name: 'Luma Ray 2 (Fal)',
2192
+ provider: 'fal',
2193
+ strategy: 'video',
2194
+ released: '2025-11',
2195
+ cost: { type: 'unknown' },
2196
+ features: {
2197
+ textToVideo: true,
2198
+ imageToVideo: true,
2199
+ capabilities: ['t2v', 'i2v'],
2200
+ aspectRatios: commonVideoRatios,
2201
+ seed: true,
2202
+ multipleVideos: false,
2203
+ },
2204
+ providerOptions: falVideoProviderOptions,
2205
+ },
2206
+ {
2207
+ id: 'minimax-video',
2208
+ name: 'MiniMax Video (Fal)',
2209
+ provider: 'fal',
2210
+ strategy: 'video',
2211
+ released: '2025-10',
2212
+ cost: { type: 'unknown' },
2213
+ features: {
2214
+ textToVideo: true,
2215
+ imageToVideo: false,
2216
+ capabilities: ['t2v'],
2217
+ aspectRatios: commonVideoRatios,
2218
+ seed: false,
2219
+ multipleVideos: false,
2220
+ },
2221
+ providerOptions: falVideoProviderOptions,
2222
+ },
2223
+ {
2224
+ id: 'hunyuan-video',
2225
+ name: 'Hunyuan Video (Fal)',
2226
+ provider: 'fal',
2227
+ strategy: 'video',
2228
+ released: '2025-09',
2229
+ cost: { type: 'unknown' },
2230
+ features: {
2231
+ textToVideo: true,
2232
+ imageToVideo: true,
2233
+ capabilities: ['t2v', 'i2v'],
2234
+ aspectRatios: commonVideoRatios,
2235
+ seed: true,
2236
+ multipleVideos: false,
2237
+ },
2238
+ providerOptions: falVideoProviderOptions,
2239
+ },
2240
+ ]
2241
+
2242
+ // ─── provider option helpers ─────────────────────────────────────────────────
2243
+
2244
+ /**
2245
+ * Collect the valid values for a CLI flag across all providers in the catalog.
2246
+ * Returns a map of provider name → enum values array. Only includes providers
2247
+ * that declare values for the given flag. Used by cli.ts to auto-generate
2248
+ * flag descriptions like "xAI: low, medium, high. OpenAI: auto, low, medium, high".
2249
+ */
2250
+ export function getProviderValuesForFlag(
2251
+ flag: string,
2252
+ catalogs: AnyModelEntry[][] = [CATALOG, VIDEO_CATALOG],
2253
+ ): Map<string, string[]> {
2254
+ const result = new Map<string, string[]>()
2255
+ for (const catalog of catalogs) {
2256
+ for (const entry of catalog) {
2257
+ if (!entry.providerOptions) continue
2258
+ for (const opt of entry.providerOptions) {
2259
+ if (opt.flag === flag && opt.values?.length && !result.has(entry.provider)) {
2260
+ result.set(entry.provider, opt.values)
2261
+ }
2262
+ }
2263
+ }
2264
+ }
2265
+ return result
2266
+ }
2267
+
2268
+ /**
2269
+ * Build a human-readable description suffix listing provider-specific values
2270
+ * for a flag. Includes default values when available.
2271
+ * Example: "xai: low, medium, high (default: medium). openai: auto, low, medium, high (default: auto)"
2272
+ */
2273
+ export function describeProviderValues(
2274
+ flag: string,
2275
+ catalogs?: AnyModelEntry[][],
2276
+ ): string {
2277
+ const allCatalogs = catalogs ?? [CATALOG, VIDEO_CATALOG]
2278
+ // collect {provider → {values, defaultValue}} for this flag
2279
+ const providerInfo = new Map<string, { values: string[]; defaultValue?: string }>()
2280
+ for (const catalog of allCatalogs) {
2281
+ for (const entry of catalog) {
2282
+ if (!entry.providerOptions) continue
2283
+ for (const opt of entry.providerOptions) {
2284
+ if (opt.flag === flag && opt.values?.length && !providerInfo.has(entry.provider)) {
2285
+ providerInfo.set(entry.provider, {
2286
+ values: opt.values,
2287
+ defaultValue: opt.defaultValue,
2288
+ })
2289
+ }
2290
+ }
2291
+ }
2292
+ }
2293
+ if (providerInfo.size === 0) return ''
2294
+ return [...providerInfo.entries()]
2295
+ .map(([provider, info]) => {
2296
+ const vals = info.values.join(', ')
2297
+ const def = info.defaultValue ? ` (default: ${info.defaultValue})` : ''
2298
+ return `${provider}: ${vals}${def}`
2299
+ })
2300
+ .join('. ')
2301
+ }
2302
+
2303
+ /**
2304
+ * Find the ProviderOption definition for a given flag and provider from a model entry.
2305
+ * Returns undefined if the model doesn't support this flag.
2306
+ */
2307
+ export function findProviderOption(
2308
+ entry: AnyModelEntry,
2309
+ flag: string,
2310
+ ): ProviderOption | undefined {
2311
+ return entry.providerOptions?.find((opt) => opt.flag === flag)
2312
+ }
2313
+
2314
+ // ─── lookup helpers ──────────────────────────────────────────────────────────
2315
+
2316
+ const imageCatalogIndex = new Map(CATALOG.map((m) => [m.id, m]))
2317
+ const videoCatalogIndex = new Map(VIDEO_CATALOG.map((m) => [m.id, m]))
2318
+
2319
+ export function findModel(id: string): ImageModelEntry | undefined {
2320
+ return imageCatalogIndex.get(id)
2321
+ }
2322
+
2323
+ export function findVideoModel(id: string): VideoModelEntry | undefined {
2324
+ return videoCatalogIndex.get(id)
2325
+ }
2326
+
2327
+ export function findAnyModel(id: string): AnyModelEntry | undefined {
2328
+ return imageCatalogIndex.get(id) ?? videoCatalogIndex.get(id)
2329
+ }
2330
+
2331
+ // Re-export speech catalog for convenience in CLI code that needs all catalogs.
2332
+ export { SPEECH_CATALOG, findSpeechModel } from './speech-catalog.js'
2333
+
2334
+ // Re-export transcription catalog.
2335
+ export { TRANSCRIPTION_CATALOG, findTranscriptionModel } from './transcription-catalog.js'
2336
+ export type { TranscriptionModelEntry } from './transcription-catalog.js'