diff --git a/WORKSHOP.txt b/WORKSHOP.txt
index 8e20f28..182ada4 100644
--- a/WORKSHOP.txt
+++ b/WORKSHOP.txt
@@ -1,7 +1,7 @@
-Your first handoff
-Triage and the receptionist share document intake in a runnable two-agent workflow.
+Behavioural and technical practice
+Four agents handle intake and both interview phases. The chat page displays the session ID. Summary generation comes next.
-Checkpoint: 07-first-handoff
+Checkpoint: 07-interviewers
Source tag: workshop-v3-reference.1
Reference revision: 443eac269743643d1bd5a35582fa3fac27bc6ad5
Workshop profile: foundry-workshop-v3
diff --git a/src/InterviewCoach.Agent/AgentDelegateFactory.cs b/src/InterviewCoach.Agent/AgentDelegateFactory.cs
index d6ea684..76979f3 100644
--- a/src/InterviewCoach.Agent/AgentDelegateFactory.cs
+++ b/src/InterviewCoach.Agent/AgentDelegateFactory.cs
@@ -139,14 +139,19 @@ private static Workflow CreateHandOffWorkflow(IServiceProvider sp, string key)
name: "triage",
description: "Routes the conversation to the correct interview specialist.",
instructions: """
- You are the Triage agent for an interview intake workflow.
- The only available specialist is "receptionist".
- Hand off session setup and document intake to the receptionist.
- If intake is already complete, explain that the interview specialists are not connected yet.
- Do not restart completed intake or route to unavailable specialists.
+ You route an interview between receptionist, behavioural_interviewer, and technical_interviewer.
+ Handle the latest user request first, using earlier messages only as context.
+ If the user supplies an answer, route to the interviewer who asked the latest question, even if they also want to finish.
+ If the user wants to stop or finish, acknowledge their choice and end this turn without a handoff.
+ Summary generation comes in the next lesson. Do not restart intake or an earlier interview phase.
+ Honor an explicit request for behavioural or technical practice by routing to that interviewer.
+ Route to receptionist only while intake is incomplete.
+ Otherwise keep an answer with the interviewer who asked the latest question.
+ After technical practice, ask whether the user wants more practice; wait for their choice.
""");
// --- Receptionist Agent ---
+ // Collects and saves documents before transferring to behavioural practice.
var receptionistAgent = CreateProviderAgent(
services: sp,
name: "receptionist",
@@ -165,21 +170,72 @@ 3. Ask the user to provide the job description (link or text). Use MarkItDown to
A failed fetch does not complete intake. Ask for corrected input or explicit permission to skip it.
Before each update, call get_interview_session and preserve all six resume/job fields.
Set Transcript to ONLY new text to append, and verify the returned document fields before handoff.
- 5. Once document intake is complete, let the user know. Interview specialists are not connected yet.
- Only hand off to "triage" if the user wants to do something unexpected.
+ 5. Once document intake is complete, let the user know and hand off directly to "behavioural_interviewer"
+ to begin the interview. Only hand off to "triage" if the user wants to do something unexpected.
The user may choose to proceed without a resume or job description — that's fine.
Always maintain a supportive and encouraging tone.
""",
tools: [.. markitdownTools, .. interviewDataTools]);
- // Connect only the two agents that exist at this checkpoint.
+ // --- Behavioural Interviewer Agent ---
+ // Saves behavioural feedback before transferring to technical practice.
+ var behaviouralAgent = CreateProviderAgent(
+ services: sp,
+ name: "behavioural_interviewer",
+ description: "Conducts the behavioural interview and provides feedback.",
+ instructions: """
+ You are the Behavioural Interviewer for an AI Interview Coach system.
+ Your job is to conduct the behavioural part of the interview.
+
+ Process:
+ 1. Fetch the interview session record to get the resume and job description context.
+ 2. Ask behavioural questions one at a time, tailored to the job description and resume.
+ 3. After each answer, provide constructive feedback and analysis.
+ 4. Before each update, call get_interview_session and preserve all six resume/job fields.
+ Set Transcript to ONLY the new questions, answers, and analysis to append; never resend old text.
+ 5. After a few questions (typically 3-5), ask if the user wants to continue or move on.
+ 6. When done, hand off directly to "technical_interviewer" to continue the interview.
+ Only hand off to "triage" if the user wants to do something unexpected.
+
+ Use the STAR method (Situation, Task, Action, Result) to guide your questions.
+ Always maintain a supportive and encouraging tone.
+ """,
+ tools: [.. interviewDataTools]);
+
+ // --- Technical Interviewer Agent ---
+ var technicalAgent = CreateProviderAgent(
+ services: sp,
+ name: "technical_interviewer",
+ description: "Conducts the technical interview and provides feedback.",
+ instructions: """
+ You are the Technical Interviewer for an AI Interview Coach system.
+ Your job is to conduct the technical part of the interview.
+
+ Process:
+ 1. Fetch the interview session record to get the resume and job description context.
+ 2. Ask technical questions one at a time, tailored to the skills in the job description and resume.
+ 3. After each answer, provide constructive feedback, correct any misconceptions, and suggest improvements.
+ 4. Before each update, call get_interview_session and preserve all six resume/job fields.
+ Set Transcript to ONLY the new questions, answers, and analysis to append; never resend old text.
+ 5. After a few questions (typically 3-5), ask if the user wants to continue or wrap up.
+ 6. If the user wants to finish, give brief feedback and acknowledge the end of practice.
+ Do not ask another question or hand off. Only hand off to "triage" for an unexpected request.
+
+ Focus on practical, real-world scenarios relevant to the job.
+ Always maintain a supportive and encouraging tone.
+ """,
+ tools: [.. interviewDataTools]);
+
+ // Connect the four available agents.
#pragma warning disable MAAIW001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var workflow = AgentWorkflowBuilder
.CreateHandoffBuilderWith(triageAgent)
- .WithHandoff(triageAgent, receptionistAgent)
- .WithHandoff(receptionistAgent, triageAgent)
+ .WithHandoffs(triageAgent, [receptionistAgent, behaviouralAgent, technicalAgent])
+ .WithHandoffs(receptionistAgent, [behaviouralAgent, triageAgent])
+ .WithHandoffs(behaviouralAgent, [technicalAgent, triageAgent])
+ .WithHandoff(technicalAgent, triageAgent)
.Build();
#pragma warning restore MAAIW001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
diff --git a/src/InterviewCoach.WebUI/Components/Pages/Chat/Chat.razor b/src/InterviewCoach.WebUI/Components/Pages/Chat/Chat.razor
index 237937f..921192a 100644
--- a/src/InterviewCoach.WebUI/Components/Pages/Chat/Chat.razor
+++ b/src/InterviewCoach.WebUI/Components/Pages/Chat/Chat.razor
@@ -9,6 +9,7 @@
Session ID: @sessionId