fix: support all image providers for canvas text edit
This commit is contained in:
parent
7bf3363211
commit
7d51b980b9
@ -2,7 +2,18 @@ import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { auth } from "@/app/(auth)/auth";
|
||||
import { getEnabledAiModelsWithProvider } from "@/lib/db/queries";
|
||||
import { createGeminiImage } from "@/lib/ai/providers/gemini-image";
|
||||
import { createHuankeGemini } from "@/lib/ai/providers/huanke-gemini";
|
||||
import { createAlibabaImage } from "@/lib/ai/providers/alibaba-image";
|
||||
import { createBflImage } from "@/lib/ai/providers/bfl-image";
|
||||
import { createRuxaImage } from "@/lib/ai/providers/ruxa-image";
|
||||
import { createFalImage } from "@/lib/ai/providers/fal-image";
|
||||
import { createOpenAIImage } from "@/lib/ai/providers/openai-image";
|
||||
import { createMidjourney } from "@/lib/ai/providers/midjourney";
|
||||
import { createRunway } from "@/lib/ai/providers/runway";
|
||||
import { createKrea } from "@/lib/ai/providers/krea";
|
||||
import { createVolcanoVision } from "@/lib/ai/providers/volcano-vision";
|
||||
import { isImageGenerationModelDescriptor } from "@/lib/ai/model-classification";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const maxDuration = 120;
|
||||
@ -19,9 +30,35 @@ const requestSchema = z.object({
|
||||
items: z.array(textItemSchema).min(1, "至少需要一条文字修改"),
|
||||
});
|
||||
|
||||
const SUPPORTED_TEXT_EDIT_PROVIDER_TYPES = new Set([
|
||||
"gemini",
|
||||
"grsai-gpt-image",
|
||||
"huanke-gemini",
|
||||
"alibaba-image",
|
||||
"bfl-image",
|
||||
"ruxa-image",
|
||||
"fal-image",
|
||||
"openai-image",
|
||||
"midjourney",
|
||||
"runway",
|
||||
"krea",
|
||||
"volcano-vision",
|
||||
]);
|
||||
|
||||
function pickTextEditModel(models: Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>) {
|
||||
const candidates = models
|
||||
.filter((item) => item.model.supportsImageGen && item.provider.type === "volcano-vision")
|
||||
.filter(
|
||||
(item) =>
|
||||
isImageGenerationModelDescriptor({
|
||||
providerType: item.provider.type,
|
||||
modelId: item.model.modelId,
|
||||
capabilities: item.model.capabilities,
|
||||
supportsImageGen: item.model.supportsImageGen,
|
||||
}) &&
|
||||
item.model.isEnabled &&
|
||||
item.provider.isEnabled &&
|
||||
SUPPORTED_TEXT_EDIT_PROVIDER_TYPES.has(item.provider.type),
|
||||
)
|
||||
.sort((a, b) => {
|
||||
const aScore =
|
||||
(a.model.isDefaultTextEditModel ? 100 : 0) +
|
||||
@ -39,6 +76,41 @@ function pickTextEditModel(models: Awaited<ReturnType<typeof getEnabledAiModelsW
|
||||
return candidates[0];
|
||||
}
|
||||
|
||||
function createTextEditProvider(
|
||||
provider: Awaited<ReturnType<typeof getEnabledAiModelsWithProvider>>[number]["provider"],
|
||||
) {
|
||||
const baseURL = provider.baseUrl;
|
||||
const apiKey = provider.apiKey;
|
||||
|
||||
switch (provider.type) {
|
||||
case "gemini":
|
||||
case "grsai-gpt-image":
|
||||
return createGeminiImage({ baseURL, apiKey });
|
||||
case "huanke-gemini":
|
||||
return createHuankeGemini({ baseURL, apiKey });
|
||||
case "alibaba-image":
|
||||
return createAlibabaImage({ baseURL, apiKey });
|
||||
case "bfl-image":
|
||||
return createBflImage({ baseURL, apiKey });
|
||||
case "ruxa-image":
|
||||
return createRuxaImage({ baseURL, apiKey });
|
||||
case "fal-image":
|
||||
return createFalImage({ baseURL, apiKey });
|
||||
case "openai-image":
|
||||
return createOpenAIImage({ baseURL, apiKey });
|
||||
case "midjourney":
|
||||
return createMidjourney({ baseURL, apiKey });
|
||||
case "runway":
|
||||
return createRunway({ baseURL, apiKey });
|
||||
case "krea":
|
||||
return createKrea({ baseURL, apiKey });
|
||||
case "volcano-vision":
|
||||
return createVolcanoVision({ baseURL, apiKey });
|
||||
default:
|
||||
throw new Error(`当前文字编辑暂不支持服务商类型:${provider.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseImageFromMarkdown(markdown: string): { originalUrl: string; thumbnailUrl: string } {
|
||||
const strictMatch = markdown.match(/!\[thumb\|\|\|([^|]+)\|\|\|[^\]]*\]\(([^)]+)\)/);
|
||||
if (strictMatch) {
|
||||
@ -156,7 +228,7 @@ export async function POST(request: Request) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
success: false,
|
||||
error: "未配置可用的文字编辑生图模型,请在系统设置-AI 模型中启用一个火山生图模型并设为默认文字编辑生图模型",
|
||||
error: "未配置可用的文字编辑生图模型,请在系统设置-AI 模型中启用一个支持图片生成的模型并设为默认文字编辑生图模型",
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
@ -171,10 +243,7 @@ export async function POST(request: Request) {
|
||||
isDefaultTextEditModel: selected.model.isDefaultTextEditModel,
|
||||
});
|
||||
|
||||
const provider = createVolcanoVision({
|
||||
baseURL: selected.provider.baseUrl,
|
||||
apiKey: selected.provider.apiKey,
|
||||
});
|
||||
const provider = createTextEditProvider(selected.provider);
|
||||
|
||||
const prompt = buildTextEditPrompt(replacements, deletions);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user