1224a74e63
- Grader: separate followup hint from scoring feedback - Interviewer: use followup hint directly without prefix/suffix - Restored standard and choice question presentation paths
89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import { AIMessage } from '@langchain/core/messages';
|
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
import { EvaluationState } from '../state';
|
|
|
|
/**
|
|
* Node responsible for presenting the current question or follow-up to the user.
|
|
*/
|
|
export const interviewerNode = async (
|
|
state: EvaluationState,
|
|
config?: RunnableConfig,
|
|
): Promise<Partial<EvaluationState>> => {
|
|
const { questions, currentQuestionIndex, shouldFollowUp, messages } = state;
|
|
|
|
console.log('[InterviewerNode] Entering node...', {
|
|
numQuestions: questions?.length,
|
|
currentIndex: currentQuestionIndex,
|
|
shouldFollowUp,
|
|
numMessages: messages?.length,
|
|
});
|
|
|
|
if (!questions || questions.length === 0) {
|
|
const isZh = state.language === 'zh';
|
|
const isJa = state.language === 'ja';
|
|
const msg = isZh
|
|
? '很抱歉,我无法为此会话生成任何问题。'
|
|
: isJa
|
|
? '申し訳ありませんが、このセッションの問題を生成できませんでした。'
|
|
: "I'm sorry, I couldn't generate any questions for this session.";
|
|
return {
|
|
messages: [new AIMessage(msg)],
|
|
};
|
|
}
|
|
|
|
const currentQuestion = questions[currentQuestionIndex];
|
|
|
|
if (currentQuestionIndex >= questions.length) {
|
|
return { shouldFollowUp: false };
|
|
}
|
|
|
|
const isZh = state.language === 'zh';
|
|
const isJa = state.language === 'ja';
|
|
|
|
let prompt = '';
|
|
|
|
if (
|
|
shouldFollowUp &&
|
|
state.feedbackHistory &&
|
|
state.feedbackHistory.length > 0
|
|
) {
|
|
const lastFeedbackMsg =
|
|
state.feedbackHistory[state.feedbackHistory.length - 1];
|
|
prompt = lastFeedbackMsg.content.toString();
|
|
} else if (currentQuestion.questionType === 'MULTIPLE_CHOICE' && currentQuestion.options?.length > 0) {
|
|
const label = isZh
|
|
? `问题 ${currentQuestionIndex + 1}`
|
|
: isJa
|
|
? `質問 ${currentQuestionIndex + 1}`
|
|
: `Question ${currentQuestionIndex + 1}`;
|
|
|
|
const instruction = isZh
|
|
? '请选择一个选项'
|
|
: isJa
|
|
? '選択肢から1つ選んでください'
|
|
: 'Please select one option';
|
|
|
|
prompt = `${label}: ${currentQuestion.questionText}\n\n${instruction}`;
|
|
} else {
|
|
const label = isZh
|
|
? `问题 ${currentQuestionIndex + 1}`
|
|
: isJa
|
|
? `質問 ${currentQuestionIndex + 1}`
|
|
: `Question ${currentQuestionIndex + 1}`;
|
|
|
|
const instruction = isZh
|
|
? '请提供您的回答。'
|
|
: isJa
|
|
? '回答を入力してください。'
|
|
: 'Please provide your answer.';
|
|
|
|
prompt = `${label}: ${currentQuestion.questionText}\n\n${instruction}`;
|
|
}
|
|
|
|
console.log('[InterviewerNode] Returning question:', { currentQuestionIndex, questionText: currentQuestion?.questionText });
|
|
return {
|
|
messages: [new AIMessage(prompt)],
|
|
shouldFollowUp: false,
|
|
};
|
|
};
|