ai-chatbot/lib/ai/bananaimage-models.ts
2026-07-13 23:04:54 +08:00

185 lines
5.0 KiB
TypeScript

export interface BananaImageModelPreset {
modelId: string;
displayName: string;
description: string;
supportsVision: boolean;
supportsImageGen: boolean;
capabilities?: Record<string, any>;
defaultParams?: Record<string, any>;
imageGenConfig?: Record<string, any>;
sortOrder: number;
}
export const BANANAIMAGE_BASE_URL = "https://bananaimage.aigenmedia.art";
const BANANAIMAGE_STANDARD_RATIOS = [
"auto",
"1:1",
"2:3",
"3:2",
"3:4",
"4:3",
"4:5",
"5:4",
"9:16",
"16:9",
"21:9",
];
const BANANAIMAGE_EXTENDED_RATIOS = [
"auto",
"1:1",
"1:4",
"1:8",
"2:3",
"3:2",
"3:4",
"4:1",
"4:3",
"4:5",
"5:4",
"8:1",
"9:16",
"16:9",
"21:9",
];
const BANANAIMAGE_GPT_IMAGE_2_RATIOS = [
"auto",
"1:1",
"4:5",
"5:4",
"3:4",
"4:3",
"2:3",
"3:2",
"9:16",
"16:9",
"1:2",
"2:1",
"9:21",
"21:9",
];
const BANANAIMAGE_IMAGE_SIZES = ["1K", "2K", "4K"];
const BANANAIMAGE_IMAGE_CONFIG = {
maxImages: 1,
supportsSize: true,
supports1K: true,
supports2K: true,
supports4K: true,
supportsPromptExtend: false,
supportsNegativePrompt: false,
supportsWatermark: false,
supportsSeed: false,
maxReferenceImages: 14,
supportedImageSizes: BANANAIMAGE_IMAGE_SIZES,
enableLoadingPlaceholder: true,
loadingColor: "yellow",
};
function buildBananaImagePreset(params: {
modelId: string;
displayName: string;
description: string;
apiFormat: "bananaimage-gemini" | "bananaimage-gpt-image-2";
supportedAspectRatios: string[];
sortOrder: number;
}) {
return {
modelId: params.modelId,
displayName: params.displayName,
description: params.description,
supportsVision: true,
supportsImageGen: true,
capabilities: {
provider: "bananaimage",
apiFormat: params.apiFormat,
supportedModes: ["text-to-image", "image-to-image", "reference-images"],
supportedAspectRatios: params.supportedAspectRatios,
supportedImageSizes: BANANAIMAGE_IMAGE_SIZES,
supportsMultiImageReference: true,
maxReferenceImages: 14,
fourKAllowedRatios:
params.apiFormat === "bananaimage-gpt-image-2"
? BANANAIMAGE_GPT_IMAGE_2_RATIOS.filter((ratio) => ratio !== "auto")
: undefined,
},
defaultParams: {
provider: "bananaimage",
apiFormat: params.apiFormat,
endpoint: params.modelId,
imageSize: "2K",
aspectRatio: "auto",
supportedModes: ["text-to-image", "image-to-image", "reference-images"],
},
imageGenConfig: {
...BANANAIMAGE_IMAGE_CONFIG,
apiFormat: params.apiFormat,
supportedAspectRatios: params.supportedAspectRatios,
},
sortOrder: params.sortOrder,
} satisfies BananaImageModelPreset;
}
export const BANANAIMAGE_MODEL_PRESETS: BananaImageModelPreset[] = [
buildBananaImagePreset({
modelId: "gemini-3-pro-image-preview",
displayName: "BananaImage Nano Banana Pro",
description: "BananaImage Nano Banana Pro。支持文生图、图片编辑、多图参考、比例选择和 1K/2K/4K 输出。",
apiFormat: "bananaimage-gemini",
supportedAspectRatios: BANANAIMAGE_STANDARD_RATIOS,
sortOrder: 10,
}),
buildBananaImagePreset({
modelId: "gemini-3.1-flash-image-preview",
displayName: "BananaImage Nano Banana 2",
description: "BananaImage Nano Banana 2。支持文生图、图片编辑、多图参考、极端比例和 1K/2K/4K 输出。",
apiFormat: "bananaimage-gemini",
supportedAspectRatios: BANANAIMAGE_EXTENDED_RATIOS,
sortOrder: 20,
}),
buildBananaImagePreset({
modelId: "gemini-3-pro-image-preview-plus",
displayName: "BananaImage Nano Banana Pro+",
description: "BananaImage Nano Banana Pro+ 放宽限制版。支持文生图、图片编辑、多图参考、比例选择和 1K/2K/4K 输出。",
apiFormat: "bananaimage-gemini",
supportedAspectRatios: BANANAIMAGE_STANDARD_RATIOS,
sortOrder: 30,
}),
buildBananaImagePreset({
modelId: "gemini-3.1-flash-image-preview-plus",
displayName: "BananaImage Nano Banana 2+",
description: "BananaImage Nano Banana 2+ 放宽限制版。支持文生图、图片编辑、多图参考、极端比例和 1K/2K/4K 输出。",
apiFormat: "bananaimage-gemini",
supportedAspectRatios: BANANAIMAGE_EXTENDED_RATIOS,
sortOrder: 40,
}),
buildBananaImagePreset({
modelId: "gpt-image-2",
displayName: "BananaImage GPT Image 2",
description: "BananaImage GPT Image 2。支持文生图、图片编辑、最多 14 张参考图、比例选择和 1K/2K/4K 输出。",
apiFormat: "bananaimage-gpt-image-2",
supportedAspectRatios: BANANAIMAGE_GPT_IMAGE_2_RATIOS,
sortOrder: 50,
}),
];
export function getBananaImageModelPresetById(modelId: string) {
return BANANAIMAGE_MODEL_PRESETS.find(
(preset) => preset.modelId === String(modelId || "").trim()
);
}
export function resolveBananaImageRuntimeModelId(modelId: string) {
const preset = getBananaImageModelPresetById(modelId);
const endpoint = preset?.defaultParams?.endpoint;
if (typeof endpoint === "string" && endpoint.trim()) {
return endpoint.trim();
}
return modelId;
}