Add admin vision lab and LLM vision verification

这个提交包含在:
cryptocommuniums-afk
2026-03-15 00:41:09 +08:00
父节点 20e183d2da
当前提交 ad83ce9c68
修改 18 个文件,包含 915 行新增16 行删除

查看文件

@@ -66,6 +66,33 @@ async function invokeStructured<T>(params: StructuredParams<T>) {
throw lastError instanceof Error ? lastError : new Error("Failed to parse structured LLM response");
}
function contentToPlainText(content: Message["content"]) {
if (typeof content === "string") {
return content;
}
const parts = Array.isArray(content) ? content : [content];
return parts
.map((part) => {
if (typeof part === "string") {
return part;
}
if (part.type === "text") {
return part.text;
}
if (part.type === "image_url") {
return `[image] ${part.image_url.url}`;
}
if (part.type === "file_url") {
return `[file] ${part.file_url.url}`;
}
return "";
})
.filter(Boolean)
.join("\n");
}
function parseDataUrl(input: string) {
const match = input.match(/^data:(.+?);base64,(.+)$/);
if (!match) {
@@ -296,7 +323,7 @@ async function createTextCorrectionResult(payload: {
return {
kind: "analysis_corrections" as const,
corrections: response.choices[0]?.message?.content || "暂无建议",
corrections: contentToPlainText(response.choices[0]?.message?.content || "暂无建议"),
};
}
@@ -347,16 +374,26 @@ async function runMultimodalCorrectionTask(task: NonNullable<TaskRow>) {
},
});
return {
const result = {
kind: "pose_correction_multimodal" as const,
imageUrls: payload.imageUrls,
report,
corrections: renderMultimodalCorrectionMarkdown(report as Parameters<typeof renderMultimodalCorrectionMarkdown>[0]),
visionStatus: "ok" as const,
};
await db.completeVisionTestRun(task.id, {
visionStatus: "ok",
summary: (report as { summary?: string }).summary ?? null,
corrections: result.corrections,
report,
warning: null,
});
return result;
} catch (error) {
const fallback = await createTextCorrectionResult(payload);
return {
const result = {
kind: "pose_correction_multimodal" as const,
imageUrls: payload.imageUrls,
report: null,
@@ -364,6 +401,16 @@ async function runMultimodalCorrectionTask(task: NonNullable<TaskRow>) {
visionStatus: "fallback" as const,
warning: error instanceof Error ? error.message : "Vision model unavailable",
};
await db.completeVisionTestRun(task.id, {
visionStatus: "fallback",
summary: null,
corrections: result.corrections,
report: null,
warning: result.warning,
});
return result;
}
}