File size: 4,701 Bytes
282fa46
 
 
 
 
 
 
 
 
 
 
 
 
5c084c2
e7d20ff
5c084c2
 
 
 
282fa46
5aa846e
 
e7d20ff
5aa846e
e7d20ff
5aa846e
282fa46
 
 
e7d20ff
f4ffa02
 
282fa46
5c084c2
e7d20ff
282fa46
 
e7d20ff
282fa46
 
 
 
5c084c2
282fa46
 
 
 
 
 
 
 
 
 
 
 
 
 
e7d20ff
5c084c2
 
282fa46
 
 
5c084c2
 
 
 
 
 
282fa46
 
e7d20ff
282fa46
 
 
 
 
 
 
 
 
 
 
e7d20ff
5c084c2
282fa46
 
 
e7d20ff
5c084c2
282fa46
e7d20ff
5c084c2
 
 
 
 
 
282fa46
 
e7d20ff
 
 
 
 
 
 
5c084c2
e7d20ff
5c084c2
e7d20ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# src/interview_logic.py

from .perplexity_detector import is_ai_generated
from .local_llm_handler import get_llm_response

EXCEL_QUESTIONS = [
    "What is the difference between the VLOOKUP and HLOOKUP functions in Excel?",
    "Explain how to use the INDEX and MATCH functions together, and why you might prefer them over VLOOKUP.",
    "Describe what a Pivot Table is and give an example of a scenario where it would be useful.",
    "What is Conditional Formatting in Excel? Can you provide an example?",
]

def start_interview(state: dict) -> dict:
    """
    Appends a welcome message to the history, preserving the user's first message.
    """
    intro_message = "Welcome to the automated Excel skills assessment! I will ask you a series of questions to gauge your knowledge. Let's start with the first one."
    history = state.get("interview_history", [])
    history.append(("ai", intro_message))
    return {
        **state,
        "interview_status": 1,
        "interview_history": history,
        "questions": EXCEL_QUESTIONS,
        "question_index": 0,
        "evaluations": [],
    }

def ask_question(state: dict) -> dict:
    """Asks the current question based on the question_index."""
    question_index = state["question_index"]
    current_question = state["questions"][question_index]
    history = state.get("interview_history", [])
    history.append(("ai", current_question))
    return {**state, "interview_history": history}

def process_user_response(state: dict) -> dict:
    """Evaluates the user's response and appends the evaluation to history."""
    history = state.get("interview_history", [])
    user_response = history[-1][1]

    if is_ai_generated(user_response, threshold=35.0):
        termination_message = "This interview will now be terminated due to the detection of AI-generated content."
        history.append(("ai", termination_message))
        return {**state, "interview_history": history, "interview_status": 2}
    
    current_question = state["questions"][state["question_index"]]

    evaluation_prompt = (
        "You are an expert evaluator. Concisely evaluate the following answer to an Excel interview question "
        "based on its technical accuracy and clarity. Start the evaluation directly without conversational filler.\n\n"
        f"Question: {current_question}\n"
        f"Answer: {user_response}"
    )
    
    evaluation = get_llm_response(evaluation_prompt)
    
    # Add a clear marker for the user
    history.append(("ai", f"**Evaluation:**\n{evaluation}"))
    
    evaluations = state.get("evaluations", [])
    evaluations.append(evaluation)

    return {
        **state, 
        "interview_history": history,
        "evaluations": evaluations, 
        "question_index": state["question_index"] + 1
    }

def generate_final_report(state: dict) -> dict:
    """Generates and appends the final performance summary."""
    interview_transcript = "\n".join([f"{speaker.capitalize()}: {text}" for speaker, text in state['interview_history']])
    evaluations_summary = "\n\n".join(f"Evaluation for Q{i+1}:\n{e}" for i, e in enumerate(state['evaluations']))

    report_prompt = (
        "You are a career coach. Based on the interview transcript and evaluations below, write a brief, constructive performance summary. "
        "Use Markdown for a 'Strengths' section and an 'Areas for Improvement' section.\n\n"
        f"---TRANSCRIPT---\n{interview_transcript}\n\n---EVALUATIONS---\n{evaluations_summary}"
    )
    
    final_feedback = get_llm_response(report_prompt)
    history = state.get("interview_history", [])
    # Add a clear marker for the user
    history.append(("ai", f"**Final Performance Summary:**\n{final_feedback}"))

    return {**state, "final_feedback": final_feedback, "interview_history": history, "interview_status": 2}

# --- CORRECTED ROUTING LOGIC ---

def route_after_evaluation(state: dict):
    """Routes to the next step after a user's response has been processed."""
    if state.get("interview_status") == 2:
        return "terminate"
    elif state["question_index"] >= len(state["questions"]):
        return "generate_final_report"
    else:
        return "ask_question"

def route_start_of_interview(state: dict):
    """
    CORRECTED: This is the critical fix.
    Checks if it's the very first user message to start the interview.
    Otherwise, it processes the message as an answer.
    """
    # If the history has exactly one turn, it must be the user's initial message.
    if len(state["interview_history"]) == 1:
        return "start_interview"
    # Otherwise, the user is responding to a question.
    else:
        return "process_user_response"