ai-chatbot/components/canvas/tvstar/creativeAnalysisClient.ts

57 lines
2.4 KiB
TypeScript

export type CreativeAnalysisModel = {
id: string;
label: string;
modelId: string;
providerType: string;
supportsVision: boolean;
};
type CreativeAnalysisRequest = {
mode: "agent-plan" | "story-script" | "character-scene-extraction";
prompt: string;
nodeTitle: string;
models: CreativeAnalysisModel[];
preferredModelRef?: string;
imageUrls?: string[];
videoUrls?: string[];
};
function modelPriority(model: CreativeAnalysisModel) {
if (model.providerType === "alibaba" && model.modelId === "qwen3.8-max") return 0;
if (model.providerType === "alibaba" && model.modelId === "qwen3.8-omni-flash") return 1;
return 2;
}
export async function requestCreativeAnalysis(input: CreativeAnalysisRequest): Promise<Record<string, unknown>> {
const hasVisualInput = Boolean(input.imageUrls?.length || input.videoUrls?.length);
const compatible = input.models.filter(model => !hasVisualInput || model.supportsVision);
const selected = input.preferredModelRef
? compatible.find(model => model.id === input.preferredModelRef || model.modelId === input.preferredModelRef)
: undefined;
if (input.preferredModelRef && !selected) throw new Error("所选模型不支持当前素材,请重新选择模型");
const candidates = selected ? [selected] : [...compatible].sort((left, right) => modelPriority(left) - modelPriority(right));
const attempts: (CreativeAnalysisModel | undefined)[] = candidates.length ? candidates : [undefined];
let lastError = "分析失败,请稍后重试";
for (const [index, model] of attempts.entries()) {
const response = await fetch("/api/canvas/workflow/analyze", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
mode: input.mode,
prompt: input.prompt,
nodeTitle: input.nodeTitle,
preferredModelRef: model?.id,
imageUrls: input.imageUrls?.slice(0, 4) || [],
videoUrls: input.videoUrls?.slice(0, 2) || [],
}),
});
const result = await response.json().catch(() => ({}));
if (response.ok && result.success) return result.data as Record<string, unknown>;
lastError = String(result.error || "分析失败,请稍后重试");
const authenticationFailure = /invalid authentication|invalid token|invalid api.?key|authentication failed|鉴权失败|认证失败/i.test(lastError);
if (selected || !authenticationFailure || index === attempts.length - 1) break;
}
throw new Error(lastError);
}