first-update
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { db } from '@/lib/db/index';
|
||||
import LLMClient from '@/lib/llm/core/index';
|
||||
import { getModelConfigById } from '@/lib/db/model-config';
|
||||
|
||||
/**
|
||||
* Get current question and generate answers from two models
|
||||
*/
|
||||
export async function GET(request, { params }) {
|
||||
try {
|
||||
const { projectId, taskId } = params;
|
||||
|
||||
const task = await db.task.findFirst({
|
||||
where: {
|
||||
id: taskId,
|
||||
projectId,
|
||||
taskType: 'blind-test'
|
||||
}
|
||||
});
|
||||
|
||||
if (!task) {
|
||||
return NextResponse.json({ code: 404, error: 'Task not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
if (task.status !== 0) {
|
||||
return NextResponse.json({ code: 400, error: 'Task has ended' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Parse task detail
|
||||
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);
|
||||
}
|
||||
|
||||
const questionIds = detail.questionIds || detail.evalDatasetIds || [];
|
||||
const currentIndex = detail.currentIndex || 0;
|
||||
|
||||
// Check if all questions are completed
|
||||
if (questionIds.length === 0 || currentIndex >= questionIds.length) {
|
||||
return NextResponse.json({
|
||||
code: 0,
|
||||
data: {
|
||||
completed: true,
|
||||
message: 'All questions completed'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch current question
|
||||
const currentQuestionId = questionIds[currentIndex];
|
||||
const currentQuestion = await db.evalDatasets.findUnique({
|
||||
where: { id: currentQuestionId },
|
||||
select: {
|
||||
id: true,
|
||||
question: true,
|
||||
questionType: true,
|
||||
correctAnswer: true,
|
||||
tags: true
|
||||
}
|
||||
});
|
||||
|
||||
if (!currentQuestion) {
|
||||
return NextResponse.json({ code: 404, error: 'Question not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
// Fetch both model configs
|
||||
const [modelConfigA, modelConfigB] = await Promise.all([
|
||||
getModelConfigById(modelInfo.modelA.providerId),
|
||||
getModelConfigById(modelInfo.modelB.providerId)
|
||||
]);
|
||||
|
||||
if (!modelConfigA || !modelConfigB) {
|
||||
return NextResponse.json({ code: 400, error: 'Model configuration not found' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Build prompts
|
||||
const systemPrompt = "You are a helpful assistant. Provide detailed and accurate answers to the user's question.";
|
||||
const userPrompt = currentQuestion.question;
|
||||
|
||||
// Call both models in parallel
|
||||
const startTimeA = Date.now();
|
||||
const startTimeB = Date.now();
|
||||
|
||||
let answerA = '';
|
||||
let answerB = '';
|
||||
let errorA = null;
|
||||
let errorB = null;
|
||||
let durationA = 0;
|
||||
let durationB = 0;
|
||||
|
||||
try {
|
||||
// Call model A
|
||||
const clientA = new LLMClient(modelConfigA);
|
||||
|
||||
const resultA = await clientA.chat([
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
]);
|
||||
|
||||
answerA = resultA.text || '';
|
||||
durationA = Date.now() - startTimeA;
|
||||
} catch (err) {
|
||||
console.error('Model A call failed:', err);
|
||||
errorA = err.message;
|
||||
durationA = Date.now() - startTimeA;
|
||||
}
|
||||
|
||||
try {
|
||||
// Call model B
|
||||
const clientB = new LLMClient(modelConfigB);
|
||||
|
||||
const resultB = await clientB.chat([
|
||||
{ role: 'system', content: systemPrompt },
|
||||
{ role: 'user', content: userPrompt }
|
||||
]);
|
||||
|
||||
answerB = resultB.text || '';
|
||||
durationB = Date.now() - startTimeB;
|
||||
} catch (err) {
|
||||
console.error('Model B call failed:', err);
|
||||
errorB = err.message;
|
||||
durationB = Date.now() - startTimeB;
|
||||
}
|
||||
|
||||
// Randomly swap positions (core blind-test behavior)
|
||||
const isSwapped = Math.random() > 0.5;
|
||||
|
||||
return NextResponse.json({
|
||||
code: 0,
|
||||
data: {
|
||||
completed: false,
|
||||
currentIndex,
|
||||
totalCount: evalDatasetIds.length,
|
||||
question: currentQuestion,
|
||||
// Blind test: do not reveal which model is which
|
||||
leftAnswer: {
|
||||
content: isSwapped ? answerB : answerA,
|
||||
error: isSwapped ? errorB : errorA,
|
||||
duration: isSwapped ? durationB : durationA
|
||||
},
|
||||
rightAnswer: {
|
||||
content: isSwapped ? answerA : answerB,
|
||||
error: isSwapped ? errorA : errorB,
|
||||
duration: isSwapped ? durationA : durationB
|
||||
},
|
||||
// Server stores the actual mapping for scoring
|
||||
_swap: isSwapped
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch current question:', error);
|
||||
return NextResponse.json(
|
||||
{ code: 500, error: 'Failed to fetch current question', message: error.message },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user