From ab306e298b2394b30c4de229fa3526e80651ef29 Mon Sep 17 00:00:00 2001 From: 134 Date: Mon, 10 Aug 2026 15:45:28 +0800 Subject: [PATCH] Revert "fix(ai): block costly and text-to-image VIP98K models" This reverts commit 6b2c2c7b42d8a893b170736c06448f99aa059881. --- app/api/admin/vip98k-models/route.ts | 33 +---------------- lib/ai/vip98k-models.ts | 41 --------------------- tests/routes/model-classification.test.ts | 45 +++-------------------- 3 files changed, 7 insertions(+), 112 deletions(-) diff --git a/app/api/admin/vip98k-models/route.ts b/app/api/admin/vip98k-models/route.ts index c461bdce2..145884a3b 100644 --- a/app/api/admin/vip98k-models/route.ts +++ b/app/api/admin/vip98k-models/route.ts @@ -5,11 +5,7 @@ import { type Vip98kModelPreset, } from "@/lib/ai/vip98k-models"; import { db } from "@/lib/db"; -import { - deleteAiModel, - getAiModelsByProviderId, - getAiProviderById, -} from "@/lib/db/queries"; +import { getAiProviderById } from "@/lib/db/queries"; import { aiModel, type AiModel } from "@/lib/db/schema"; import { requireAdmin } from "@/lib/middleware/admin"; @@ -101,33 +97,8 @@ export async function POST(request: Request) { const addedModels: AiModel[] = []; const updatedModels: AiModel[] = []; - const removedModels: AiModel[] = []; const errors: Array<{ modelId: string; error: string }> = []; - const allowedCatalogModelIds = new Set( - catalogPresets.map((preset) => preset.modelId), - ); - const existingModels = await getAiModelsByProviderId({ providerId }); - const blockedImageModels = existingModels.filter( - (model) => - model.supportsImageGen && !allowedCatalogModelIds.has(model.modelId), - ); - for (const model of blockedImageModels) { - try { - const deleted = await deleteAiModel({ id: model.id }); - removedModels.push(...deleted); - } catch (error) { - console.error( - `[VIP98K Models API] Failed to remove blocked image model ${model.modelId}:`, - error, - ); - errors.push({ - modelId: model.modelId, - error: error instanceof Error ? error.message : "Removal failed", - }); - } - } - for (const preset of presets) { try { const existing = await db.query.aiModel.findFirst({ @@ -190,10 +161,8 @@ export async function POST(request: Request) { success: true, addedCount: addedModels.length, updatedCount: updatedModels.length, - removedCount: removedModels.length, addedModels, updatedModels, - removedModels, errors: errors.length > 0 ? errors : undefined, counts: { requested: presets.length, diff --git a/lib/ai/vip98k-models.ts b/lib/ai/vip98k-models.ts index 240f9b2bf..9bc8fca6b 100644 --- a/lib/ai/vip98k-models.ts +++ b/lib/ai/vip98k-models.ts @@ -1,5 +1,4 @@ export const VIP98K_BASE_URL = "https://api.vip98k.com"; -export const VIP98K_MAX_IMAGE_PRICE_CNY = 0.3; export type Vip98kCatalogModelType = | "image" @@ -356,12 +355,6 @@ function getCapabilities(model: Vip98kCatalogModel) { ); } -function getTaskTypes(model: Vip98kCatalogModel) { - return parseStringArray(model.taskTypes || model.task_types).map((item) => - item.trim().toLowerCase().replace(/_/g, "-"), - ); -} - function getInputModes(model: Vip98kCatalogModel) { return parseStringArray(model.inputModes || model.input_modes).map((item) => item.trim().toLowerCase(), @@ -400,39 +393,6 @@ function getBillingMode(model: Vip98kCatalogModel) { return String(model.billingMode || model.billing_mode || "per_request").trim(); } -export function getVip98kImageModelPolicy(model: Vip98kCatalogModel) { - const presetType = resolvePresetType(model); - const effectivePrice = getEffectivePrice(model); - if (presetType !== "image") { - return { - allowed: true, - effectivePrice, - isTextToImage: false, - reasons: [] as string[], - }; - } - - const modelId = getModelId(model).toLowerCase().replace(/_/g, "-"); - const modes = new Set([...getCapabilities(model), ...getTaskTypes(model)]); - const isTextToImage = - modes.has("text-to-image") || modelId.includes("text-to-image"); - const reasons: string[] = []; - if (isTextToImage) reasons.push("text-to-image"); - if ( - effectivePrice !== undefined && - effectivePrice > VIP98K_MAX_IMAGE_PRICE_CNY - ) { - reasons.push("price-over-limit"); - } - - return { - allowed: reasons.length === 0, - effectivePrice, - isTextToImage, - reasons, - }; -} - function getVip98kMetadata(model: Vip98kCatalogModel, type: string) { const invocation = toRecord(model.invocation); return { @@ -811,7 +771,6 @@ export function buildVip98kModelPresets( .map((model, index) => { const modelId = getModelId(model); if (!modelId) return null; - if (!getVip98kImageModelPolicy(model).allowed) return null; const type = resolvePresetType(model); if (type === "image") return createImagePreset(model, index); if (type === "video") return createVideoPreset(model, index); diff --git a/tests/routes/model-classification.test.ts b/tests/routes/model-classification.test.ts index 53c54603a..010b1351a 100644 --- a/tests/routes/model-classification.test.ts +++ b/tests/routes/model-classification.test.ts @@ -385,68 +385,35 @@ test.describe("AI model media classification", () => { modelId: "black-forest-labs/flux-dev", displayName: "Flux Dev", type: "image", - capabilities: ["image_to_image"], + capabilities: ["text_to_image"], }, { - modelId: "google/nano-banana-2/edit", + modelId: "google/nano-banana-2/text-to-image", displayName: "Nano Banana 2", type: "image", - capabilities: ["image_to_image"], + capabilities: ["text_to_image"], }, { modelId: "future-image-with-date", displayName: "Future image", type: "image", - capabilities: ["image_to_image"], + capabilities: ["text_to_image"], releasedAt: "2027-02-01", }, { modelId: "old-image-with-date", displayName: "Old image", type: "image", - capabilities: ["image_to_image"], + capabilities: ["text_to_image"], releasedAt: "2025-12-15", }, ]); expect(presets.find((item) => item.modelId === "black-forest-labs/flux-dev")?.isHidden).toBe(true); expect( - presets.find((item) => item.modelId === "google/nano-banana-2/edit")?.isHidden, + presets.find((item) => item.modelId === "google/nano-banana-2/text-to-image")?.isHidden, ).toBe(false); expect(presets.find((item) => item.modelId === "future-image-with-date")?.isHidden).toBe(false); expect(presets.find((item) => item.modelId === "old-image-with-date")?.isHidden).toBe(true); }); - - test("excludes VIP98K text-to-image and image models priced over CNY 0.30", () => { - const presets = buildVip98kModelPresets([ - { - modelId: "cheap-text-to-image", - type: "image", - task_types: ["text_to_image"], - pricing: { effective_price: 0.02 }, - }, - { - modelId: "expensive-image-edit", - type: "image", - capabilities: ["image_to_image"], - pricing: { effective_price: 0.31 }, - }, - { - modelId: "affordable-image-edit", - type: "image", - capabilities: ["image_to_image"], - pricing: { effective_price: 0.3 }, - }, - { - modelId: "remove-background", - type: "image_tool", - pricing: { effective_price: 0.9 }, - }, - ]); - - expect(presets.map((item) => item.modelId)).toEqual([ - "affordable-image-edit", - "remove-background", - ]); - }); });