first-update
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { db } from '@/lib/db/index';
|
||||
|
||||
/**
|
||||
* Get all blind-test tasks for a project
|
||||
*/
|
||||
export async function GET(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
const { searchParams } = new URL(request.url);
|
||||
const page = parseInt(searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(searchParams.get('pageSize') || '20');
|
||||
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Project ID is required' }, { status: 400 });
|
||||
}
|
||||
|
||||
const skip = (page - 1) * pageSize;
|
||||
|
||||
// Fetch task list and total count
|
||||
const [tasks, total] = await Promise.all([
|
||||
db.task.findMany({
|
||||
where: {
|
||||
projectId,
|
||||
taskType: 'blind-test'
|
||||
},
|
||||
orderBy: { createAt: 'desc' },
|
||||
skip,
|
||||
take: pageSize
|
||||
}),
|
||||
db.task.count({
|
||||
where: {
|
||||
projectId,
|
||||
taskType: 'blind-test'
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
// Fetch evaluation results for all tasks to calculate scores
|
||||
const taskIds = tasks.map(t => t.id);
|
||||
const allEvalResults = await db.evalResults.findMany({
|
||||
where: { taskId: { in: taskIds } },
|
||||
select: {
|
||||
taskId: true,
|
||||
judgeResponse: true
|
||||
}
|
||||
});
|
||||
|
||||
// Group results by taskId and calculate scores
|
||||
const taskScores = {};
|
||||
for (const result of allEvalResults) {
|
||||
if (!taskScores[result.taskId]) {
|
||||
taskScores[result.taskId] = { modelAScore: 0, modelBScore: 0 };
|
||||
}
|
||||
try {
|
||||
const judge = JSON.parse(result.judgeResponse || '{}');
|
||||
taskScores[result.taskId].modelAScore += judge.modelAScore || 0;
|
||||
taskScores[result.taskId].modelBScore += judge.modelBScore || 0;
|
||||
} catch (e) {
|
||||
// Ignore parse errors
|
||||
}
|
||||
}
|
||||
|
||||
// Parse task detail fields and attach scores
|
||||
const tasksWithDetails = tasks.map(task => {
|
||||
let detail = {};
|
||||
let modelInfo = {};
|
||||
try {
|
||||
detail = task.detail ? JSON.parse(task.detail) : {};
|
||||
modelInfo = task.modelInfo ? JSON.parse(task.modelInfo) : {};
|
||||
} catch (e) {
|
||||
console.error('Failed to parse task detail:', e);
|
||||
}
|
||||
|
||||
// Attach calculated scores as results array
|
||||
const scores = taskScores[task.id] || { modelAScore: 0, modelBScore: 0 };
|
||||
const results = [
|
||||
{
|
||||
modelAScore: scores.modelAScore,
|
||||
modelBScore: scores.modelBScore
|
||||
}
|
||||
];
|
||||
|
||||
return {
|
||||
...task,
|
||||
detail: {
|
||||
...detail,
|
||||
results // Attach results for display in task card
|
||||
},
|
||||
modelInfo
|
||||
};
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
code: 0,
|
||||
data: {
|
||||
items: tasksWithDetails,
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
totalPages: Math.ceil(total / pageSize)
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch blind-test task list:', error);
|
||||
return NextResponse.json(
|
||||
{ code: 500, error: 'Failed to fetch blind-test task list', message: error.message },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a blind-test task
|
||||
*/
|
||||
export async function POST(request, { params }) {
|
||||
try {
|
||||
const { projectId } = params;
|
||||
const data = await request.json();
|
||||
|
||||
const { modelA, modelB, evalDatasetIds, language = 'zh-CN' } = data;
|
||||
|
||||
if (!modelA || !modelA.modelId || !modelA.providerId) {
|
||||
return NextResponse.json({ code: 400, error: 'Please select model A' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!modelB || !modelB.modelId || !modelB.providerId) {
|
||||
return NextResponse.json({ code: 400, error: 'Please select model B' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (modelA.modelId === modelB.modelId && modelA.providerId === modelB.providerId) {
|
||||
return NextResponse.json({ code: 400, error: 'The two models must be different' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!evalDatasetIds || evalDatasetIds.length === 0) {
|
||||
return NextResponse.json({ code: 400, error: 'Please select questions to evaluate' }, { status: 400 });
|
||||
}
|
||||
|
||||
const evalDatasets = await db.evalDatasets.findMany({
|
||||
where: {
|
||||
id: { in: evalDatasetIds },
|
||||
projectId
|
||||
},
|
||||
select: { id: true, questionType: true }
|
||||
});
|
||||
|
||||
const invalidQuestions = evalDatasets.filter(
|
||||
q => q.questionType !== 'short_answer' && q.questionType !== 'open_ended'
|
||||
);
|
||||
|
||||
if (invalidQuestions.length > 0) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
code: 400,
|
||||
error: 'Blind-test tasks only support short-answer and open-ended questions'
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Fetch model config info
|
||||
const [modelConfigA, modelConfigB] = await Promise.all([
|
||||
db.modelConfig.findFirst({
|
||||
where: { projectId, providerId: modelA.providerId, modelId: modelA.modelId }
|
||||
}),
|
||||
db.modelConfig.findFirst({
|
||||
where: { projectId, providerId: modelB.providerId, modelId: modelB.modelId }
|
||||
})
|
||||
]);
|
||||
|
||||
// Build model info (two models)
|
||||
const modelInfo = {
|
||||
modelA: {
|
||||
id: modelConfigA?.id,
|
||||
modelId: modelA.modelId,
|
||||
modelName: modelConfigA?.modelName || modelA.modelId,
|
||||
providerId: modelA.providerId,
|
||||
providerName: modelConfigA?.providerName || modelA.providerId
|
||||
},
|
||||
modelB: {
|
||||
id: modelConfigB?.id,
|
||||
modelId: modelB.modelId,
|
||||
modelName: modelConfigB?.modelName || modelB.modelId,
|
||||
providerId: modelB.providerId,
|
||||
providerName: modelConfigB?.providerName || modelB.providerId
|
||||
}
|
||||
};
|
||||
|
||||
// Build task detail (only store evalDatasetIds and currentIndex)
|
||||
const taskDetail = {
|
||||
evalDatasetIds,
|
||||
currentIndex: 0 // Current question index
|
||||
};
|
||||
|
||||
// Create task
|
||||
const newTask = await db.task.create({
|
||||
data: {
|
||||
projectId,
|
||||
taskType: 'blind-test',
|
||||
status: 0, // Running
|
||||
modelInfo: JSON.stringify(modelInfo),
|
||||
language,
|
||||
detail: JSON.stringify(taskDetail),
|
||||
totalCount: evalDatasetIds.length,
|
||||
completedCount: 0,
|
||||
note: ''
|
||||
}
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
code: 0,
|
||||
data: {
|
||||
...newTask,
|
||||
detail: taskDetail,
|
||||
modelInfo
|
||||
},
|
||||
message: 'Blind-test task created'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to create blind-test task:', error);
|
||||
return NextResponse.json(
|
||||
{ code: 500, error: 'Failed to create blind-test task', message: error.message },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user