refactor(providers): split KIE image catalog out of imageRegistry to respect file-size cap

imageRegistry.ts hit 805 lines after adding the MiniMax image provider (cap is
800). Extract the KIE image-model catalog (largest single provider entry,
~35 models) into its own semantic-family module,
providers/registry/kie/imageModels.ts, following the same pattern already
used for LMARENA_DIRECT_IMAGE_MODELS. imageRegistry.ts now imports
KIE_IMAGE_MODELS instead of inlining the list.

Also update minimax-media-servicekinds.test.ts: getRegistryMediaKinds derives
membership by design from every registry in MEDIA_KIND_REGISTRIES, including
IMAGE_PROVIDERS. Now that minimax is a key in IMAGE_PROVIDERS, it correctly
gains the "image" kind alongside tts/video/music — the same behavior already
asserted for openai in this file. The exact-match assertion is updated to
["image","music","tts","video"]; the other assertions (which only check
.includes for tts/video/music/llm) were already correct and untouched.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-14 21:54:43 -03:00
parent 3813e40225
commit 33d4e057ef
3 changed files with 61 additions and 42 deletions

View File

@@ -6,6 +6,7 @@
*/
import { LMARENA_DIRECT_IMAGE_MODELS } from "./providers/registry/lmarena/directModels.ts";
import { KIE_IMAGE_MODELS } from "./providers/registry/kie/imageModels.ts";
interface ImageModelEntry {
id: string;
@@ -311,44 +312,7 @@ export const IMAGE_PROVIDERS: Record<string, ImageProviderConfig> = {
authType: "apikey",
authHeader: "bearer",
format: "kie-image",
models: [
{ id: "gpt4o-image", name: "KIE 4o Image" },
{ id: "seedream/4.5-text-to-image", name: "Seedream 4.5", isMarket: true },
{ id: "seedream/4.5-edit", name: "Seedream 4.5 Edit", isMarket: true },
{ id: "seedream/5.0-lite-text-to-image", name: "Seedream 5.0 Lite", isMarket: true },
{ id: "seedream/5.0-lite-image-to-image", name: "Seedream 5.0 Lite I2I", isMarket: true },
{ id: "z-image/4.0-text-to-image", name: "Z-Image v4.0", isMarket: true },
{ id: "z-image/4.5-text-to-image", name: "Z-Image v4.5", isMarket: true },
{ id: "google-imagen/imagen4-fast", name: "Imagen 4 Fast", isMarket: true },
{ id: "google-imagen/imagen4-ultra", name: "Imagen 4 Ultra", isMarket: true },
{ id: "google-imagen/imagen4", name: "Imagen 4", isMarket: true },
{ id: "google-imagen/nano-banana-2", name: "Nano Banana 2", isMarket: true },
{ id: "google-imagen/nano-banana", name: "Nano Banana", isMarket: true },
{ id: "google-imagen/nano-banana-pro", name: "Nano Banana Pro", isMarket: true },
{ id: "google-imagen/nano-banana-edit", name: "Nano Banana Edit", isMarket: true },
{ id: "flux/2-pro-image-to-image", name: "Flux 2 Pro I2I", isMarket: true },
{ id: "flux/2-pro-text-to-image", name: "Flux 2 Pro T2I", isMarket: true },
{ id: "flux/2-image-to-image", name: "Flux 2 I2I", isMarket: true },
{ id: "flux/2-text-to-image", name: "Flux 2 T2I", isMarket: true },
{ id: "flux/kontext", name: "Flux Kontext", isMarket: true },
{ id: "grok-imagine/text-to-image", name: "Grok Imagine T2I", isMarket: true },
{ id: "grok-imagine/image-to-image", name: "Grok Imagine I2I", isMarket: true },
{ id: "gpt/gpt-image-1.5-text-to-image", name: "GPT Image 1.5 T2I", isMarket: true },
{ id: "gpt/gpt-image-1.5-image-to-image", name: "GPT Image 1.5 I2I", isMarket: true },
{ id: "gpt/gpt-image-2-text-to-image", name: "GPT Image 2 T2I", isMarket: true },
{ id: "gpt/gpt-image-2-image-to-image", name: "GPT Image 2 I2I", isMarket: true },
{ id: "ideogram/v3-text-to-image", name: "Ideogram v3", isMarket: true },
{ id: "ideogram/v3-edit", name: "Ideogram v3 Edit", isMarket: true },
{ id: "ideogram/v3-remix", name: "Ideogram v3 Remix", isMarket: true },
{ id: "ideogram/v3-reframe", name: "Ideogram v3 Reframe", isMarket: true },
{ id: "qwen/text-to-image", name: "Qwen T2I", isMarket: true },
{ id: "qwen/image-to-image", name: "Qwen I2I", isMarket: true },
{ id: "qwen/image-edit", name: "Qwen Edit", isMarket: true },
{ id: "qwen2/image-edit", name: "Qwen2 Edit", isMarket: true },
{ id: "qwen2/text-to-image", name: "Qwen2 T2I", isMarket: true },
{ id: "wan/2.7-image", name: "Wan 2.7 Image", isMarket: true },
{ id: "wan/2.7-image-pro", name: "Wan 2.7 Image Pro", isMarket: true },
],
models: KIE_IMAGE_MODELS,
supportedSizes: ["1:1", "16:9", "9:16", "4:3", "3:4"],
},

View File

@@ -0,0 +1,55 @@
/**
* KIE image-generation model catalog.
*
* Extracted out of imageRegistry.ts (which hit the 800-line file-size cap) so the
* catalog lives in its own semantic family module, following the same pattern as
* `providers/registry/lmarena/directModels.ts`. KIE aggregates many third-party
* image models (Seedream, Z-Image, Imagen, Flux, Grok Imagine, GPT Image, Ideogram,
* Qwen, Wan) behind a single `kie-image` format/handler — see `imageRegistry.ts`'s
* `kie` entry for baseUrl/auth/format wiring.
*/
export interface KieImageModelEntry {
id: string;
name: string;
isMarket?: boolean;
}
export const KIE_IMAGE_MODELS: KieImageModelEntry[] = [
{ id: "gpt4o-image", name: "KIE 4o Image" },
{ id: "seedream/4.5-text-to-image", name: "Seedream 4.5", isMarket: true },
{ id: "seedream/4.5-edit", name: "Seedream 4.5 Edit", isMarket: true },
{ id: "seedream/5.0-lite-text-to-image", name: "Seedream 5.0 Lite", isMarket: true },
{ id: "seedream/5.0-lite-image-to-image", name: "Seedream 5.0 Lite I2I", isMarket: true },
{ id: "z-image/4.0-text-to-image", name: "Z-Image v4.0", isMarket: true },
{ id: "z-image/4.5-text-to-image", name: "Z-Image v4.5", isMarket: true },
{ id: "google-imagen/imagen4-fast", name: "Imagen 4 Fast", isMarket: true },
{ id: "google-imagen/imagen4-ultra", name: "Imagen 4 Ultra", isMarket: true },
{ id: "google-imagen/imagen4", name: "Imagen 4", isMarket: true },
{ id: "google-imagen/nano-banana-2", name: "Nano Banana 2", isMarket: true },
{ id: "google-imagen/nano-banana", name: "Nano Banana", isMarket: true },
{ id: "google-imagen/nano-banana-pro", name: "Nano Banana Pro", isMarket: true },
{ id: "google-imagen/nano-banana-edit", name: "Nano Banana Edit", isMarket: true },
{ id: "flux/2-pro-image-to-image", name: "Flux 2 Pro I2I", isMarket: true },
{ id: "flux/2-pro-text-to-image", name: "Flux 2 Pro T2I", isMarket: true },
{ id: "flux/2-image-to-image", name: "Flux 2 I2I", isMarket: true },
{ id: "flux/2-text-to-image", name: "Flux 2 T2I", isMarket: true },
{ id: "flux/kontext", name: "Flux Kontext", isMarket: true },
{ id: "grok-imagine/text-to-image", name: "Grok Imagine T2I", isMarket: true },
{ id: "grok-imagine/image-to-image", name: "Grok Imagine I2I", isMarket: true },
{ id: "gpt/gpt-image-1.5-text-to-image", name: "GPT Image 1.5 T2I", isMarket: true },
{ id: "gpt/gpt-image-1.5-image-to-image", name: "GPT Image 1.5 I2I", isMarket: true },
{ id: "gpt/gpt-image-2-text-to-image", name: "GPT Image 2 T2I", isMarket: true },
{ id: "gpt/gpt-image-2-image-to-image", name: "GPT Image 2 I2I", isMarket: true },
{ id: "ideogram/v3-text-to-image", name: "Ideogram v3", isMarket: true },
{ id: "ideogram/v3-edit", name: "Ideogram v3 Edit", isMarket: true },
{ id: "ideogram/v3-remix", name: "Ideogram v3 Remix", isMarket: true },
{ id: "ideogram/v3-reframe", name: "Ideogram v3 Reframe", isMarket: true },
{ id: "qwen/text-to-image", name: "Qwen T2I", isMarket: true },
{ id: "qwen/image-to-image", name: "Qwen I2I", isMarket: true },
{ id: "qwen/image-edit", name: "Qwen Edit", isMarket: true },
{ id: "qwen2/image-edit", name: "Qwen2 Edit", isMarket: true },
{ id: "qwen2/text-to-image", name: "Qwen2 T2I", isMarket: true },
{ id: "wan/2.7-image", name: "Wan 2.7 Image", isMarket: true },
{ id: "wan/2.7-image-pro", name: "Wan 2.7 Image Pro", isMarket: true },
];

View File

@@ -10,16 +10,16 @@ import assert from "node:assert/strict";
// serviceKinds, so every media page was empty. The fix derives media membership from
// the registries (single source of truth) and unions it with declared serviceKinds.
//
// MiniMax was the flagged case: its international endpoint serves TTS/video/music, the
// China variant (minimax-cn) has no media registry entries.
// MiniMax was the flagged case: its international endpoint serves TTS/video/music/image,
// the China variant (minimax-cn) has no media registry entries.
const { getRegistryMediaKinds, resolveProviderServiceKinds, REGISTRY_MEDIA_KINDS } =
await import("../../open-sse/config/mediaServiceKinds.ts");
const { AI_PROVIDERS } = await import("../../src/shared/constants/providers.ts");
test("minimax (international) derives tts/video/music from the registries", () => {
test("minimax (international) derives image/tts/video/music from the registries", () => {
const kinds = getRegistryMediaKinds("minimax").sort();
assert.deepEqual(kinds, ["music", "tts", "video"]);
assert.deepEqual(kinds, ["image", "music", "tts", "video"]);
});
test("minimax-cn derives no media kinds (China endpoint has no media registry entries)", () => {