161 lines
4.5 KiB
TypeScript
161 lines
4.5 KiB
TypeScript
import { and, eq } from "drizzle-orm";
|
|
import { NextResponse } from "next/server";
|
|
import {
|
|
BLTCY_IMAGE_MODEL_PRESETS,
|
|
BLTCY_IMAGE_OPENAI_BASE_URL,
|
|
} from "@/lib/ai/bltcy-image-models";
|
|
import { db } from "@/lib/db";
|
|
import { getAiProviderById } from "@/lib/db/queries";
|
|
import { type AiModel, aiModel } from "@/lib/db/schema";
|
|
import { requireAdmin } from "@/lib/middleware/admin";
|
|
|
|
const TRAILING_SLASHES_REGEX = /\/+$/;
|
|
const TRAILING_V1_REGEX = /\/v1$/i;
|
|
const BLTCY_IMAGE_BASE_URL = BLTCY_IMAGE_OPENAI_BASE_URL.replace(
|
|
TRAILING_SLASHES_REGEX,
|
|
""
|
|
);
|
|
const BLTCY_IMAGE_BASE_URL_WITHOUT_V1 = BLTCY_IMAGE_OPENAI_BASE_URL.replace(
|
|
TRAILING_V1_REGEX,
|
|
""
|
|
);
|
|
|
|
function isBltcyImageBaseUrl(value?: string | null) {
|
|
const normalized = String(value || "")
|
|
.trim()
|
|
.replace(TRAILING_SLASHES_REGEX, "");
|
|
return (
|
|
normalized === BLTCY_IMAGE_BASE_URL ||
|
|
normalized === BLTCY_IMAGE_BASE_URL_WITHOUT_V1
|
|
);
|
|
}
|
|
|
|
export async function GET() {
|
|
try {
|
|
await requireAdmin();
|
|
return NextResponse.json({
|
|
presets: BLTCY_IMAGE_MODEL_PRESETS,
|
|
counts: {
|
|
imageEdit: BLTCY_IMAGE_MODEL_PRESETS.length,
|
|
total: BLTCY_IMAGE_MODEL_PRESETS.length,
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
console.error("[BLTCY Image Models API] GET error:", error);
|
|
return NextResponse.json(
|
|
{ error: error.message || "Failed to fetch BLTCY image model presets" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
await requireAdmin();
|
|
|
|
const body = await request.json();
|
|
const providerId = String(body?.providerId || "").trim();
|
|
const modelIds = Array.isArray(body?.modelIds)
|
|
? body.modelIds
|
|
.map((item: unknown) => String(item || "").trim())
|
|
.filter(Boolean)
|
|
: null;
|
|
|
|
if (!providerId) {
|
|
return NextResponse.json(
|
|
{ error: "Provider ID is required" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const provider = await getAiProviderById({ id: providerId });
|
|
if (
|
|
!provider ||
|
|
provider.type !== "openai-image" ||
|
|
!isBltcyImageBaseUrl(provider.baseUrl)
|
|
) {
|
|
return NextResponse.json(
|
|
{ error: "Provider must be a 柏拉图 OpenAI 图片兼容 provider" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const presetsToAdd = modelIds
|
|
? BLTCY_IMAGE_MODEL_PRESETS.filter((preset) =>
|
|
modelIds.includes(preset.modelId)
|
|
)
|
|
: BLTCY_IMAGE_MODEL_PRESETS;
|
|
|
|
const addedModels: AiModel[] = [];
|
|
const errors: { modelId: string; error: string }[] = [];
|
|
|
|
for (const preset of presetsToAdd) {
|
|
try {
|
|
const existing = await db.query.aiModel.findFirst({
|
|
where: and(
|
|
eq(aiModel.providerId, providerId),
|
|
eq(aiModel.modelId, preset.modelId)
|
|
),
|
|
});
|
|
|
|
if (existing) {
|
|
errors.push({
|
|
modelId: preset.modelId,
|
|
error: "Model already exists",
|
|
});
|
|
continue;
|
|
}
|
|
|
|
const [newModel] = await db
|
|
.insert(aiModel)
|
|
.values({
|
|
providerId,
|
|
modelId: preset.modelId,
|
|
displayName: preset.displayName,
|
|
description: preset.description,
|
|
supportsVision: preset.supportsVision,
|
|
supportsImageGen: preset.supportsImageGen,
|
|
isEnabled: true,
|
|
isHidden: false,
|
|
isDefault: false,
|
|
sortOrder: preset.sortOrder,
|
|
capabilities: preset.capabilities || null,
|
|
defaultParams: preset.defaultParams || null,
|
|
imageGenConfig: preset.imageGenConfig || null,
|
|
isSubModel: false,
|
|
parentModelId: null,
|
|
})
|
|
.returning();
|
|
|
|
addedModels.push(newModel);
|
|
} catch (error: any) {
|
|
console.error(
|
|
`[BLTCY Image Models API] Failed to add ${preset.modelId}:`,
|
|
error
|
|
);
|
|
errors.push({
|
|
modelId: preset.modelId,
|
|
error: error.message || "Insert failed",
|
|
});
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
addedCount: addedModels.length,
|
|
addedModels,
|
|
errors: errors.length > 0 ? errors : undefined,
|
|
counts: {
|
|
requested: presetsToAdd.length,
|
|
total: BLTCY_IMAGE_MODEL_PRESETS.length,
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
console.error("[BLTCY Image Models API] POST error:", error);
|
|
return NextResponse.json(
|
|
{ error: error.message || "Failed to add BLTCY image models" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|