Add admin vision lab and LLM vision verification
这个提交包含在:
@@ -1,9 +1,10 @@
|
||||
import { COOKIE_NAME, ONE_YEAR_MS } from "@shared/const";
|
||||
import { getSessionCookieOptions } from "./_core/cookies";
|
||||
import { systemRouter } from "./_core/systemRouter";
|
||||
import { publicProcedure, protectedProcedure, router } from "./_core/trpc";
|
||||
import { adminProcedure, publicProcedure, protectedProcedure, router } from "./_core/trpc";
|
||||
import { z } from "zod";
|
||||
import { sdk } from "./_core/sdk";
|
||||
import { ENV } from "./_core/env";
|
||||
import { storagePut } from "./storage";
|
||||
import * as db from "./db";
|
||||
import { nanoid } from "nanoid";
|
||||
@@ -271,6 +272,111 @@ export const appRouter = router({
|
||||
}),
|
||||
}),
|
||||
|
||||
vision: router({
|
||||
library: protectedProcedure.query(async () => {
|
||||
await db.seedVisionReferenceImages();
|
||||
return db.listVisionReferenceImages();
|
||||
}),
|
||||
|
||||
seedLibrary: adminProcedure.mutation(async () => {
|
||||
await db.seedVisionReferenceImages();
|
||||
const images = await db.listVisionReferenceImages();
|
||||
return { count: images.length };
|
||||
}),
|
||||
|
||||
runs: protectedProcedure
|
||||
.input(z.object({ limit: z.number().min(1).max(100).default(50) }).optional())
|
||||
.query(async ({ ctx, input }) => {
|
||||
const limit = input?.limit ?? 50;
|
||||
return db.listVisionTestRuns(ctx.user.role === "admin" ? undefined : ctx.user.id, limit);
|
||||
}),
|
||||
|
||||
runReference: protectedProcedure
|
||||
.input(z.object({
|
||||
referenceImageId: z.number(),
|
||||
exerciseType: z.string().optional(),
|
||||
}))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const reference = await db.getVisionReferenceImageById(input.referenceImageId);
|
||||
if (!reference || reference.isPublished !== 1) {
|
||||
throw new Error("Reference image not found");
|
||||
}
|
||||
|
||||
const task = await enqueueTask({
|
||||
userId: ctx.user.id,
|
||||
type: "pose_correction_multimodal",
|
||||
title: `${reference.title} 视觉测试`,
|
||||
message: "视觉标准图测试已加入后台队列",
|
||||
payload: {
|
||||
poseMetrics: {
|
||||
referenceSource: "vision_reference_library",
|
||||
expectedFocus: reference.expectedFocus,
|
||||
sourcePageUrl: reference.sourcePageUrl,
|
||||
},
|
||||
exerciseType: input.exerciseType || reference.exerciseType,
|
||||
detectedIssues: [],
|
||||
imageUrls: [reference.imageUrl],
|
||||
},
|
||||
});
|
||||
|
||||
const runId = await db.createVisionTestRun({
|
||||
taskId: task.taskId,
|
||||
userId: ctx.user.id,
|
||||
referenceImageId: reference.id,
|
||||
title: `${reference.title} 视觉测试`,
|
||||
exerciseType: input.exerciseType || reference.exerciseType,
|
||||
imageUrl: reference.imageUrl,
|
||||
status: "queued",
|
||||
visionStatus: "pending",
|
||||
configuredModel: ENV.llmVisionModel || null,
|
||||
expectedFocus: reference.expectedFocus,
|
||||
});
|
||||
|
||||
return { taskId: task.taskId, runId };
|
||||
}),
|
||||
|
||||
runAll: protectedProcedure.mutation(async ({ ctx }) => {
|
||||
const references = await db.listVisionReferenceImages();
|
||||
const queued: Array<{ taskId: string; referenceImageId: number }> = [];
|
||||
|
||||
for (const reference of references) {
|
||||
const task = await enqueueTask({
|
||||
userId: ctx.user.id,
|
||||
type: "pose_correction_multimodal",
|
||||
title: `${reference.title} 视觉测试`,
|
||||
message: "视觉标准图测试已加入后台队列",
|
||||
payload: {
|
||||
poseMetrics: {
|
||||
referenceSource: "vision_reference_library",
|
||||
expectedFocus: reference.expectedFocus,
|
||||
sourcePageUrl: reference.sourcePageUrl,
|
||||
},
|
||||
exerciseType: reference.exerciseType,
|
||||
detectedIssues: [],
|
||||
imageUrls: [reference.imageUrl],
|
||||
},
|
||||
});
|
||||
|
||||
await db.createVisionTestRun({
|
||||
taskId: task.taskId,
|
||||
userId: ctx.user.id,
|
||||
referenceImageId: reference.id,
|
||||
title: `${reference.title} 视觉测试`,
|
||||
exerciseType: reference.exerciseType,
|
||||
imageUrl: reference.imageUrl,
|
||||
status: "queued",
|
||||
visionStatus: "pending",
|
||||
configuredModel: ENV.llmVisionModel || null,
|
||||
expectedFocus: reference.expectedFocus,
|
||||
});
|
||||
|
||||
queued.push({ taskId: task.taskId, referenceImageId: reference.id });
|
||||
}
|
||||
|
||||
return { count: queued.length, queued };
|
||||
}),
|
||||
}),
|
||||
|
||||
task: router({
|
||||
list: protectedProcedure
|
||||
.input(z.object({ limit: z.number().min(1).max(50).default(20) }).optional())
|
||||
|
||||
在新工单中引用
屏蔽一个用户