From 142640325a06aea6165e6d065114a9a981d7c35c Mon Sep 17 00:00:00 2001 From: kowshik Date: Thu, 6 Feb 2025 20:22:43 +0000 Subject: [PATCH] ds apis implemented --- .gitignore | 57 + app.py | 353 +++ config.py | 20 + conversations.json | 428 +++ data/config_files/questions.json | 258 ++ data/config_files/theme_context.json | 97 + notebooks/conversations.json | 332 +++ notebooks/output.pdf | 112 + notebooks/test.ipynb | 3120 ++++++++++++++++++++++ requirements.txt | 23 + scripts/generate_pdf.py | 101 + scripts/generate_quiz.py | 175 ++ scripts/generate_theme.py | 239 ++ src/llm.py | 197 ++ src/prompts.py | 134 + test.py | 195 ++ upload_folder/Resume_-_Erika_Kiviaho.pdf | Bin 0 -> 169090 bytes utils/document_loader.py | 53 + utils/utils.py | 73 + 19 files changed, 5967 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 config.py create mode 100644 conversations.json create mode 100644 data/config_files/questions.json create mode 100644 data/config_files/theme_context.json create mode 100644 notebooks/conversations.json create mode 100644 notebooks/output.pdf create mode 100644 notebooks/test.ipynb create mode 100644 requirements.txt create mode 100644 scripts/generate_pdf.py create mode 100644 scripts/generate_quiz.py create mode 100644 scripts/generate_theme.py create mode 100644 src/llm.py create mode 100644 src/prompts.py create mode 100644 test.py create mode 100644 upload_folder/Resume_-_Erika_Kiviaho.pdf create mode 100644 utils/document_loader.py create mode 100644 utils/utils.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68a0117 --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Python bytecode +__pycache__/ +*.py[cod] + +# Distribution / packaging +.Python +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +*.egg-info/ +dist/ +build/ + +# IDEs and editors +.vscode/ +.idea/ +*.swp +*.swo + +# Jupyter Notebook checkpoints +.ipynb_checkpoints + +# Pytest cache +.cache + +# Coverage reports +htmlcov/ +.coverage +.coverage.* +.cache +nosetests.xml +test-results/ + +# MyPy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# C extensions +*.so + +# Data files +*.csv +*.dat +*.db +*.sqlite3 + +# Logs +*.log + +# Environment variables +.env \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..2aa27e2 --- /dev/null +++ b/app.py @@ -0,0 +1,353 @@ +import os +from typing import Optional +from fastapi import FastAPI, HTTPException, Security, Depends +from fastapi.security import APIKeyHeader +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +from dotenv import load_dotenv +from utils.document_loader import load_document +import json +from pydantic import BaseModel +from src.llm import ai_chat +from langchain_openai import ChatOpenAI +import requests +import tempfile +from scripts.generate_pdf import create_pdf +from scripts.generate_theme import generate_theme +from scripts.generate_quiz import generate_quiz +from typing import Dict, Any +from fastapi.responses import Response +from datetime import datetime +from fastapi import HTTPException +from pydantic import BaseModel +from typing import Optional, Union, Dict, Any +import os +import requests +import os +from PyPDF2 import PdfReader +from config import QUIZ_TYPES +# Load environment variables +load_dotenv() +API_KEY = os.getenv("API_KEY_ACCESS") + +base_path = os.path.join("data", "config_files") +QUESTIONS_PATH = os.path.join(base_path, "questions.json") +THEME_CONTEXT_PATH = os.path.join(base_path, "theme_context.json") + +# Load themes at module level +with open(THEME_CONTEXT_PATH, "r") as f: + themes = json.load(f) + +# Initialize FastAPI app +app = FastAPI( + title="Fire Fighter Interview API", + description="API For fire fighter", + version="1.0.0" +) + +# Add CORS middleware +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# Setup API key authentication +api_key_header = APIKeyHeader(name="Authorization", auto_error=False) + + + +async def get_api_key(api_key_header: str = Security(api_key_header)) -> str: + """Validate API key from header""" + if not api_key_header or not api_key_header.startswith('Bearer '): + raise HTTPException( + status_code=401, + detail={"error": "Unauthorized", "message": "API key is missing or invalid."} + ) + + token = api_key_header.split(' ')[1] + if token != API_KEY: + raise HTTPException( + status_code=401, + detail={"error": "Unauthorized", "message": "API key does not match."} + ) + + return token + +class ChatRequest(BaseModel): + resume_url: Optional[str] = None + query: str=None + conversation_id: str + theme_id: Optional[int] = 1 + +class ChatResponse(BaseModel): + message: str + end: bool + error: Optional[str] = None + + + +class GeneratePDFRequest(BaseModel): + conversation_id: str + feedback: Optional[str] = None + previous_results: Optional[Dict[str, Any]] = None + resume_url: Optional[str] = None + full_history_url: Optional[str] = None + +class QuizRequest(BaseModel): + pdf_url: str + quiz_type: int # 1, 2, or 3 corresponding to QUIZ_TYPES + +class QuizResponse(BaseModel): + success: bool + message: str + quiz_data: Optional[Dict[str, Any]] = None + error: Optional[str] = None + + +async def extract_pdf_text(pdf_url: str) -> Union[str, None]: + """Extract text from PDF and handle potential errors.""" + try: + response = requests.get(pdf_url) + response.raise_for_status() + + # Create a temporary file + with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_pdf: + temp_pdf.write(response.content) + temp_path = temp_pdf.name + + # Extract text from PDF + reader = PdfReader(temp_path) + text = "\n\n".join( + page.extract_text() for page in reader.pages if page.extract_text() + ) + + # Clean up temporary file + os.unlink(temp_path) + + if not text.strip(): + return None + return text + + except requests.RequestException as e: + raise HTTPException( + status_code=400, + detail=f"Error downloading PDF: {str(e)}" + ) + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Error processing PDF: {str(e)}" + ) + +@app.post("/rescue-career/chat", response_model=ChatResponse) +async def chat_endpoint( + request: ChatRequest, + api_key: str = Depends(get_api_key) +): + try: + # Validate theme + matching_themes = [t for t in themes if t["id"] == request.theme_id] + if not matching_themes: + raise HTTPException( + status_code=400, + detail=f"No theme found with ID {request.theme_id}" + ) + + # Only try to load document if resume_url is provided + resume_docs = "" + if request.resume_url: + docs = load_document(request.resume_url) + if not docs: + raise HTTPException( + status_code=400, + detail="Invalid resume URL: Unable to fetch document" + ) + resume_docs = "\n".join(f"- {doc.page_content}" for doc in docs) + + # Get AI chat response + response = ai_chat( + query=request.query, + conversation_id=request.conversation_id, + theme_id=request.theme_id, + resume=resume_docs + ) + + # Parse response + try: + parsed_response = json.loads(response) + return ChatResponse( + message=parsed_response.get("message", ""), + end=parsed_response.get("end", "no") == "yes", + error=None + ) + except json.JSONDecodeError: + return ChatResponse( + message=response, + end=False, + error=None + ) + + except HTTPException as e: + # Re-raise HTTP exceptions + raise + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Error processing chat request: {str(e)}" + ) + + + +@app.post("/rescue-career/generate-theme") +async def generate_pdf_endpoint( + request: GeneratePDFRequest, + api_key: str = Depends(get_api_key) +): + + try: + # Here you would fetch the conversation data using the conversation_id + # This is a placeholder - replace with your actual conversation data fetching logic + conversation_data = await get_conversation_data(request.conversation_id) + + if not conversation_data: + raise HTTPException( + status_code=404, + detail=f"No conversation found with ID {request.conversation_id}" + ) + + resume_docs = "" + if request.resume_url: + docs = load_document(request.resume_url) + if not docs: + raise HTTPException( + status_code=400, + detail="Invalid resume URL: Unable to fetch document" + ) + resume_docs = "\n".join(f"- {doc.page_content}" for doc in docs) + + + full_history_docs = "" + if request.full_history_url: + docs = load_document(request.full_history_url) + if not docs: + raise HTTPException( + status_code=400, + detail="Invalid full_history URL: Unable to fetch document" + ) + full_history_docs = "\n".join(f"- {doc.page_content}" for doc in docs) + # Generate theme data using the generate_theme function + theme_data = generate_theme( + conversation_data=conversation_data, + feedback=request.feedback, + previous_result=request.previous_results, + resume = resume_docs, + full_history = full_history_docs + ) + + if not theme_data: + raise HTTPException( + status_code=500, + detail="Failed to generate theme data" + ) + + # Generate the PDF using the create_pdf function + pdf_content = create_pdf(theme_data) + + # Create filename with timestamp + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"theme_{timestamp}.pdf" + + # Return the PDF as a response + return Response( + content=pdf_content, + media_type="application/pdf", + headers={ + "Content-Disposition": f'attachment; filename="{filename}"' + } + ) + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Error generating PDF: {str(e)}" + ) + +@app.post("/rescue-career/generate-quiz", response_model=QuizResponse) +async def generate_quiz_endpoint( + request: QuizRequest, + api_key: str = Depends(get_api_key) +): + """Generate quiz based on PDF content and quiz type.""" + # Validate quiz type + if request.quiz_type not in QUIZ_TYPES: + raise HTTPException( + status_code=400, + detail=f"Invalid quiz type. Must be one of: {list(QUIZ_TYPES)}" + ) + + try: + # Extract text from PDF + pdf_text = await extract_pdf_text(request.pdf_url) + if not pdf_text: + return QuizResponse( + success=False, + message="PDF extraction completed but no text content found", + error="Empty PDF content" + ) + + # Generate quiz using the existing function + quiz_data = generate_quiz( + startpop_pdf=pdf_text, + quiz_type=request.quiz_type + ) + + if not quiz_data: + return QuizResponse( + success=False, + message="Quiz generation failed", + error="Unable to generate quiz from the provided content" + ) + + return QuizResponse( + success=True, + message="Quiz generated successfully", + quiz_data=quiz_data + ) + + except HTTPException as he: + raise he + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Unexpected error during quiz generation: {str(e)}" + ) + + + +async def get_conversation_data(conversation_id: str) -> dict: + """ + Fetch conversation data using the conversation ID. + Replace this with your actual implementation to fetch conversation data. + """ + try: + storage_path = "conversations.json" + with open(storage_path, 'r') as f: + convs = json.load(f) + convs_id = convs[conversation_id] + return convs_id + except Exception as e: + print(f"Error fetching conversation data: {e}") + return None + + +@app.on_event("startup") +async def startup_event(): + """Initialize required components on startup""" + pass + +if __name__ == "__main__": + import uvicorn + uvicorn.run("app:app", host="0.0.0.0", port=5048, reload=True) \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..82c8a78 --- /dev/null +++ b/config.py @@ -0,0 +1,20 @@ +QUIZ_TYPES = { + 1: { + "name": "Single Line Text Inputs", + "format": """ + {"question": "Your question here", "correct_answer": "Your correct answer here"} + """ + }, + 2: { + "name": "Multiple Choice Questions", + "format": """ + {"question": "Your question here", "options": ["Option 1", "Option 2", "Option 3"], "correct_answer": "Correct Option"} + """ + }, + 3: { + "name": "True or False Questions", + "format": """ + {"question": "Your question here", "options": ["True", "False"], "correct_answer": "True or False"} + """ + } +} \ No newline at end of file diff --git a/conversations.json b/conversations.json new file mode 100644 index 0000000..e510cfa --- /dev/null +++ b/conversations.json @@ -0,0 +1,428 @@ +{ + "123456789": { + "resume": "[Document(metadata={'source': '/tmp/tmpqjejyycy.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': '/tmp/tmpqjejyycy.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme Guidance for Creating The Professional Connection (Lessons Learned{'id': 1, 'theme': 'Disability Questions', 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person\u2019s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"}", + "messages": [ + { + "role": "ai", + "content": "Tell me about a time when you had to work as part of a team during a challenging situation while volunteering as a firefighter. How did your actions contribute to the team's success?", + "timestamp": "2025-01-20T18:21:21.122031" + }, + { + "role": "human", + "content": "I did made a couple of lessons for our junior ones who find it difficult to carry out some tasks, My actions made the junios one able to understnad convcept and couls so thins with less intervention by senior officers ", + "timestamp": "2025-01-20T18:23:21.269503" + }, + { + "role": "ai", + "content": "That's a great example of teamwork and leadership in action! Can you describe the specific situation or task you were helping the junior team members with? What steps did you take to ensure they understood the concepts clearly?", + "timestamp": "2025-01-20T18:23:22.972163" + }, + { + "role": "human", + "content": "i helped them to n how to use certain devices correctly and training ground on how to attned to mergency ", + "timestamp": "2025-01-20T18:24:09.089028" + }, + { + "role": "ai", + "content": "That's valuable experience! Training junior members on the proper use of devices during emergencies is crucial. How did you assess when they were ready to apply what they learned in real situations? Did you observe any changes in their confidence or performance after your training sessions?", + "timestamp": "2025-01-20T18:24:10.323869" + }, + { + "role": "human", + "content": "Yes i saw a big impovement as this improve their confidence and overall perfomrnace ", + "timestamp": "2025-01-20T18:24:48.313409" + }, + { + "role": "ai", + "content": "It's wonderful to hear that you saw significant improvement in their confidence and performance! Can you share a specific instance during an emergency response where you noticed the juniors applying what they learned? How did that make you feel about your contribution to their training?", + "timestamp": "2025-01-20T18:24:49.495195" + }, + { + "role": "human", + "content": "There was a time one of the junior followed a sneior officer to site and normlly the senior officer did not allows the junior to do a thing as he believes he may not have anough experince the junior officcer was confident and has to go on the tother side and excute the task and this made the whole process faster and cool ", + "timestamp": "2025-01-20T18:26:51.288656" + }, + { + "role": "ai", + "content": "That's an excellent example of how your training positively impacted the junior firefighter's confidence and the overall team's efficiency! It sounds like you played a crucial role in making that happen. How did you feel witnessing that junior take the initiative? Did it reinforce any lessons or motivate you to continue with training other members?", + "timestamp": "2025-01-20T18:26:52.755038" + }, + { + "role": "human", + "content": "It made feel really happy and ready to do more ", + "timestamp": "2025-01-20T18:27:23.254507" + }, + { + "role": "ai", + "content": "That's fantastic to hear! Feeling happy about your contributions can be incredibly motivating. Can you talk about how this experience has influenced your approach to teamwork or leadership moving forward? What specific skills or lessons will you carry with you into future situations?", + "timestamp": "2025-01-20T18:27:24.520854" + }, + { + "role": "human", + "content": "leadership and teamwork ", + "timestamp": "2025-01-20T18:27:49.359266" + }, + { + "role": "ai", + "content": "Leadership and teamwork are essential skills in firefighting! Can you share an example of a time you demonstrated leadership or teamwork in a high-pressure situation, perhaps during an emergency response? What actions did you take, and what was the outcome?", + "timestamp": "2025-01-20T18:27:50.538022" + }, + { + "role": "human", + "content": "By applying what i leanrt ", + "timestamp": "2025-01-20T18:28:14.539165" + }, + { + "role": "ai", + "content": "That's a great approach! Applying what you've learned in high-pressure situations can make a big difference. Can you think of a specific incident where you had to rely on your training and knowledge to contribute to your team's effort during an emergency? What actions did you take, and what was the result?", + "timestamp": "2025-01-20T18:28:16.132002" + }, + { + "role": "human", + "content": "let us end the conersation for now please ", + "timestamp": "2025-01-20T18:28:41.878431" + }, + { + "role": "ai", + "content": "Thank you for sharing your experiences and insights! They will be valuable for your interview preparation. Good luck!", + "timestamp": "2025-01-20T18:28:43.034032" + } + ] + }, + "ewjnjegg": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme Guidance for Creating The Professional Connection (Lessons Learned{'id': 1, 'theme': 'Disability Questions', 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person\u2019s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you had to effectively communicate with someone during a stressful situation, perhaps while responding to an emergency as a volunteer firefighter?", + "timestamp": "2025-01-20T20:40:05.436365" + }, + { + "role": "human", + "content": "what can ypu say about my resume", + "timestamp": "2025-01-20T20:40:22.139718" + }, + { + "role": "ai", + "content": "Your resume showcases a well-rounded background that highlights both your educational achievements and relevant experience in fire service and emergency response. Here are some key strengths:\n\n1. **Focused Education**: You have completed a comprehensive NFPA 1001 Pre-Service Firefighter Program and various other certifications that are crucial for a firefighting career, indicating a strong commitment to the profession.\n\n2. **Relevant Experience**: Your ongoing role as a volunteer firefighter demonstrates practical experience in emergency situations, teamwork, and problem-solving skills. This experience is vital for showing that you can handle real-world challenges.\n\n3. **Skills Diversity**: Your experience in customer service roles, such as at Starbucks, speaks to your strong communication and interpersonal skills, which are essential for providing good customer service as a firefighter.\n\n4. **Volunteering and Leadership**: Being involved in community service and leadership roles, such as coaching, shows your initiative and ability to work with diverse groups, which can enhance team dynamics in firefighting.\n\n5. **Commitment to Continuous Learning**: Your willingness to pursue additional training in areas like emergency management and inclusion training highlights your dedication to personal and professional development.\n\nGiven all these points, you have a solid foundation to leverage in your interviews. Now, let's explore a specific experience that aligns with the current theme of communication and stress management. Can you think of a situation where quick communication made a significant difference during an emergency response?", + "timestamp": "2025-01-20T20:40:28.960197" + } + ] + }, + "gfdbfbhgehb": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme(id, theme and more context) with Guidance for Creating The Professional Connection (Lessons Learned): {'id': 1, 'theme': 'Disability Questions', 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person\u2019s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you had to solve a difficult problem while working as a volunteer firefighter? What was the situation, and how did you handle it?", + "timestamp": "2025-01-20T21:25:08.073496" + }, + { + "role": "human", + "content": "During my time as a volunteer firefighter, we received a call about a residential fire late at night. Upon arrival, we found that the fire had engulfed a significant portion of the house, and the homeowners were visibly distressed as their dog was trapped inside. The first challenge was ensuring the fire didn't spread to neighboring properties, as the houses were closely packed. While part of the team worked on containment, I took charge of assessing the structure's safety to see if a rescue was possible. The situation was tense, as time was critical. I quickly coordinated with my team to create a safe entry point and used a thermal imaging camera to locate the dog. Navigating through thick smoke and debris, I managed to reach the dog, who was trapped in a back room. With my team's support, we safely extracted the dog and reunited it with the family. What made this experience particularly challenging was balancing the rescue operation with the ongoing efforts to control the fire. Effective communication and teamwork were essential to ensuring both the safety of the team and the success of the operation. This experience taught me the importance of staying calm under pressure, trusting my training, and leading decisively during critical moments.", + "timestamp": "2025-01-20T21:27:15.258528" + }, + { + "role": "ai", + "content": "That was a compelling story! Now, can you describe a specific time when you had a disagreement with a team member during your firefighting duties? How did you resolve that conflict?", + "timestamp": "2025-01-20T21:27:16.212187" + }, + { + "role": "human", + "content": "During a training exercise, a fellow firefighter and I had a disagreement about the best approach to simulate a rescue scenario in a confined space. He believed in using a traditional approach we had practiced before, while I proposed a new method that involved using recently introduced equipment to improve efficiency. The situation became tense as we both felt strongly about our perspectives, and time was limited to prepare for the exercise. Recognizing the need for resolution, I suggested we take a few minutes to discuss the pros and cons of each approach, with input from our team lead. I presented my reasoning, highlighting how the new equipment could simulate real-world scenarios more accurately and provide valuable learning opportunities. He shared his concerns about potential safety risks and unfamiliarity with the equipment. By focusing on the shared goal of team safety and skill development, we reached a compromise to combine both approaches: starting with the traditional method and incorporating the new equipment once the team was comfortable. In the end, the exercise went smoothly, and our team gained practical experience with the new equipment while reinforcing foundational skills. This experience taught me the importance of open communication, active listening, and focusing on shared goals to resolve conflicts effectively.", + "timestamp": "2025-01-20T21:28:45.349437" + }, + { + "role": "ai", + "content": "Great example! Now, can you share a time when you were part of a successful team that accomplished a challenging task? What role did you play, and what was the outcome?", + "timestamp": "2025-01-20T21:28:46.677845" + }, + { + "role": "human", + "content": "I played good roles in helping both junior and senior offiucers.", + "timestamp": "2025-01-20T21:29:26.094944" + }, + { + "role": "ai", + "content": "Can you provide a specific example of a challenging task you worked on as a team, highlighting your contributions and the overall outcome? What was your role in that situation?", + "timestamp": "2025-01-20T21:29:27.491027" + }, + { + "role": "human", + "content": "One of the most challenging tasks I worked on as a team was during a large-scale wildfire incident. The fire was rapidly spreading due to high winds, and we were assigned to protect a small rural community in its path. My specific role was to coordinate with neighboring teams and establish a defensible fire line around the most vulnerable areas. My contributions included assessing the terrain, determining the optimal placement of firebreaks, and communicating our strategy to the team. I also took the lead in setting up a water supply system by locating nearby sources and coordinating with the water tanker units. The situation was intense, as we were working against the clock to protect both lives and property. Despite the challenges, our team successfully contained the fire at the perimeter of the community, with minimal damage to the area. This experience reinforced my belief in the power of collaboration, clear communication, and staying composed under pressure.", + "timestamp": "2025-01-20T21:30:21.956752" + }, + { + "role": "ai", + "content": "That was an impressive example of teamwork! Now, can you share a time when you made a mistake during an emergency response? How did you handle it, and what did you learn from that experience?", + "timestamp": "2025-01-20T21:30:23.472074" + }, + { + "role": "human", + "content": "Let us end it for now", + "timestamp": "2025-01-20T21:30:47.374243" + }, + { + "role": "ai", + "content": "Thank you for sharing your experiences! I believe we have gathered enough material to prepare your STARTPOP responses effectively. Good luck with your interview preparation!", + "timestamp": "2025-01-20T21:30:48.932842" + }, + { + "role": "ai", + "content": "Can you tell me about a time when you had to deal with a challenging situation while volunteering as a firefighter? What was the situation and how did you respond?", + "timestamp": "2025-01-20T23:59:32.808932" + }, + { + "role": "ai", + "content": "Can you tell me about a time when you faced a significant challenge while volunteering as a firefighter and how you overcame it?", + "timestamp": "2025-01-21T00:10:39.632022" + } + ] + }, + "efrrb": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme(id, theme and more context) with Guidance for Creating The Professional Connection (Lessons Learned): {'id': 19, 'theme': 'Challenge Questions', 'context': 'Life is full of challenges. It is important for firefighters to be the type of people that take those challenges head on and constantly work to find ways to overcome them.\\n- Grit, persistence, creative problem solving, and strong mental health are the keys to overcoming challenges.\\n- Life can change in a second. Its important to be adaptive and flexible.\\n- Potential Conclusions:\\no And I am certain that ______ Fire works very hard to meet every challenge and then overcome them.\\no I think about how you guys handled the ________ situation\\no or the recent fire at _______\\no and as an outsider looking in, I was thoroughly impressed with the way the department handled it.'}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you faced a significant challenge while responding to an emergency call as a volunteer firefighter? What was the situation, and how did you handle it?", + "timestamp": "2025-01-21T00:11:00.450106" + } + ] + }, + "rgtn": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme(id, theme and more context) with Guidance for Creating The Professional Connection (Lessons Learned): {'id': 10, 'theme': 'Disagree with a Supervisor Questions', 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you demonstrated strong customer service while interacting with the public during your time as a volunteer firefighter or in any of your previous jobs?", + "timestamp": "2025-01-21T00:11:19.572419" + } + ] + }, + "random-conv_123": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme(id, theme and more context) with Guidance for Creating The Professional Connection (Lessons Learned): {'id': 10, 'theme': 'Disagree with a Supervisor Questions', 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you had to work as part of a team in a stressful situation while volunteering at the Muskoka Lakes Fire Department? What was the situation, and how did you and your team handle it?", + "timestamp": "2025-01-21T18:38:32.000940" + }, + { + "role": "human", + "content": "it was a gtough eperince ", + "timestamp": "2025-01-21T18:39:17.418714" + }, + { + "role": "ai", + "content": "It sounds like it was quite challenging. Could you elaborate a bit more on what specifically made that experience tough? What were the key challenges you and your team faced during that situation?", + "timestamp": "2025-01-21T18:39:18.275298" + }, + { + "role": "human", + "content": "le us end it for now ", + "timestamp": "2025-01-21T18:39:35.291572" + }, + { + "role": "ai", + "content": "Thank you for sharing. If you feel ready to continue preparing or have more experiences to discuss later, just let me know!", + "timestamp": "2025-01-21T18:39:36.112467" + } + ] + }, + "54561045": { + "resume": "[Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': 'https://s3.us-east-2.amazonaws.com/com.mkdlabs.images/baas/jordan/096547600220Resume%20%20-%20Erika%20Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": "Current theme(id, theme and more context) with Guidance for Creating The Professional Connection (Lessons Learned): {'id': 10, 'theme': 'Disagree with a Supervisor Questions', 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'}", + "messages": [ + { + "role": "ai", + "content": "Can you tell me about a time when you effectively used problem-solving skills in a volunteer firefighting scenario? What was the situation, and what steps did you take to address it?", + "timestamp": "2025-01-21T20:23:17.710439" + } + ] + }, + "12345": { + "messages": [ + { + "role": "human", + "content": "Hi, I'm preparing for my firefighter interview", + "timestamp": "2025-01-24T21:29:45.063353" + }, + { + "role": "ai", + "content": "CURRENT THEME USER IS INTERESTED IN 1\n\n{\n \"message\": \"That's great to hear! With your background in Fire Science and volunteer firefighting experience, you have a lot to offer. To help with your preparation, let's focus on the theme of 'Customer Service'. Can you share a specific instance from your volunteer experience where you had to go above and beyond to provide excellent customer service during an emergency response?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T21:29:45.066548" + }, + { + "role": "human", + "content": "I have a situation where I helped a elderly person during my EMT shift", + "timestamp": "2025-01-24T21:29:45.935805" + }, + { + "role": "ai", + "content": "CURRENT THEME USER IS INTERESTED IN 1\n\n{\n \"message\": \"That sounds like a perfect example! Could you tell me more about the initial situation you encountered with the elderly person? What were the circumstances, and why did they need assistance?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T21:29:45.937741" + }, + { + "role": "human", + "content": "What was my last questions?", + "timestamp": "2025-01-24T21:32:41.781675" + }, + { + "role": "ai", + "content": "CURRENT THEME USER IS INTERESTED IN 1\n\n{\n \"message\": \"I asked about the initial situation you encountered with the elderly person during your EMT shift. Specifically, I was curious about the circumstances and why they needed assistance. Can you share more details about that?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T21:32:41.785253" + }, + { + "role": "human", + "content": "What was my last questions?", + "timestamp": "2025-01-24T22:04:39.758374" + }, + { + "role": "ai", + "content": "CURRENT THEME USER IS INTERESTED IN 1\n\n{\n \"message\": \"I asked about the initial situation with the elderly person you helped during your EMT shift, looking to understand the circumstances and why they required assistance. Could you share more details about the situation?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T22:04:39.761391" + } + ] + }, + "sam_test": { + "messages": [ + { + "role": "human", + "content": "Hi ", + "timestamp": "2025-01-24T22:38:20.450177" + }, + { + "role": "ai", + "content": "{\n \"message\":\"Hello Erika! Let's dive into the theme of leadership skills. Given your diverse experiences, could you share a moment from your time as Assistant Captain of the Varsity Women\u2019s Hockey Team where you inspired your teammates to reach their full potential? Let's explore how you demonstrated leadership beyond just giving orders.\",\n \"end\":\"no\"\n}", + "timestamp": "2025-01-24T22:38:20.452327" + }, + { + "role": "human", + "content": "Hi ", + "timestamp": "2025-01-24T22:41:52.178605" + }, + { + "role": "ai", + "content": "{\n \"message\":\"Hi Erika! I'm excited to chat with you about your leadership skills. Reflecting on your role as Team Captain of the Canadian National Ringette Team, can you tell me about a specific challenge where you adapted quickly and decisively to lead your team effectively? This could serve as a great basis for discussing leadership in a high-stress environment.\",\n \"end\":\"no\"\n}", + "timestamp": "2025-01-24T22:41:52.181911" + }, + { + "role": "human", + "content": "I am very busy at the moment ", + "timestamp": "2025-01-24T22:42:24.896239" + }, + { + "role": "ai", + "content": "{\n \"message\":\"I understand, Erika. Just a quick one then \u2013 how did your experience as a Council Member & Mentor with Ringette Canada Athletes Council help you develop leadership skills related to fostering a culture of continuous learning and improvement? This could be a key point when talking about promoting innovation and encouraging feedback.\",\n \"end\":\"no\"\n}", + "timestamp": "2025-01-24T22:42:24.898612" + }, + { + "role": "human", + "content": "are you conifent i will pass the interview ", + "timestamp": "2025-01-24T22:43:08.764972" + }, + { + "role": "ai", + "content": "{\n \"message\":\"While I can't guarantee outcomes, I'm confident that by leveraging your experiences and preparing responses based on the STARTPOP framework, you'll have a strong foundation for showcasing your leadership skills. Once you've had the chance to go through the questions, feel free to reach out whenever you're ready to dive back into the interview prep!\",\n \"end\":\"yes\"\n}", + "timestamp": "2025-01-24T22:43:08.767351" + }, + { + "role": "human", + "content": "okay let us continue", + "timestamp": "2025-01-24T22:46:13.181009" + }, + { + "role": "ai", + "content": "{\n \"message\":\"Great! Given your extensive volunteer work, how has your involvement in construction and build projects with Habitat for Humanity influenced your leadership style and approach to teamwork? This could showcase your ability to lead by example and build trust in diverse team settings.\",\n \"end\":\"no\"\n}", + "timestamp": "2025-01-24T22:46:13.183731" + } + ] + }, + "latest": { + "messages": [ + { + "role": "human", + "content": "hi", + "timestamp": "2025-01-24T23:46:57.852413" + }, + { + "role": "ai", + "content": "{\n \"message\": \"Hello there! Given your experience, can you share a time when you had to respond to an unexpected emergency, and how your training helped you in that situation?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T23:46:57.856778" + }, + { + "role": "human", + "content": "i responded by learning from experince", + "timestamp": "2025-01-24T23:47:26.328363" + }, + { + "role": "ai", + "content": "{\n \"message\": \"Great approach! Can you think of a specific incident where this happened, perhaps during your time as a Volunteer Firefighter with Muskoka Lakes Fire Department? What was the situation, and how did you apply your previous learnings?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-24T23:47:26.330976" + }, + { + "role": "human", + "content": "i responded by learning from experince", + "timestamp": "2025-01-25T00:17:41.669616" + }, + { + "role": "ai", + "content": "{\n \"message\": \"That's a valuable approach. Could you elaborate on what specific aspects or techniques from your training were particularly useful during an emergency response? Maybe something from your NFPA training or volunteer firefighting experience?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-01-25T00:17:41.673539" + } + ] + }, + "striyrfefhjegfng": { + "messages": [ + { + "role": "human", + "content": "hi", + "timestamp": "2025-02-05T14:38:18.002995" + }, + { + "role": "ai", + "content": "{\n \"message\": \"Hello! I hope you're doing well. Today, we're focusing on preparing for disability-related questions in your firefighter interview. To start, can you share a time when you interacted with someone who had a visible or invisible disability, and how you approached the situation?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-02-05T14:38:18.006403" + } + ] + }, + "conve657575": { + "messages": [ + { + "role": "human", + "content": "Hi", + "timestamp": "2025-02-05T14:52:12.855875" + }, + { + "role": "ai", + "content": "{\"message\":\"What specific experiences do you have that required you to interact with individuals who may have had visible or invisible disabilities?\",\"end\":\"no\"}", + "timestamp": "2025-02-05T14:52:12.860725" + }, + { + "role": "human", + "content": "I took of them with utmost sincerity", + "timestamp": "2025-02-05T14:53:36.990279" + }, + { + "role": "ai", + "content": "{\"message\":\"Can you tell me about a specific situation where you had to adapt your approach to accommodate someone's disabilities, whether physical or mental, perhaps during your time as a volunteer firefighter or in your previous jobs?\",\"end\":\"no\"}", + "timestamp": "2025-02-05T14:53:36.993797" + } + ] + }, + "54687": { + "messages": [ + { + "role": "ai", + "content": "{\n \"message\": \"Great! Let's talk about disagreements with supervisors. Can you share an experience where you had a disagreement with a supervisor or someone in a leadership role? What was the situation and how did you handle it?\",\n \"end\": \"no\"\n}", + "timestamp": "2025-02-05T15:22:52.123414" + } + ] + } +} \ No newline at end of file diff --git a/data/config_files/questions.json b/data/config_files/questions.json new file mode 100644 index 0000000..0422438 --- /dev/null +++ b/data/config_files/questions.json @@ -0,0 +1,258 @@ +{ + "General Competency Questions": [ + { + "id": 1, + "question": "Why do you want to be a firefighter?" + }, + { + "id": 2, + "question": "What have you done to prepare for a career in the Fire Service?" + }, + { + "id": 3, + "question": "Why do you want to work for this department?" + }, + { + "id": 4, + "question": "Name some of the traits, characteristics, or attributes of a good firefighter." + }, + { + "id": 5, + "question": "What are some of the biggest challenges faced by the Fire Service today?" + }, + { + "id": 6, + "question": "Describe the emergency vs. non-emergency duties of a firefighter." + }, + { + "id": 7, + "question": "Where do you see yourself in 1, 5, 10, 20 years?" + }, + { + "id": 8, + "question": "Describe the chain of command and your role in it." + }, + { + "id": 9, + "question": "How do you handle stress, now and once you have the job?" + }, + { + "id": 10, + "question": "How do you think the role of the firefighter will be different in 5 years?" + }, + { + "id": 11, + "question": "What is the organizational structure of our Fire Department?" + }, + { + "id": 12, + "question": "Why do you think honesty and integrity are important in the Fire Service?" + }, + { + "id": 13, + "question": "What are the advantages and disadvantages of similar vs diverse teams?" + }, + { + "id": 14, + "question": "List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement." + }, + { + "id": 15, + "question": "What is the most important duty of a firefighter?" + }, + { + "id": 16, + "question": "What does leadership mean to you?" + }, + { + "id": 17, + "question": "What do you like most and least about a supervisor?" + }, + { + "id": 18, + "question": "What do you appreciate in a manager’s style?" + }, + { + "id": 19, + "question": "What are the six common leadership styles in the Fire Service?" + }, + { + "id": 20, + "question": "What do you like most and least about being a firefighter?" + }, + { + "id": 21, + "question": "How does diversity impact the Fire Service today?" + }, + { + "id": 22, + "question": "How would you make a positive impact regarding the diversity in the community?" + }, + { + "id": 23, + "question": "Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?" + }, + { + "id": 24, + "question": "Public Education is important in the Fire Service. How would you provide this service?" + }, + { + "id": 25, + "question": "You are a probationary firefighter. How do you prepare yourself?" + }, + { + "id": 26, + "question": "Why is respect so important, and what does it mean?" + }, + { + "id": 27, + "question": "Would you break a rule if asked to?" + }, + { + "id": 28, + "question": "What are potential sources of workplace conflict? How would you handle workplace conflict?" + }, + { + "id": 29, + "question": "Why should we hire you?" + }, + { + "id": 30, + "question": "What are your strengths and weaknesses? (What would your boss say about you?)" + }, + { + "id": 31, + "question": "How do you want to be remembered at the end of your career?" + }, + { + "id": 32, + "question": "What skills do you bring to Dispatch?" + }, + { + "id": 33, + "question": "Walk me through a truck check." + }, + { + "id": 34, + "question": "How do you define teamwork in the context of firefighting?" + }, + { + "id": 35, + "question": "What motivates you to perform well in stressful situations?" + }, + { + "id": 36, + "question": "Explain how you would handle feedback from a superior, especially if it was critical." + }, + { + "id": 37, + "question": "What is your understanding of the core values of the Fire Service?" + }, + { + "id": 38, + "question": "Describe a time when you demonstrated initiative in the workplace." + }, + { + "id": 39, + "question": "How do you prioritize tasks during an emergency response?" + }, + { + "id": 40, + "question": "What role does technology play in modern firefighting, and how are you prepared for it?" + }, + { + "id": 41, + "question": "How would you approach learning new skills and techniques required for this job?" + }, + { + "id": 42, + "question": "Explain how you balance personal and professional commitments in a demanding job." + }, + { + "id": 43, + "question": "What strategies do you use to ensure continuous improvement in your work?" + }, + { + "id": 44, + "question": "How do you approach building trust and relationships within a new team?" + }, + { + "id": 45, + "question": "What does a day in the life of a firefighter look like for both emergency and non-emergency activities?" + } + ], + "Situational Questions": [ + { + "id": 1, + "question": "What would you do if a firefighter makes disparaging remarks in public about visible minorities?" + }, + { + "id": 2, + "question": "What would you do if a senior firefighter is making inappropriate, unwelcomed, bullying comments towards another firefighter?" + }, + { + "id": 3, + "question": "What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?" + }, + { + "id": 4, + "question": "What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?" + }, + { + "id": 5, + "question": "What would you do if your captain gives you a performance review that you are unhappy with?" + }, + { + "id": 6, + "question": "What would you do if you saw a firefighter put a valuable item in their pocket at a call?" + }, + { + "id": 7, + "question": "What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?" + }, + { + "id": 8, + "question": "What would you do if you noticed two firefighters cheating on an exam?" + }, + { + "id": 9, + "question": "What would you do if you see two firefighters getting heated and about to fight?" + }, + { + "id": 10, + "question": "What would you do if you are confronted by an irate citizen and you are all by yourself?" + }, + { + "id": 11, + "question": "What would you do if you are on your way home after a shift and see a car accident or other emergency?" + }, + { + "id": 12, + "question": "What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?" + }, + { + "id": 13, + "question": "What would you do if you notice one firefighter not being included in the group (e.g., coffee poured for everyone but them)?" + }, + { + "id": 14, + "question": "What would you do if you are the apparatus driver and during your daily truck check you discover the emergency lights are not working, and your captain says, 'Don’t worry about it. The next crew on duty will take care of it'?" + }, + { + "id": 15, + "question": "What would you do if one member of the crew has a really negative attitude about training?" + }, + { + "id": 16, + "question": "What would you do if a fellow firefighter tells you they don’t want minorities, women, or LGBTQ+ individuals in the fire service?" + }, + { + "id": 17, + "question": "What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?" + }, + { + "id": 18, + "question": "What would you do if you are faced with conflicting orders from two supervisors at the scene of an emergency?" + } + ] +} \ No newline at end of file diff --git a/data/config_files/theme_context.json b/data/config_files/theme_context.json new file mode 100644 index 0000000..8d76dd8 --- /dev/null +++ b/data/config_files/theme_context.json @@ -0,0 +1,97 @@ +[ + { + "id": 1, + "theme": "Disability Questions", + "context": "Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\n- Potential Conclusions:\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up" + }, + { + "id": 2, + "theme": "Leadership Skills Questions", + "context": "Leadership is not about having authority; it's about inspiring others to reach their full potential.\n- Effective leaders lead by example, demonstrating integrity, accountability, and a commitment to teamwork.\n- In the fire service, leadership is not confined to rank; every firefighter has the opportunity to lead and contribute to the success of the team.\n- Adaptability and decisiveness are crucial qualities in leadership, especially in high-stress and rapidly changing environments.\n- Leadership is also about fostering a culture of continuous learning and improvement, encouraging feedback, and promoting innovation.\n- Potential Conclusions:\no I've heard about the emphasis on leadership development within ______ Fire, and it's clear that the department values cultivating leaders at all levels. I'm eager to contribute to that culture and continue growing as a leader.\no During my station visit, I observed how firefighters at ______ Fire take initiative and support each other, regardless of rank. That collaborative leadership approach is something I aspire to emulate and contribute to.\no I've learned that leadership in the fire service is not just about giving orders; it's about empowering others, building trust, and fostering a sense of unity within the team. I'm excited about the opportunity to lead by example and positively influence my fellow firefighters at ______ Fire." + }, + { + "id": 3, + "theme": "Conflict Questions", + "context": "Conflict is a huge problem in high performing teams.\n- Creates a poisonous work environment, reduces efficiencies, and creates mental health issues.\n- Those are serious issues and must be addressed as soon as they pop up.\n- One of the best ways to address it through increasing the communication and giving people an opportunity to explain their opinions or viewpoints.\n- I tend to think about the three T’s (teamwork, training and trust) and how important it is to fall back on those.\n- Attempt to secure behaviour modification through voluntary compliance.\n- Potential Conclusions:\no I know that professionalism runs through the entire department here. ______\no Firefighters are professional and committed to safe and respectful workplaces.\no One thing about the fire service is that you all do a great job of communicating and creating a chain of command to help simplify complex problems\no Its important to remember the values of the fire service and keep those in mind whenever conflicts arise.\no Tie in stats and figures from your research on the department." + }, + { + "id": 4, + "theme": "Stress Questions", + "context": "My big takeaway is that stress is everywhere, and it affects everyone in different ways.\n- The amount of mental health issues and stress levels are up exponentially with the community.\n- Especially when you factor in the effects of COVID-19 and the lockdowns.\n- That _________ situation made me realize that we must be supportive of one another and reduce the stigma.\n- Potential Conclusions:\no I know that the team members at _______ Fire are exposed to stressful situations on a regular basis, and it is critical that they be supportive to one another in order to maintain a strong team.\no I have spoken to ______ about your mental health programs and can see that you really take the time to pour into each of your firefighter’s cup. I really admire that.\no I looked into that _________ program that your department us" + }, + { + "id": 5, + "theme": "Emergency Questions", + "context": "Emergencies can happen anywhere at anytime.\n- Usually with little to no warning.\n- During those times people fall back onto their training and most commonly practiced strategies.\n- We need to ensure that our personnel are available and ready to answer the call whenever that happens in the community, and they are using the most effective strategies and techniques possible.\n- Potential Conclusions:\no I know that the expectation of _______ Fire is to train at least 2-3 hours per shift.\no That works out to 14-21 hours per month. When you factor in running calls in between those training sessions there is a fair bit of opportunity for Firefighters to become very good at their jobs and be fully prepared.\no Consistent commitment to training everything from the basics up to the complicated things 2-3 hours per shift is what makes the people on _____ Fire so good at their job." + }, + { + "id": 6, + "theme": "Mistake", + "context": "We all make mistakes. It is okay to make them. But it is not okay to not learn from them.\n- Mistakes are just proof that you are trying your best.\n- They are an opportunity for growth and for development.\n- They are the things that help sharpen the knives in a drawer.\n- The key is not to make the same mistake twice.\n- Potential Conclusions:\no I am certain that _______ Firefighters conduct regular follow-ups after calls.\no Its important for everyone to check their ego and be accountable for the things they messed up on.\no I know that Chief ______ promotes an open and transparent environment. He/She is not afraid to admit when they made a mistake. So, it is important for everyone in the department to follow suit." + }, + { + "id": 7, + "theme": "Cultural, Diversity, and Inclusion Questions", + "context": "Communities are becoming more and more diverse everyday. It is important for the Fire Service to recognize that.\n- Steps can be taken every single day to create an environment that is inclusive and open to everyone regardless of their background, language, abilities, or self-identification.\n- Public servants serve the public.\n- No passing judgement on people. No racism, no homophobia, no misogyny.\n- Treat everyone with respect and educate ourselves about the differences in our communities.\n- Potential Conclusions:\no ______ Fire is very professional and respectful. I have only seen and heard good things about how much of a concerted effort you are making to be more inclusive.\no I spent some time looking at the Public Education pamphlets at station _____ and saw that they were offered in a bunch of different languages. That was amazing and I really think that shows the community how much you care about reducing the barriers to safety.\no I spoke with _____ and learned about how enjoyable of an experience they have had working on your departmen" + }, + { + "id": 8, + "theme": "Customer Service Questions", + "context": "Providing great customer service really just requires caring about people and trying to always make things better than you found it.\n- Our communities are better served when they have people that are willing to sacrifice their time and energy.\n- I personally enjoy going to places and working with people that provide great customer service. I would only expect that to be the level of service provided by firefighters.\n- Potential Conclusions:\no You can’t train people to care and its important for the fire service to hire people who innately have a desire to go the extra mile. It has to be in their DNA.\no I know that _____ Fire has done a great job finding lots of those types of people and they constantly work towards fostering that characteristic in everyone brought into the organization.\no Firefighters go above and beyond every shift. Its our job to serve the community and protect life, property" + }, + { + "id": 9, + "theme": "Successful and Unsuccessful Team Questions", + "context": "Teamwork is necessary to assist in overcoming emergencies. Especially expanding ones. I understand how chain of commands works and the importance of monitoring the span of control as well.\n- Great teamwork creates synergy in the workplace and makes environments happier, healthier, and safer.\n- There is no “I†in team.\n- All tasks are important no matter how big or small it may seem.\n- Great teams are built by people that are committed to training and knowing their roles well.\n- Need to train in order to create muscle memory and prevent “skills fadeâ€\n- Potential Conclusions:\no I know that Firefighting is a team sport and that _____ Fire does a great job in fostering that camaraderie.\no I have seen the _____ Fire team play in _____ tournament and know that you guys applaud crews bonding over meals at the station.\no I really appreciate the fact that you allow crews to train together and share insights learned across the department so that everyone gets better all the time.\no Include stats and figures, following SOPs and safety protocols into the answer" + }, + { + "id": 10, + "theme": "Disagree with a Supervisor Questions", + "context": "Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\n- I always recommend doing them in a private and non-confrontational manner\n- With a focus on finding acceptable solutions that can be implemented effectively.\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\n- Potential Conclusions:\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\no _____ Fire works hard to minimize the number of disagreements in the workplace." + }, + { + "id": 11, + "theme": "Rule Bending", + "context": "I do not bend rules that jeopardize health and safety or rules that test my ethics and morality.\n- I know that the fire service has that same perspective.\n- Therefore, all organizations need to have rules and all people in those organizations need to know them.\n- This is why there are internal SOPs, OHSA, HTA, Fire Code, Criminal Code etc.\n- Potential Conclusions:\no I know that _____ Fire has a robust SOP package, and it is part of the training process for every new hire to go through them and get schooled up on the importance of them.\no The onus is on me to spend time learning the ins and outs of this organization if I am blessed with the opportunity to work here.\no Firefighters need to be rule followers. It is an inherently dangerous job and freelancing has no part o." + }, + { + "id": 12, + "theme": "Integrity Challenge Questions", + "context": "Integrity is the cornerstone of the fire service profession, guiding every action and decision.\n- Firefighters are entrusted with public safety, making it imperative to uphold the highest ethical standards.\n- In the fire service, we are governed by regulations such as the NFPA standards and the Ontario FPPA, which mandate strict compliance to ensure safety and well-being.\n- These guidelines underscore the need for transparency and ethical conduct in all our actions.\n- Potential Conclusions:\no Integrity is not just a personal attribute; it is a professional necessity that ensures the effectiveness and reliability of our fire service operations.\no When faced with an integrity challenge, it is essential to remain steadfast in ethical principles, even under pressure.\no This experience reinforced my commitment to the values of the fire service and highlighted the importance of fostering a culture where integrity is paramount.\no By upholding these standards, we not only protect ourselves and our colleagues but also maintain the trust and confidence of the communities we serve." + }, + { + "id": 13, + "theme": "Taking a Shortcut at work", + "context": "I believe in having strong work ethic. I was raised that way and my work experience to date proves that…\n- I definitely do not take shortcuts around things that compromise health and safety or my ethics and morality.\n- I never take shortcuts that compromise the health and safety of myself or others, or that challenge my ethical and moral values.\n- I believe that the fire service shares this same perspective, prioritizing safety, ethics, and morality above all else.\n- In my view, all organizations should establish clear rules, and it is essential for every member of those organizations to be aware of and follow these rules.\n- This is why organizations have internal Standard Operating Procedures (SOPs), Occupational Health and Safety Act (OHSA) guidelines, Highway Traffic Act (HTA) regulations, Fire Codes, and even the Criminal Code when necessary.\n- Potential Conclusions:\no I'm aware that at _____ Fire, they have a comprehensive set of Standard Operating Procedures (SOPs) that are diligently followed. During my training, I learned about the critical importance of these procedures and the reasons for adhering to them.\no If I were fortunate enough to join this organization, I understand that it would be my responsibility to thoroughly acquaint myself with its rules and procedures. I'm committed to investing the necessary time and effort to ensure I comply with them.\no In firefighting, there's no room for shortcuts. It's an inherently perilous job and deviating from established procedures can jeopardize lives. Rules are not just guidelines but safeguards that protect everyone and ensure a safe return from each mission." + }, + { + "id": 14, + "theme": "Delivering Difficult Messages", + "context": "I do not shy away from the responsibility of delivering difficult messages when necessary, even though it may be uncomfortable. My commitment to honesty and ethical conduct remains unwavering.\n- I believe that the fire service, like any responsible organization, understands the importance of addressing challenging issues head-on, which aligns with my perspective on this matter.\n- In all organizations, there should be clear protocols and guidelines for delivering difficult messages effectively and sensitively, ensuring that the message is conveyed while respecting the dignity and feelings of the recipients.\n- This is why organizations often have established procedures and communication guidelines to handle such situations professionally and ethically.\n- Potential Conclusions:\no I'm aware that at _____ Fire, they prioritize open and honest communication. During my training, I learned about their approach to delivering difficult messages and the importance of doing so with empathy and professionalism.\no If I were part of this organization, I would understand that delivering difficult messages might be a part of my role. I would be committed to following their established protocols and guidelines for addressing such situations.\no In firefighting and similar high-stakes professions, effective communication, even in challenging circumstances, can be a matter of life and death. The rules and procedures in place are not just about following a script but ensuring that messages are conveyed in a way that respects the emotions and well-being of all involved parties." + }, + { + "id": 15, + "theme": "Not Following SOPs/SOGs", + "context": "I have never deviated from established SOPs at work, as doing so can compromise safety, ethical standards, and the integrity of the organization.\n- I understand that the fire service, like any responsible organization, places a high value on adherence to SOPs, which is consistent with my perspective.\n- In every organization, it's crucial to have clear and well-documented SOPs that every member understands and follows. This ensures consistency, safety, and ethical conduct.\n- This is why organizations implement internal SOPs and adhere to external regulations like OHSA, HTA, and Fire Codes to maintain high standards of operation.\n- Potential conclusions:\no I'm aware that at _____ Fire, strict adherence to SOPs is fundamental to their operational success. During my training, I gained a deep appreciation for the importance of following these procedures and the consequences of not doing so.\no If I were to become part of this organization, I would fully understand the gravity of following SOPs. I would uphold these standards and would actively seek training and support to ensure compliance.\no In firefighting and similar high-risk professions, disregarding SOPs is simply not an option. These procedures are in place to protect lives and property. Any deviation can have serious consequences, and rule adherence is non-negotiable." + }, + { + "id": 16, + "theme": "Continuous Improvement", + "context": "Continuous improvement is about striving to be better every day, both as an individual and as part of a team.\n- I believe that the fire service embodies this concept by constantly evolving through training, adopting new technologies, and learning from past experiences.\n- Reflecting on one's performance and seeking feedback are essential components of continuous improvement, as they help identify strengths and areas for growth.\n- Staying updated with new firefighting techniques, equipment, and regulations is crucial for maintaining effectiveness and safety in the field.\n- Potential Conclusions:\no I've seen how ______ Fire prioritizes ongoing training and professional development to ensure its firefighters remain at the forefront of the profession. I look forward to being part of an organization that values growth and innovation.\no During my station visit, I was impressed by the emphasis on learning and improvement at ______ Fire. That environment aligns perfectly with my personal commitment to always better myself and support my team in doing the same.\no I believe continuous improvement is not just about improving skills but also about fostering a culture where everyone strives to do better. At ______ Fire, I’m eager to contribute to that culture by embracing challenges, seeking feedback, and pursuing opportunities for growth." + }, + { + "id": 17, + "theme": "Handling Sensitive Information", + "context": "Firefighters are often entrusted with sensitive information, whether it pertains to medical calls, emergency incidents, or personal details about community members.\n- Maintaining confidentiality and discretion is critical for preserving trust and ensuring the dignity of individuals involved.\n- Handling sensitive information responsibly requires understanding and adhering to organizational policies, as well as exercising sound judgment.\n- Respecting privacy is a key component of professionalism, especially in a role as visible and impactful as firefighting.\n- Potential Conclusions:\no I understand that ______ Fire has clear guidelines and training around handling sensitive information. I respect and appreciate the importance of these protocols and would adhere to them without compromise.\no If given the opportunity to join ______ Fire, I would uphold the highest standards of confidentiality and discretion, ensuring that sensitive information is treated with the respect it deserves.\no Handling sensitive information with care is essential to maintaining the trust of the community and the integrity of the fire service. I’m committed to embodying these values and ensuring that all information is managed professionally and ethically." + }, + { + "id": 18, + "theme": "Solving a Problem", + "context": "I believe problem-solving is one of the most valuable skills in the fire service, as it often determines the success or failure of a critical situation.\n- Effective problem-solving requires a clear assessment of the situation, evaluating available resources, and making informed decisions quickly.\n- Firefighting often involves scenarios where unexpected challenges arise, and the ability to stay calm and address issues methodically is essential.\n- Collaboration is a significant part of problem-solving, as no one firefighter has all the answers. Solutions come from teamwork and leveraging everyone's strengths.\n- Potential Conclusions:\no I understand that ______ Fire emphasizes critical thinking and problem-solving in their training programs. During my training, I honed these skills and learned how to approach challenges systematically and effectively.\no If I were part of ______ Fire, I would actively apply my problem-solving abilities in both emergency and non-emergency situations, ensuring I work collaboratively with my team to find the best outcomes.\no Solving problems in firefighting goes beyond emergencies; it's about addressing challenges proactively, whether it's equipment maintenance, community outreach, or operational efficiency. I'm committed to contributing to this problem-solving culture at ______ Fire." + }, + { + "id": 19, + "theme": "Challenge Questions", + "context": "Life is full of challenges. It is important for firefighters to be the type of people that take those challenges head on and constantly work to find ways to overcome them.\n- Grit, persistence, creative problem solving, and strong mental health are the keys to overcoming challenges.\n- Life can change in a second. Its important to be adaptive and flexible.\n- Potential Conclusions:\no And I am certain that ______ Fire works very hard to meet every challenge and then overcome them.\no I think about how you guys handled the ________ situation\no or the recent fire at _______\no and as an outsider looking in, I was thoroughly impressed with the way the department handled it." + } +] \ No newline at end of file diff --git a/notebooks/conversations.json b/notebooks/conversations.json new file mode 100644 index 0000000..65ce505 --- /dev/null +++ b/notebooks/conversations.json @@ -0,0 +1,332 @@ +{ + "user123": { + "resume": "Resume [Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet\u2019s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue \u2013 Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue \u2013 Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue \u2013 Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 \u2013 Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot\u2019s Bay, ON 2023 \u2013 Present \\n\u2022 Member of Muskoka Lake\u2019s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n\u2022 Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n\u2022 Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n\u2022 Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n\u2022 Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n\u2022 Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n\u2022 Required to constantly use problem solving, stress management, communication , and team working skills. \\n\u2022 Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 \u2013 Present \\n\u2022 Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka\u2019s. \\n\u2022 Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n\u2022 Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n\u2022 Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n\u2022 Ensures compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\n '), Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n\u2022 Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n\u2022 Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n\u2022 Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n\u2022 Functioned with team members from other departments and trained new hires about course procedures. \\n\u2022 Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 \u2013 2022 \\n\u2022 Member of the city\u2019s crew tasked with keeping municipal properties and public spaces in great condition. \\n\u2022 Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n\u2022 Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n\u2022 Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n\u2022 Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n\u2022 Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n\u2022 Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n\u2022 Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n\u2022 Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n\u2022 Ensured compliance with the Occupational Health and Safety Act \u2013 Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 \u2013 2020 \\n\u2022 Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n\u2022 Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n\u2022 Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n\u2022 Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n\u2022 Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 \u2013 2016 \\n\u2022 Played as a Forward and served as Assistant Captain for three years on the Varsity Women\u2019s Hockey Team. \\n\u2022 Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n\u2022 Travelled to different universities serving as an ambassador for the school at various community events. \\n\u2022 Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n\u2022 Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n\u2022 Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 \u2013 Present \\n\u2022 Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 \u2013 Present \\n\u2022 Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n\u2022 Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 \u2013 Present \\n\u2022 Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 \u2013 Present \\n\u2022 Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n\u2022 Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n\u2022 Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]", + "theme": { + "id": 1, + "theme": "Disability Questions", + "context": "Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person\u2019s well-being.\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\n- Potential Conclusions:\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up" + }, + "messages": [ + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Hi Erika! Let's start preparing your responses for the interview. Can you tell me about a time when you had to deliver a difficult message to a team member or during a situation related to your firefighting volunteer work?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:16:49.474173" + }, + { + "role": "human", + "content": "hi", + "timestamp": "2025-01-17T23:16:56.514187" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Hi Erika! I thought we were preparing for your interview. Is there a specific topic or theme you're more comfortable starting with, or do you want to continue discussing delivering difficult messages?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:16:57.945261" + }, + { + "role": "human", + "content": "let us atrt with current theme", + "timestamp": "2025-01-17T23:17:34.742492" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Great! Let's focus on the current theme. Can you tell me about a situation during your firefighting volunteer experience where you faced a significant challenge? What was the challenge, and how did you handle it?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:17:36.006645" + }, + { + "role": "human", + "content": "my boss said i did not do last operation correctly and then was annoyed and reportedc me to senioyur officer, id di not take oitm personally but what id di was to lear n from t he situal tiona d make things good", + "timestamp": "2025-01-17T23:18:28.387057" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That sounds like a valuable experience. How did you approach the situation with your boss after receiving that feedback? What specific actions did you take to ensure you improved in the future?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:18:29.420293" + }, + { + "role": "human", + "content": "i just went to him perosnally and ap[olified and mae de him know i will improve", + "timestamp": "2025-01-17T23:19:07.742505" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's a great approach! Personal communication and taking responsibility show maturity and professionalism. Can you share any specific steps you implemented afterward to ensure you improved in that area or avoided similar issues in the future?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:19:08.739362" + }, + { + "role": "human", + "content": "i took up a course to learn more and the next operation was better ", + "timestamp": "2025-01-17T23:19:40.902476" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's fantastic! Taking the initiative to improve through a course shows dedication to personal and professional growth. After implementing what you learned in the course, how did your boss or team respond to your improvement during the next operation?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:19:42.507827" + }, + { + "role": "human", + "content": "they were quite happy", + "timestamp": "2025-01-17T23:20:06.469033" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's wonderful to hear! Receiving positive feedback from your boss and team must have felt rewarding after putting in the effort to improve. Now, reflecting on that situation, what did you learn about yourself and your ability to handle challenges in a team setting?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:20:07.840809" + }, + { + "role": "human", + "content": "i strive well", + "timestamp": "2025-01-17T23:20:23.081544" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's a powerful insight! Recognizing that you strive well under pressure and challenges is important for personal growth. How do you think this experience and the lessons you learned can apply to a firefighting role, particularly in a high-performance team environment?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:20:24.810726" + }, + { + "role": "human", + "content": "it will work please", + "timestamp": "2025-01-17T23:20:42.193414" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Absolutely! Your ability to strive well under pressure will be a great asset in firefighting, especially in high-stress situations. Let's move on to the next aspect. Can you share a time when you had to work closely with a team to solve a problem during your firefighting experience? What was the situation, and what did you contribute to the solution?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:20:44.533898" + }, + { + "role": "human", + "content": "it will help in a long term", + "timestamp": "2025-01-17T23:21:09.433297" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's a great point! Long-term growth and learning are essential, especially in such a critical field. Now, let's dive into another scenario. Can you recall an instance where you had to adapt quickly to a change during a firefighting operation? What was the situation, and how did you handle the adaptation?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:21:11.337163" + }, + { + "role": "human", + "content": "by learning from experince ", + "timestamp": "2025-01-17T23:21:27.244576" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Learning from experiences is key, especially in firefighting where situations can change rapidly. Can you provide a specific example of a time when you had to adapt quickly during an operation? What was the situation, and what adjustments did you make in your approach?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:21:28.940375" + }, + { + "role": "human", + "content": "i can not rmeber please", + "timestamp": "2025-01-17T23:21:47.523011" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"No problem at all! We can skip that for now. Let's shift gears a bit. Can you tell me about a time when you were a part of a successful team during your firefighting experience? What made the team successful, and what was your role in it?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:21:50.110819" + }, + { + "role": "human", + "content": "let us end the conersation please", + "timestamp": "2025-01-17T23:22:12.003986" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Of course! I'm glad we could work together on your interview preparation. If you need to revisit any topics or want to practice again, feel free to reach out. Good luck with your interview, Erika! You've got this!\",\n \"end\": \"yes\"\n}\n```", + "timestamp": "2025-01-17T23:22:14.000480" + }, + { + "role": "human", + "content": "thanks", + "timestamp": "2025-01-17T23:22:27.276870" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"You're welcome! If you have any more questions in the future or need further assistance, don't hesitate to ask. Good luck again with your interview!\",\n \"end\": \"yes\"\n}\n```", + "timestamp": "2025-01-17T23:22:28.868397" + }, + { + "role": "human", + "content": "thanks", + "timestamp": "2025-01-17T23:22:41.523713" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"You're welcome! If you need any more help or have questions in the future, feel free to reach out. Good luck with everything!\",\n \"end\": \"yes\"\n}\n```", + "timestamp": "2025-01-17T23:22:43.368386" + }, + { + "role": "ai", + "content": "Let's focus on the Customer Service theme first. Can you tell me about a time when you provided exceptional customer service, perhaps in your role as a firefighter or while working at Starbucks? What was the situation like?", + "timestamp": "2025-01-17T23:47:17.049827" + }, + { + "role": "human", + "content": "it was awesome , evry customer liked me", + "timestamp": "2025-01-17T23:47:51.563259" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's great to hear! It sounds like you had a positive impact on your customers. Can you share a specific example of a situation where you went above and beyond to ensure a customer had a great experience?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:47:52.825807" + }, + { + "role": "human", + "content": "i always asked customer what ever they want in details anmd thye kloved it", + "timestamp": "2025-01-17T23:48:31.811670" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"That's an excellent approach! Paying attention to detail and proactively asking customers what they need is crucial for great service. Can you tell me about a specific interaction where your attention to detail made a difference for a customer?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:48:36.513427" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-17T23:48:48.495915" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems you did not respond. If you're comfortable, let's continue discussing your customer service experiences. Can you recall a specific situation where your efforts were particularly appreciated by a customer?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:48:51.398001" + }, + { + "role": "human", + "content": "HI", + "timestamp": "2025-01-17T23:50:34.006993" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Hi! How can I assist you today? Are you ready to continue preparing for your firefighter interview?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:50:36.082073" + }, + { + "role": "human", + "content": "YES", + "timestamp": "2025-01-17T23:50:57.859563" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Great! Let's pick up where we left off. Can you share an example of a time you faced a challenge in your firefighting volunteer work? What was the situation, and how did you handle it?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:50:59.885961" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-17T23:51:16.884390" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems you've not responded. If you'd like to continue focusing on your interview preparation, can you tell me about a challenge you faced during your firefighting experience and how you managed it?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:51:19.305404" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-17T23:51:24.519115" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"I see you haven\u2019t responded. If you need more time or want to discuss a different aspect of your interview preparation, just let me know! Are there any specific topics you\u2019d like to cover?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:51:27.327605" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-17T23:52:17.463434" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems we have not connected in a while. If you're ready to continue your interview preparation, or if there's anything specific you'd like to focus on, please let me know!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:52:20.311367" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-17T23:52:24.546166" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"I see you may not be ready to continue right now. Whenever you're ready to resume or if you have any questions, feel free to reach out. I'm here to help!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-17T23:52:28.179002" + }, + { + "role": "human", + "content": "dsqfg", + "timestamp": "2025-01-18T00:12:57.202532" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems there might have been a typing error. If you have specific questions or topics to cover regarding your interview preparation, please share, and I'll be glad to assist!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:13:01.356215" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:07.083211" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"I see you're not responding right now. Whenever you're ready to continue, just let me know. I'm here to support you with your interview preparation!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:13:10.104803" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:11.615328" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems you might need more time. If you have any questions in the future or want to continue preparing for your interview, feel free to reach out anytime!\",\n \"end\": \"yes\"\n}\n```", + "timestamp": "2025-01-18T00:13:15.479562" + }, + { + "role": "human", + "content": "end th 3 conversation please", + "timestamp": "2025-01-18T00:13:27.966521" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Of course! If you need to return for more practice or have questions later, feel free to reach out. Good luck with your interview!\",\n \"end\": \"yes\"\n}\n```", + "timestamp": "2025-01-18T00:13:31.563052" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:34.163123" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Hi Erika! Let's start preparing your responses for the interview. Can you tell me about a time when you had to deliver a difficult message to a team member or during a situation related to your firefighting volunteer work?\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:13:38.785281" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:40.255539" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems there hasn\u2019t been a response. If you'd like to continue with your interview preparation, feel free to share a topic or question you'd like to discuss!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:13:44.697883" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:50.758360" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"Hi there! If you're ready to dive back into your interview preparation, just let me know what aspect you'd like to focus on today!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:13:54.959609" + }, + { + "role": "human", + "content": "", + "timestamp": "2025-01-18T00:13:57.787439" + }, + { + "role": "ai", + "content": "```json\n{\n \"message\": \"It seems there hasn\u2019t been a response. If you have any specific topics or questions in mind regarding your interview preparation, please share, and I\u2019ll be happy to assist!\",\n \"end\": \"no\"\n}\n```", + "timestamp": "2025-01-18T00:14:06.694390" + } + ] + } +} \ No newline at end of file diff --git a/notebooks/output.pdf b/notebooks/output.pdf new file mode 100644 index 0000000..686f568 --- /dev/null +++ b/notebooks/output.pdf @@ -0,0 +1,112 @@ +%PDF-1.4 +%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com +1 0 obj +<< +/F1 2 0 R /F2 3 0 R +>> +endobj +2 0 obj +<< +/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font +>> +endobj +3 0 obj +<< +/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font +>> +endobj +4 0 obj +<< +/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 9 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +5 0 obj +<< +/Contents 11 0 R /MediaBox [ 0 0 612 792 ] /Parent 9 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +6 0 obj +<< +/Contents 12 0 R /MediaBox [ 0 0 612 792 ] /Parent 9 0 R /Resources << +/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] +>> /Rotate 0 /Trans << + +>> + /Type /Page +>> +endobj +7 0 obj +<< +/PageMode /UseNone /Pages 9 0 R /Type /Catalog +>> +endobj +8 0 obj +<< +/Author (\(anonymous\)) /CreationDate (D:20250120220756+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20250120220756+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) + /Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False +>> +endobj +9 0 obj +<< +/Count 3 /Kids [ 4 0 R 5 0 R 6 0 R ] /Type /Pages +>> +endobj +10 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1471 +>> +stream +Gat=+gMRrh&:O:SbZil>G-rjRP4K==Nf+fpi[!5#.*rcf40)r3,o)Rn7K*&m\JN5e9I1&I!jp.oR5=$MN"QuT-OJ\C!k?M5\).ii;TK29-5R?:*oT:Eq0J42/#P1jNr3@42@@dSnq=FtrCOB*U/TM>'RrS-:+rcRl"ua(C%fUG]DL4Lp0iDkqsaBBr^CEjU_k8_I+OQV*jhY^6HjXQ<(L._$X7"-aYo:VK+*XQL;imebtm^]oWN:^$-RYUh4`I"8PN[F"m'#IiUWIE]SXEk`ifa%NbUN6MoWj`q*'p)I?e5jUAR'#!%PMk-Tq#8kYKaK3%'3S7&Y#`U!Ws5H)YS;9nqoq5-qge]iA_s"]#Bc_E&%SdW#ZUN;!&._Eb8jNFE<#YN`/cSr\-/amaP]%W[Jc95RPo@*SHRo.u9L#*FNMG1FPK.'[Q?/GCfgm_`!pfidM]"L?8jM&WgAoV:L1eXSA+M@+VaM\M'@V.0TRpWD%kpOSK!eLT7klRTo(+=C7\'Lgs8O@X1l6(Fpb,B0h;=B;*LKn>"X0oEt3]Z-Tc8t-Pp[%PbmD!g:OnqmO_*0?.!I^H=Q@YHm=^n'&2F@PuM@4PS#.L`W*a3H+]^+9CJaJ$n@FL=s8!\l]ER"Jel7i+acVDC!V[OW+O,1fSkjn2260,_*W6\""h)i0%!1?Cra0Ws]Qcgb`e5gFr.l3+kSROVo2E6]/foJc/TFb!9JXRk*%g3bP_:+6JA?cl90@KjCQc,lI8Pls)@oB]#AQt:Obt6;X/">b@\>(97q>)s@>i8e:JZW3/Cq(3@ini>X`>_\o+;u9W6;E8M7;cHoZ4UBo!p(k^nnPi3k_L'HV1baY[Jk*uOP;)jM1i?J$P50/FLZ-glfrF2Z+haiS`nk2i4jnMejQ4BVli:ZaK,Q'b0P=1*\5sV)kUfF%[AZZ(?/.A1tU`YL*;W_o][hBH=G~>endstream +endobj +11 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1371 +>> +stream +Gat=+968iG&AJ$ClnR`QY"6aAge/tgdn+179q(S($OA@V<$4Hd+\);#?%=,9,n:W)1uj^3$Jb*Thl\_:dOU6*GmEhc!PeW%6'al86ajR26#d.uMMq@ilu;.4#1f8$h+ZFdnX=/Ek\Jk!;RV=SULWljQuL-)[nOVEH`5;3,>&(C[RVrb_81s<@;'YnULb2=ZP&Q]#-gPW?kBK;CCXMA&rQ^^p]XuGfTg-Cnj]Q)I*k22%+_.e?+1QIenLs,B5^.7CdIP_80&SNHlVbGB90?>t:+p"Ib]s`$X[t+sA"5pj/I<88ebm^aC([/Z'Hm_b\IBrk%TKlsZDB(a3^]8nr+&T00,*`%_Q]Y\e"Cho6;iPb)k@h%+T+-,Us?6P>&,>C81s>PU1@-=5b]pW$l';NDSN08%=6_Pck:.8G+DtC`:@ZHlR)"$#38g?Ibdc+:kK-m%Zk'-m]l[a1Kji-D>dI"3?JQq:ItF+b_/D%r\aIO\*VFmf%/Nq$O@-#'K,r>l^cH)%Jho3DdeD,hG-.nk$DFsf]f)YRhcVGKmOEgbGG]HT+_XH>(MVZo[X+Vo)@%6[A-Q5j@=2bJH\e@&l8a0KI)a72msfTq6%he4?RnERBk9hUt(4Q_f\k-nu:oV&X*G*/5\fH7%gP?'0jS?:<9Zi_OZC:BUOC0g2\NqVf"3>s%/QipT4k>p8UkN"W$`!*BDgtQRWc`7na/Hn[V+cM(?iKr50#Su$Y3Vpj_WnoB#f>d#SRL8/FM6NXm6ATmdK$9N>HP?^aP6cM7RU*(!tBtDZ)&`]<#2Y!d3AUHrY>b'H2VY.t~>endstream +endobj +12 0 obj +<< +/Filter [ /ASCII85Decode /FlateDecode ] /Length 1226 +>> +stream +GatU29lo&I&A@sBm&atL9gr3j4M>91:HL_LFdm=sQWtYP8YQ7e('(K+htI-ceRWEI'6Q-p,m]7^^5p5K[)/S/YHfDLWMCVb.B$?I=];SNZ_?r@IP.i'^+)l>GIM\#>@TJ?85[oE>qj`g>h885\B/)PB$]s8AVZY>Y<-jY\,#f)1mu]"!%]kVZ[aSj!!]Z.mY2lOKT()DIk=C\W60"Y)_d?.B:X.O.s4#">T>@ZqJ=Wq8irG:]ab>2!!d9YjW-ReBFu;45SAaWb)oZH/YN,lrK8gn\d$6[5dQK/s"+G;cZ6d01PT,r[fW$2Sar;.2jY;7hMX)\:8J2@FMO]D6d/9)'ebflik,^k-+keiF?q!`,7%#3gL#P(CH*O"@LG@NR`C*\+>GGdZ.%eYJHrJt*iTFk5hld"\*IH]TnCQYh)?2dAh\47N"Or74WYhA>Ls,K_2?ZD.,^7X\89BNu#HYfEY'%`Z0>Y5`MZMSfB!T%I<\g8">ZE9.#D`&u(fd#MiagKd65S&$iC08"E3$YY[6UOR%jk5+5jM,D%&E\L-0k5Kk2VX19?@qm2rLh%2TQC6QNhZ?^C=da]1*jLsh]M'(d[C0.T%$=<_As3FpZui,`Tj-t>W?qq49Oo-ebMq-P`A@XU>aW!U_s$Zq'(D-hUggWc-7A9lH`WsSYSVg"QUkNWseRqK:TIU^`GbqOtbJqEQZf2Ng6Rq]NERQ[GlLMkIj#R1.\IR5W;Bgk%%R'/'lYb[%8T%qL=/'^GHluFhMogL#`LIm4MpgR#%@pKkaLsHcQg^I;/i.]&gc6Zqk"i6D-/+R5]X7)pLNMaOR.@*lpE[lnK4#*$mT`G:7fIbl5enEfb'S6D\K(%@&4#89hiM:X_h@RO@;]taMW=&RdA:Q6lT4V3`,Sg3-L)sBRqVR1bMg"9e($[sf5F@~>endstream +endobj +xref +0 13 +0000000000 65535 f +0000000073 00000 n +0000000114 00000 n +0000000221 00000 n +0000000333 00000 n +0000000527 00000 n +0000000721 00000 n +0000000915 00000 n +0000000983 00000 n +0000001266 00000 n +0000001337 00000 n +0000002900 00000 n +0000004363 00000 n +trailer +<< +/ID +[<4b0a13e77a14658d2c9c7ba2786bbc6e><4b0a13e77a14658d2c9c7ba2786bbc6e>] +% ReportLab generated PDF document -- digest (http://www.reportlab.com) + +/Info 8 0 R +/Root 7 0 R +/Size 13 +>> +startxref +5681 +%%EOF diff --git a/notebooks/test.ipynb b/notebooks/test.ipynb new file mode 100644 index 0000000..72f1e86 --- /dev/null +++ b/notebooks/test.ipynb @@ -0,0 +1,3120 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from spire.doc import Document, FileFormat\n", + "from langchain_community.document_loaders import PyPDFLoader\n", + "\n", + "def convert_word_to_pdf(doc_path: str) -> str:\n", + " \"\"\"\n", + " Convert a .doc or .docx file to PDF using Spire.Doc.\n", + " \n", + " Args:\n", + " doc_path (str): The path to the .doc or .docx file.\n", + "\n", + " Returns:\n", + " str: The path to the converted PDF file.\n", + " \"\"\"\n", + " pdf_path = os.path.splitext(doc_path)[0] + '.pdf'\n", + " \n", + " # Create a Document object\n", + " document = Document()\n", + " # Load the Word document\n", + " document.LoadFromFile(doc_path)\n", + " # Save as PDF\n", + " document.SaveToFile(pdf_path, FileFormat.PDF)\n", + " document.Close()\n", + " \n", + " return pdf_path\n", + "\n", + "def load_document(file_path: str):\n", + " \"\"\"\n", + " Utility function to load a PDF, DOCX, or DOC file by first converting it to PDF.\n", + "\n", + " Args:\n", + " file_path (str): The path to the file to load.\n", + "\n", + " Returns:\n", + " List[Document]: A list of Document objects representing the contents of the file.\n", + " \"\"\"\n", + " extension = os.path.splitext(file_path)[1].lower()\n", + " \n", + " if extension in ['.doc', '.docx']:\n", + " # Convert .doc or .docx to PDF first\n", + " pdf_path = convert_word_to_pdf(file_path)\n", + " loader = PyPDFLoader(pdf_path)\n", + " elif extension == '.pdf':\n", + " loader = PyPDFLoader(file_path)\n", + " else:\n", + " raise ValueError(f\"Unsupported file type: {extension}. Only .pdf, .docx, and .doc are supported.\")\n", + " \n", + " return loader.load()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import FAISS\n", + "from langchain_openai import OpenAIEmbeddings\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", + "from langchain.schema import Document\n", + "import json\n", + "import os\n", + "\n", + "# Load questions and themes\n", + "question_path = \"../data/config_files/questions.json\"\n", + "theme_path = \"../data/config_files/theme_context.json\"\n", + "with open(question_path, \"r\") as f:\n", + " questions = json.load(f)\n", + "\n", + "with open(theme_path, \"r\") as f:\n", + " themes = json.load(f)\n", + "\n", + "def load_document(file_path: str):\n", + " extension = os.path.splitext(file_path)[1].lower()\n", + " \n", + " if extension in ['.doc', '.docx']:\n", + " # Convert .doc or .docx to PDF first\n", + " pdf_path = convert_word_to_pdf(file_path)\n", + " loader = PyPDFLoader(pdf_path)\n", + " elif extension == '.pdf':\n", + " loader = PyPDFLoader(file_path)\n", + " else:\n", + " raise ValueError(f\"Unsupported file type: {extension}. Only .pdf, .docx, and .doc are supported.\")\n", + " \n", + " return loader.load()\n", + "\n", + "# Create text splitter\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=100, chunk_overlap=50\n", + ")\n", + "\n", + "# Load and split resume document\n", + "docs = load_document('../upload_folder/Resume_-_Erika_Kiviaho.pdf')\n", + "resume_splits = text_splitter.split_documents(docs)\n", + "\n", + "# Create vector store for resume\n", + "resume_vectorstore = FAISS.from_documents(\n", + " documents=resume_splits,\n", + " embedding=OpenAIEmbeddings(),\n", + ")\n", + "resume_retriever = resume_vectorstore.as_retriever()\n", + "\n", + "# Prepare questions for vectorDB - Convert dictionary to Document objects\n", + "questions_docs = [\n", + " Document(\n", + " page_content=str(value),\n", + " metadata={\"question_id\": key}\n", + " )\n", + " for key, value in questions.items()\n", + "]\n", + "questions_splits = text_splitter.split_documents(questions_docs)\n", + "\n", + "# Create vector store for questions\n", + "questions_vectorstore = FAISS.from_documents(\n", + " documents=questions_splits,\n", + " embedding=OpenAIEmbeddings(),\n", + ")\n", + "questions_retriever = questions_vectorstore.as_retriever()\n", + "\n", + "from langchain.tools.retriever import create_retriever_tool\n", + "\n", + "# Create retriever tool for resume\n", + "resume_retriever_tool = create_retriever_tool(\n", + " resume_retriever,\n", + " \"retrieve_resume_info\",\n", + " \"Search and return information from the user's resume.\"\n", + ")\n", + "\n", + "# Create retriever tool for questions\n", + "questions_retriever_tool = create_retriever_tool(\n", + " questions_retriever,\n", + " \"retrieve_questions_info\",\n", + " \"Search and return information about general questions.\"\n", + ")\n", + "\n", + "tools = [resume_retriever_tool, questions_retriever_tool]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Starting practice session for theme: Customer Service\n", + "I'll ask you several questions, then help create a STARTPOP response.\n", + "Type your responses when prompted, or 'quit' to end.\n", + "\n" + ] + }, + { + "ename": "TypeError", + "evalue": "StateGraph.add_edge() takes 3 positional arguments but 4 were given", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 196\u001b[0m\n\u001b[1;32m 193\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mll ask you several questions, then help create a STARTPOP response.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 194\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mType your responses when prompted, or \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mquit\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m to end.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 196\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m state \u001b[38;5;129;01min\u001b[39;00m \u001b[43mrun_theme_practice\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtheme\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresume_retriever\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mquestions_retriever\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[1;32m 197\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(state\u001b[38;5;241m.\u001b[39mmessages[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m], AIMessage):\n\u001b[1;32m 198\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mAssistant:\u001b[39m\u001b[38;5;124m\"\u001b[39m, state\u001b[38;5;241m.\u001b[39mmessages[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]\u001b[38;5;241m.\u001b[39mcontent)\n", + "Cell \u001b[0;32mIn[6], line 175\u001b[0m, in \u001b[0;36mrun_theme_practice\u001b[0;34m(theme, resume_retriever, questions_retriever)\u001b[0m\n\u001b[1;32m 172\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mrun_theme_practice\u001b[39m(theme: \u001b[38;5;28mstr\u001b[39m, resume_retriever, questions_retriever):\n\u001b[1;32m 173\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Runs a practice session for a specific theme\"\"\"\u001b[39;00m\n\u001b[0;32m--> 175\u001b[0m practice_bot \u001b[38;5;241m=\u001b[39m \u001b[43mcreate_practice_assistant\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtheme\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mresume_retriever\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mquestions_retriever\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 177\u001b[0m \u001b[38;5;66;03m# Initialize state\u001b[39;00m\n\u001b[1;32m 178\u001b[0m initial_state \u001b[38;5;241m=\u001b[39m PracticeState(\n\u001b[1;32m 179\u001b[0m messages\u001b[38;5;241m=\u001b[39m[\n\u001b[1;32m 180\u001b[0m SystemMessage(content\u001b[38;5;241m=\u001b[39m\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mStarting practice session for theme: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mtheme\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 183\u001b[0m theme\u001b[38;5;241m=\u001b[39mtheme\n\u001b[1;32m 184\u001b[0m )\n", + "Cell \u001b[0;32mIn[6], line 164\u001b[0m, in \u001b[0;36mcreate_practice_assistant\u001b[0;34m(theme, resume_retriever, questions_retriever)\u001b[0m\n\u001b[1;32m 161\u001b[0m workflow\u001b[38;5;241m.\u001b[39madd_node(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenerate_startpop\u001b[39m\u001b[38;5;124m\"\u001b[39m, generate_startpop)\n\u001b[1;32m 163\u001b[0m \u001b[38;5;66;03m# Add edges\u001b[39;00m\n\u001b[0;32m--> 164\u001b[0m \u001b[43mworkflow\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_edge\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mshould_continue\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcontinue_questions\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcontinue_questions\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 165\u001b[0m workflow\u001b[38;5;241m.\u001b[39madd_edge(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mshould_continue\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenerate_startpop\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenerate_startpop\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 166\u001b[0m workflow\u001b[38;5;241m.\u001b[39madd_edge(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mget_next_question\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprocess_response\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprocess_response\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mTypeError\u001b[0m: StateGraph.add_edge() takes 3 positional arguments but 4 were given" + ] + } + ], + "source": [ + "from typing import List, Dict\n", + "from pydantic import BaseModel, Field\n", + "from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "from langgraph.graph import StateGraph, END\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "\n", + "class PracticeState(BaseModel):\n", + " \"\"\"Tracks the state of the practice session\"\"\"\n", + " messages: List[BaseMessage] = Field(default_factory=list)\n", + " theme: str\n", + " questions_asked: int = 0\n", + " gathered_responses: List[str] = Field(default_factory=list)\n", + " ready_for_startpop: bool = False\n", + "\n", + "def create_practice_assistant(theme: str, resume_retriever, questions_retriever):\n", + " \"\"\"Creates a practice assistant for a specific interview theme\"\"\"\n", + " \n", + " model = ChatOpenAI(temperature=0.7, model=\"gpt-4-turbo-preview\")\n", + " memory = MemorySaver()\n", + "\n", + " # Core system prompt for question generation\n", + " QUESTION_PROMPT = \"\"\"You are an AI assistant helping prepare for a firefighter interview, focusing on the theme: {theme}.\n", + "\n", + " Resume Context:\n", + " {resume_context}\n", + "\n", + " Sample Questions for this Theme:\n", + " {questions_context}\n", + "\n", + " Previous Questions and Responses:\n", + " {conversation_history}\n", + "\n", + " Generate a focused question that:\n", + " 1. Relates to the candidate's background from their resume\n", + " 2. Aligns with the current theme\n", + " 3. Encourages STAR/STARTPOP format responses\n", + " 4. Builds on previous responses\n", + " 5. Helps gather material for a strong STARTPOP response\n", + "\n", + " Ask only ONE question and make it conversational and encouraging.\"\"\"\n", + "\n", + " # STARTPOP generation prompt\n", + " STARTPOP_PROMPT = \"\"\"Based on all the responses gathered during our practice session, let's create a strong STARTPOP response for the theme: {theme}\n", + "\n", + " Theme: {theme}\n", + " Collected Responses: {responses}\n", + " Resume Context: {resume_context}\n", + "\n", + " Create a polished STARTPOP response that:\n", + " 1. Uses the best examples from the practice session\n", + " 2. Incorporates relevant experience from the resume\n", + " 3. Follows the exact STARTPOP format:\n", + "\n", + " Situation:\n", + " - [Specific context and background]\n", + "\n", + " Task:\n", + " - [Clear objectives and responsibilities]\n", + "\n", + " Action:\n", + " - [Both potential negative approaches and chosen positive actions]\n", + "\n", + " Results:\n", + " - [Concrete outcomes with timeframes]\n", + "\n", + " Transitions:\n", + " - [Professional firefighting terminology]\n", + "\n", + " Personal Lessons:\n", + " - [Growth and self-awareness]\n", + "\n", + " Other People Observations:\n", + " - [Team and interpersonal insights]\n", + "\n", + " Professional Connection:\n", + " - [Direct firefighting career relevance]\"\"\"\n", + "\n", + " def get_next_question(state: PracticeState) -> dict:\n", + " \"\"\"Generates the next practice question\"\"\"\n", + " # Retrieve relevant context\n", + " resume_context = resume_retriever.invoke(state.theme)\n", + " questions_context = questions_retriever.invoke(state.theme)\n", + " \n", + " # Format conversation history\n", + " conversation_history = \"\\n\".join([\n", + " f\"Q: {state.messages[i].content}\\nA: {state.messages[i+1].content}\"\n", + " for i in range(0, len(state.messages)-1, 2)\n", + " if i+1 < len(state.messages)\n", + " ])\n", + "\n", + " # Generate question\n", + " response = model.invoke({\n", + " \"messages\": [\n", + " HumanMessage(content=QUESTION_PROMPT.format(\n", + " theme=state.theme,\n", + " resume_context=resume_context,\n", + " questions_context=questions_context,\n", + " conversation_history=conversation_history\n", + " ))\n", + " ]\n", + " })\n", + " \n", + " return {\"messages\": state.messages + [AIMessage(content=response.content)]}\n", + "\n", + " def process_response(state: PracticeState) -> dict:\n", + " \"\"\"Processes user's response and determines next steps\"\"\"\n", + " # Track the response\n", + " state.gathered_responses.append(state.messages[-1].content)\n", + " state.questions_asked += 1\n", + " \n", + " # Determine if ready for STARTPOP\n", + " ready_for_startpop = state.questions_asked >= 3\n", + " \n", + " return {\n", + " \"messages\": state.messages,\n", + " \"questions_asked\": state.questions_asked,\n", + " \"gathered_responses\": state.gathered_responses,\n", + " \"ready_for_startpop\": ready_for_startpop\n", + " }\n", + "\n", + " def generate_startpop(state: PracticeState) -> dict:\n", + " \"\"\"Generates final STARTPOP response\"\"\"\n", + " # Get final context\n", + " resume_context = resume_retriever.invoke(state.theme)\n", + " \n", + " # Generate STARTPOP\n", + " response = model.invoke({\n", + " \"messages\": [\n", + " HumanMessage(content=STARTPOP_PROMPT.format(\n", + " theme=state.theme,\n", + " responses=\"\\n\".join(state.gathered_responses),\n", + " resume_context=resume_context\n", + " ))\n", + " ]\n", + " })\n", + " \n", + " return {\n", + " \"messages\": state.messages + [AIMessage(content=response.content)],\n", + " \"ready_for_startpop\": True\n", + " }\n", + "\n", + " def should_continue(state: PracticeState) -> str:\n", + " \"\"\"Determines whether to continue questions or generate STARTPOP\"\"\"\n", + " if state.ready_for_startpop:\n", + " return \"generate_startpop\"\n", + " return \"continue_questions\"\n", + "\n", + " # Create workflow\n", + " workflow = StateGraph(PracticeState)\n", + " \n", + " # Add nodes\n", + " # Create workflow\n", + "\n", + "\n", + "# Add nodes\n", + " workflow.add_node(\"get_next_question\", get_next_question)\n", + " workflow.add_node(\"process_response\", process_response)\n", + " workflow.add_node(\"should_continue\", should_continue)\n", + " workflow.add_node(\"generate_startpop\", generate_startpop)\n", + "\n", + " # Add edges\n", + " workflow.add_edge(\"should_continue\", \"continue_questions\", \"continue_questions\")\n", + " workflow.add_edge(\"should_continue\", \"generate_startpop\", \"generate_startpop\")\n", + " workflow.add_edge(\"get_next_question\", \"process_response\", \"process_response\")\n", + " workflow.add_edge(\"process_response\", \"should_continue\", \"should_continue\")\n", + " workflow.add_edge(\"generate_startpop\", END, \"generate_startpop\")\n", + " \n", + " return workflow.compile()\n", + "\n", + "def run_theme_practice(theme: str, resume_retriever, questions_retriever):\n", + " \"\"\"Runs a practice session for a specific theme\"\"\"\n", + " \n", + " practice_bot = create_practice_assistant(theme, resume_retriever, questions_retriever)\n", + " \n", + " # Initialize state\n", + " initial_state = PracticeState(\n", + " messages=[\n", + " SystemMessage(content=f\"Starting practice session for theme: {theme}\"),\n", + " HumanMessage(content=\"I'm ready to practice this theme.\")\n", + " ],\n", + " theme=theme\n", + " )\n", + " \n", + " return practice_bot.stream(initial_state)\n", + "\n", + "# Example usage\n", + "if __name__ == \"__main__\":\n", + " theme = \"Customer Service\"\n", + " \n", + " print(f\"\\nStarting practice session for theme: {theme}\")\n", + " print(\"I'll ask you several questions, then help create a STARTPOP response.\")\n", + " print(\"Type your responses when prompted, or 'quit' to end.\\n\")\n", + " \n", + " for state in run_theme_practice(theme, resume_retriever, questions_retriever):\n", + " if isinstance(state.messages[-1], AIMessage):\n", + " print(\"\\nAssistant:\", state.messages[-1].content)\n", + " \n", + " if not state.ready_for_startpop:\n", + " print(\"\\nYour response:\")\n", + " user_input = input(\"> \")\n", + " if user_input.lower() == 'quit':\n", + " break\n", + " state.messages.append(HumanMessage(content=user_input))\n", + " \n", + " if state.ready_for_startpop and len(state.messages) > 0:\n", + " print(\"\\nPractice complete! Here's your STARTPOP response for this theme.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'id': 1,\n", + " 'theme': 'Disability Questions',\n", + " 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"},\n", + " {'id': 2,\n", + " 'theme': 'Leadership Skills Questions',\n", + " 'context': \"Leadership is not about having authority; it's about inspiring others to reach their full potential.\\n- Effective leaders lead by example, demonstrating integrity, accountability, and a commitment to teamwork.\\n- In the fire service, leadership is not confined to rank; every firefighter has the opportunity to lead and contribute to the success of the team.\\n- Adaptability and decisiveness are crucial qualities in leadership, especially in high-stress and rapidly changing environments.\\n- Leadership is also about fostering a culture of continuous learning and improvement, encouraging feedback, and promoting innovation.\\n- Potential Conclusions:\\no I've heard about the emphasis on leadership development within ______ Fire, and it's clear that the department values cultivating leaders at all levels. I'm eager to contribute to that culture and continue growing as a leader.\\no During my station visit, I observed how firefighters at ______ Fire take initiative and support each other, regardless of rank. That collaborative leadership approach is something I aspire to emulate and contribute to.\\no I've learned that leadership in the fire service is not just about giving orders; it's about empowering others, building trust, and fostering a sense of unity within the team. I'm excited about the opportunity to lead by example and positively influence my fellow firefighters at ______ Fire.\"},\n", + " {'id': 3,\n", + " 'theme': 'Conflict Questions',\n", + " 'context': 'Conflict is a huge problem in high performing teams.\\n- Creates a poisonous work environment, reduces efficiencies, and creates mental health issues.\\n- Those are serious issues and must be addressed as soon as they pop up.\\n- One of the best ways to address it through increasing the communication and giving people an opportunity to explain their opinions or viewpoints.\\n- I tend to think about the three T’s (teamwork, training and trust) and how important it is to fall back on those.\\n- Attempt to secure behaviour modification through voluntary compliance.\\n- Potential Conclusions:\\no I know that professionalism runs through the entire department here. ______\\no Firefighters are professional and committed to safe and respectful workplaces.\\no One thing about the fire service is that you all do a great job of communicating and creating a chain of command to help simplify complex problems\\no Its important to remember the values of the fire service and keep those in mind whenever conflicts arise.\\no Tie in stats and figures from your research on the department.'},\n", + " {'id': 4,\n", + " 'theme': 'Stress Questions',\n", + " 'context': 'My big takeaway is that stress is everywhere, and it affects everyone in different ways.\\n- The amount of mental health issues and stress levels are up exponentially with the community.\\n- Especially when you factor in the effects of COVID-19 and the lockdowns.\\n- That _________ situation made me realize that we must be supportive of one another and reduce the stigma.\\n- Potential Conclusions:\\no I know that the team members at _______ Fire are exposed to stressful situations on a regular basis, and it is critical that they be supportive to one another in order to maintain a strong team.\\no I have spoken to ______ about your mental health programs and can see that you really take the time to pour into each of your firefighter’s cup. I really admire that.\\no I looked into that _________ program that your department us'},\n", + " {'id': 5,\n", + " 'theme': 'Emergency Questions',\n", + " 'context': 'Emergencies can happen anywhere at anytime.\\n- Usually with little to no warning.\\n- During those times people fall back onto their training and most commonly practiced strategies.\\n- We need to ensure that our personnel are available and ready to answer the call whenever that happens in the community, and they are using the most effective strategies and techniques possible.\\n- Potential Conclusions:\\no I know that the expectation of _______ Fire is to train at least 2-3 hours per shift.\\no That works out to 14-21 hours per month. When you factor in running calls in between those training sessions there is a fair bit of opportunity for Firefighters to become very good at their jobs and be fully prepared.\\no Consistent commitment to training everything from the basics up to the complicated things 2-3 hours per shift is what makes the people on _____ Fire so good at their job.'},\n", + " {'id': 6,\n", + " 'theme': 'Mistake',\n", + " 'context': 'We all make mistakes. It is okay to make them. But it is not okay to not learn from them.\\n- Mistakes are just proof that you are trying your best.\\n- They are an opportunity for growth and for development.\\n- They are the things that help sharpen the knives in a drawer.\\n- The key is not to make the same mistake twice.\\n- Potential Conclusions:\\no I am certain that _______ Firefighters conduct regular follow-ups after calls.\\no Its important for everyone to check their ego and be accountable for the things they messed up on.\\no I know that Chief ______ promotes an open and transparent environment. He/She is not afraid to admit when they made a mistake. So, it is important for everyone in the department to follow suit.'},\n", + " {'id': 7,\n", + " 'theme': 'Cultural, Diversity, and Inclusion Questions',\n", + " 'context': 'Communities are becoming more and more diverse everyday. It is important for the Fire Service to recognize that.\\n- Steps can be taken every single day to create an environment that is inclusive and open to everyone regardless of their background, language, abilities, or self-identification.\\n- Public servants serve the public.\\n- No passing judgement on people. No racism, no homophobia, no misogyny.\\n- Treat everyone with respect and educate ourselves about the differences in our communities.\\n- Potential Conclusions:\\no ______ Fire is very professional and respectful. I have only seen and heard good things about how much of a concerted effort you are making to be more inclusive.\\no I spent some time looking at the Public Education pamphlets at station _____ and saw that they were offered in a bunch of different languages. That was amazing and I really think that shows the community how much you care about reducing the barriers to safety.\\no I spoke with _____ and learned about how enjoyable of an experience they have had working on your departmen'},\n", + " {'id': 8,\n", + " 'theme': 'Customer Service Questions',\n", + " 'context': 'Providing great customer service really just requires caring about people and trying to always make things better than you found it.\\n- Our communities are better served when they have people that are willing to sacrifice their time and energy.\\n- I personally enjoy going to places and working with people that provide great customer service. I would only expect that to be the level of service provided by firefighters.\\n- Potential Conclusions:\\no You can’t train people to care and its important for the fire service to hire people who innately have a desire to go the extra mile. It has to be in their DNA.\\no I know that _____ Fire has done a great job finding lots of those types of people and they constantly work towards fostering that characteristic in everyone brought into the organization.\\no Firefighters go above and beyond every shift. Its our job to serve the community and protect life, property'},\n", + " {'id': 9,\n", + " 'theme': 'Successful and Unsuccessful Team Questions',\n", + " 'context': 'Teamwork is necessary to assist in overcoming emergencies. Especially expanding ones. I understand how chain of commands works and the importance of monitoring the span of control as well.\\n- Great teamwork creates synergy in the workplace and makes environments happier, healthier, and safer.\\n- There is no “I†in team.\\n- All tasks are important no matter how big or small it may seem.\\n- Great teams are built by people that are committed to training and knowing their roles well.\\n- Need to train in order to create muscle memory and prevent “skills fadeâ€\\n- Potential Conclusions:\\no I know that Firefighting is a team sport and that _____ Fire does a great job in fostering that camaraderie.\\no I have seen the _____ Fire team play in _____ tournament and know that you guys applaud crews bonding over meals at the station.\\no I really appreciate the fact that you allow crews to train together and share insights learned across the department so that everyone gets better all the time.\\no Include stats and figures, following SOPs and safety protocols into the answer'},\n", + " {'id': 10,\n", + " 'theme': 'Disagree with a Supervisor Questions',\n", + " 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'},\n", + " {'id': 11,\n", + " 'theme': 'Rule Bending',\n", + " 'context': 'I do not bend rules that jeopardize health and safety or rules that test my ethics and morality.\\n- I know that the fire service has that same perspective.\\n- Therefore, all organizations need to have rules and all people in those organizations need to know them.\\n- This is why there are internal SOPs, OHSA, HTA, Fire Code, Criminal Code etc.\\n- Potential Conclusions:\\no I know that _____ Fire has a robust SOP package, and it is part of the training process for every new hire to go through them and get schooled up on the importance of them.\\no The onus is on me to spend time learning the ins and outs of this organization if I am blessed with the opportunity to work here.\\no Firefighters need to be rule followers. It is an inherently dangerous job and freelancing has no part o.'},\n", + " {'id': 12,\n", + " 'theme': 'Integrity Challenge Questions',\n", + " 'context': 'Integrity is the cornerstone of the fire service profession, guiding every action and decision.\\n- Firefighters are entrusted with public safety, making it imperative to uphold the highest ethical standards.\\n- In the fire service, we are governed by regulations such as the NFPA standards and the Ontario FPPA, which mandate strict compliance to ensure safety and well-being.\\n- These guidelines underscore the need for transparency and ethical conduct in all our actions.\\n- Potential Conclusions:\\no Integrity is not just a personal attribute; it is a professional necessity that ensures the effectiveness and reliability of our fire service operations.\\no When faced with an integrity challenge, it is essential to remain steadfast in ethical principles, even under pressure.\\no This experience reinforced my commitment to the values of the fire service and highlighted the importance of fostering a culture where integrity is paramount.\\no By upholding these standards, we not only protect ourselves and our colleagues but also maintain the trust and confidence of the communities we serve.'},\n", + " {'id': 13,\n", + " 'theme': 'Taking a Shortcut at work',\n", + " 'context': \"I believe in having strong work ethic. I was raised that way and my work experience to date proves that…\\n- I definitely do not take shortcuts around things that compromise health and safety or my ethics and morality.\\n- I never take shortcuts that compromise the health and safety of myself or others, or that challenge my ethical and moral values.\\n- I believe that the fire service shares this same perspective, prioritizing safety, ethics, and morality above all else.\\n- In my view, all organizations should establish clear rules, and it is essential for every member of those organizations to be aware of and follow these rules.\\n- This is why organizations have internal Standard Operating Procedures (SOPs), Occupational Health and Safety Act (OHSA) guidelines, Highway Traffic Act (HTA) regulations, Fire Codes, and even the Criminal Code when necessary.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they have a comprehensive set of Standard Operating Procedures (SOPs) that are diligently followed. During my training, I learned about the critical importance of these procedures and the reasons for adhering to them.\\no If I were fortunate enough to join this organization, I understand that it would be my responsibility to thoroughly acquaint myself with its rules and procedures. I'm committed to investing the necessary time and effort to ensure I comply with them.\\no In firefighting, there's no room for shortcuts. It's an inherently perilous job and deviating from established procedures can jeopardize lives. Rules are not just guidelines but safeguards that protect everyone and ensure a safe return from each mission.\"},\n", + " {'id': 14,\n", + " 'theme': 'Delivering Difficult Messages',\n", + " 'context': \"I do not shy away from the responsibility of delivering difficult messages when necessary, even though it may be uncomfortable. My commitment to honesty and ethical conduct remains unwavering.\\n- I believe that the fire service, like any responsible organization, understands the importance of addressing challenging issues head-on, which aligns with my perspective on this matter.\\n- In all organizations, there should be clear protocols and guidelines for delivering difficult messages effectively and sensitively, ensuring that the message is conveyed while respecting the dignity and feelings of the recipients.\\n- This is why organizations often have established procedures and communication guidelines to handle such situations professionally and ethically.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they prioritize open and honest communication. During my training, I learned about their approach to delivering difficult messages and the importance of doing so with empathy and professionalism.\\no If I were part of this organization, I would understand that delivering difficult messages might be a part of my role. I would be committed to following their established protocols and guidelines for addressing such situations.\\no In firefighting and similar high-stakes professions, effective communication, even in challenging circumstances, can be a matter of life and death. The rules and procedures in place are not just about following a script but ensuring that messages are conveyed in a way that respects the emotions and well-being of all involved parties.\"},\n", + " {'id': 15,\n", + " 'theme': 'Not Following SOPs/SOGs',\n", + " 'context': \"I have never deviated from established SOPs at work, as doing so can compromise safety, ethical standards, and the integrity of the organization.\\n- I understand that the fire service, like any responsible organization, places a high value on adherence to SOPs, which is consistent with my perspective.\\n- In every organization, it's crucial to have clear and well-documented SOPs that every member understands and follows. This ensures consistency, safety, and ethical conduct.\\n- This is why organizations implement internal SOPs and adhere to external regulations like OHSA, HTA, and Fire Codes to maintain high standards of operation.\\n- Potential conclusions:\\no I'm aware that at _____ Fire, strict adherence to SOPs is fundamental to their operational success. During my training, I gained a deep appreciation for the importance of following these procedures and the consequences of not doing so.\\no If I were to become part of this organization, I would fully understand the gravity of following SOPs. I would uphold these standards and would actively seek training and support to ensure compliance.\\no In firefighting and similar high-risk professions, disregarding SOPs is simply not an option. These procedures are in place to protect lives and property. Any deviation can have serious consequences, and rule adherence is non-negotiable.\"},\n", + " {'id': 16,\n", + " 'theme': 'Continuous Improvement',\n", + " 'context': \"Continuous improvement is about striving to be better every day, both as an individual and as part of a team.\\n- I believe that the fire service embodies this concept by constantly evolving through training, adopting new technologies, and learning from past experiences.\\n- Reflecting on one's performance and seeking feedback are essential components of continuous improvement, as they help identify strengths and areas for growth.\\n- Staying updated with new firefighting techniques, equipment, and regulations is crucial for maintaining effectiveness and safety in the field.\\n- Potential Conclusions:\\no I've seen how ______ Fire prioritizes ongoing training and professional development to ensure its firefighters remain at the forefront of the profession. I look forward to being part of an organization that values growth and innovation.\\no During my station visit, I was impressed by the emphasis on learning and improvement at ______ Fire. That environment aligns perfectly with my personal commitment to always better myself and support my team in doing the same.\\no I believe continuous improvement is not just about improving skills but also about fostering a culture where everyone strives to do better. At ______ Fire, I’m eager to contribute to that culture by embracing challenges, seeking feedback, and pursuing opportunities for growth.\"},\n", + " {'id': 17,\n", + " 'theme': 'Handling Sensitive Information',\n", + " 'context': 'Firefighters are often entrusted with sensitive information, whether it pertains to medical calls, emergency incidents, or personal details about community members.\\n- Maintaining confidentiality and discretion is critical for preserving trust and ensuring the dignity of individuals involved.\\n- Handling sensitive information responsibly requires understanding and adhering to organizational policies, as well as exercising sound judgment.\\n- Respecting privacy is a key component of professionalism, especially in a role as visible and impactful as firefighting.\\n- Potential Conclusions:\\no I understand that ______ Fire has clear guidelines and training around handling sensitive information. I respect and appreciate the importance of these protocols and would adhere to them without compromise.\\no If given the opportunity to join ______ Fire, I would uphold the highest standards of confidentiality and discretion, ensuring that sensitive information is treated with the respect it deserves.\\no Handling sensitive information with care is essential to maintaining the trust of the community and the integrity of the fire service. I’m committed to embodying these values and ensuring that all information is managed professionally and ethically.'},\n", + " {'id': 18,\n", + " 'theme': 'Solving a Problem',\n", + " 'context': \"I believe problem-solving is one of the most valuable skills in the fire service, as it often determines the success or failure of a critical situation.\\n- Effective problem-solving requires a clear assessment of the situation, evaluating available resources, and making informed decisions quickly.\\n- Firefighting often involves scenarios where unexpected challenges arise, and the ability to stay calm and address issues methodically is essential.\\n- Collaboration is a significant part of problem-solving, as no one firefighter has all the answers. Solutions come from teamwork and leveraging everyone's strengths.\\n- Potential Conclusions:\\no I understand that ______ Fire emphasizes critical thinking and problem-solving in their training programs. During my training, I honed these skills and learned how to approach challenges systematically and effectively.\\no If I were part of ______ Fire, I would actively apply my problem-solving abilities in both emergency and non-emergency situations, ensuring I work collaboratively with my team to find the best outcomes.\\no Solving problems in firefighting goes beyond emergencies; it's about addressing challenges proactively, whether it's equipment maintenance, community outreach, or operational efficiency. I'm committed to contributing to this problem-solving culture at ______ Fire.\"},\n", + " {'id': 19,\n", + " 'theme': 'Challenge Questions',\n", + " 'context': 'Life is full of challenges. It is important for firefighters to be the type of people that take those challenges head on and constantly work to find ways to overcome them.\\n- Grit, persistence, creative problem solving, and strong mental health are the keys to overcoming challenges.\\n- Life can change in a second. Its important to be adaptive and flexible.\\n- Potential Conclusions:\\no And I am certain that ______ Fire works very hard to meet every challenge and then overcome them.\\no I think about how you guys handled the ________ situation\\no or the recent fire at _______\\no and as an outsider looking in, I was thoroughly impressed with the way the department handled it.'}]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "themes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import List, Dict\n", + "from pydantic import BaseModel, Field\n", + "from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langgraph.graph import StateGraph, END\n", + "\n", + "class PracticeState(BaseModel):\n", + " \"\"\"Tracks the state of the practice session\"\"\"\n", + " messages: List[BaseMessage] = Field(default_factory=list)\n", + " theme: str\n", + " questions_asked: int = 0\n", + " gathered_responses: List[str] = Field(default_factory=list)\n", + " ready_for_startpop: bool = False\n", + "\n", + "def create_practice_assistant(theme: str, resume_retriever, questions_retriever):\n", + " \"\"\"Creates a practice assistant for a specific interview theme\"\"\"\n", + " \n", + " model = ChatOpenAI(temperature=0.7, model=\"gpt-4-turbo-preview\")\n", + "\n", + " # Core system prompt for question generation\n", + " QUESTION_PROMPT = \"\"\"You are an AI assistant helping prepare for a firefighter interview, focusing on the theme: {theme}.\n", + "\n", + " Resume Context:\n", + " {resume_context}\n", + "\n", + " Sample Questions for this Theme:\n", + " {questions_context}\n", + "\n", + " Previous Questions and Responses:\n", + " {conversation_history}\n", + "\n", + " Generate a focused question that:\n", + " 1. Relates to the candidate's background from their resume\n", + " 2. Aligns with the current theme\n", + " 3. Encourages STAR/STARTPOP format responses\n", + " 4. Builds on previous responses\n", + " 5. Helps gather material for a strong STARTPOP response\n", + "\n", + " Ask only ONE question and make it conversational and encouraging.\"\"\"\n", + "\n", + " # STARTPOP generation prompt\n", + " STARTPOP_PROMPT = \"\"\"Based on all the responses gathered during our practice session, let's create a strong STARTPOP response for the theme: {theme}\n", + "\n", + " Theme: {theme}\n", + " Collected Responses: {responses}\n", + " Resume Context: {resume_context}\n", + "\n", + " Create a polished STARTPOP response that:\n", + " 1. Uses the best examples from the practice session\n", + " 2. Incorporates relevant experience from the resume\n", + " 3. Follows the exact STARTPOP format:\n", + "\n", + " Situation:\n", + " - [Specific context and background]\n", + "\n", + " Task:\n", + " - [Clear objectives and responsibilities]\n", + "\n", + " Action:\n", + " - [Both potential negative approaches and chosen positive actions]\n", + "\n", + " Results:\n", + " - [Concrete outcomes with timeframes]\n", + "\n", + " Transitions:\n", + " - [Professional firefighting terminology]\n", + "\n", + " Personal Lessons:\n", + " - [Growth and self-awareness]\n", + "\n", + " Other People Observations:\n", + " - [Team and interpersonal insights]\n", + "\n", + " Professional Connection:\n", + " - [Direct firefighting career relevance]\"\"\"\n", + "\n", + " def get_next_question(state: PracticeState) -> dict:\n", + " \"\"\"Generates the next practice question\"\"\"\n", + " # Retrieve relevant context\n", + " resume_context = resume_retriever.invoke(state.theme)\n", + " questions_context = questions_retriever.invoke(state.theme)\n", + " \n", + " # Format conversation history\n", + " conversation_history = \"\\n\".join([\n", + " f\"Q: {state.messages[i].content}\\nA: {state.messages[i+1].content}\"\n", + " for i in range(0, len(state.messages)-1, 2)\n", + " if i+1 < len(state.messages)\n", + " ])\n", + "\n", + " # Generate question\n", + " chain = ChatPromptTemplate.from_template(QUESTION_PROMPT) | model\n", + " \n", + " response = chain.invoke({\n", + " \"theme\": state.theme,\n", + " \"resume_context\": resume_context,\n", + " \"questions_context\": questions_context,\n", + " \"conversation_history\": conversation_history\n", + " })\n", + " \n", + " return {\"messages\": state.messages + [AIMessage(content=response)]}\n", + "\n", + " def process_response(state: PracticeState) -> dict:\n", + " \"\"\"Processes user's response and determines next steps\"\"\"\n", + " # Track the response\n", + " state.gathered_responses.append(state.messages[-1].content)\n", + " state.questions_asked += 1\n", + " \n", + " # Determine if ready for STARTPOP\n", + " ready_for_startpop = state.questions_asked >= 3\n", + " \n", + " return {\n", + " \"messages\": state.messages,\n", + " \"questions_asked\": state.questions_asked,\n", + " \"gathered_responses\": state.gathered_responses,\n", + " \"ready_for_startpop\": ready_for_startpop\n", + " }\n", + "\n", + " def generate_startpop(state: PracticeState) -> dict:\n", + " \"\"\"Generates final STARTPOP response\"\"\"\n", + " # Get final context\n", + " resume_context = resume_retriever.invoke(state.theme)\n", + " \n", + " # Generate STARTPOP\n", + " chain = ChatPromptTemplate.from_template(STARTPOP_PROMPT) | model\n", + " \n", + " response = chain.invoke({\n", + " \"theme\": state.theme,\n", + " \"responses\": \"\\n\".join(state.gathered_responses),\n", + " \"resume_context\": resume_context\n", + " })\n", + " \n", + " return {\n", + " \"messages\": state.messages + [AIMessage(content=response)],\n", + " \"ready_for_startpop\": True\n", + " }\n", + "\n", + " def should_continue(state: PracticeState) -> str:\n", + " \"\"\"Determines whether to continue questions or generate STARTPOP\"\"\"\n", + " if state.ready_for_startpop:\n", + " return \"generate_startpop\"\n", + " return \"continue_questions\"\n", + "\n", + " # Create workflow\n", + " workflow = StateGraph(PracticeState)\n", + " \n", + " # Add nodes\n", + " workflow.add_node(\"get_next_question\", get_next_question)\n", + " workflow.add_node(\"process_response\", process_response)\n", + " workflow.add_node(\"should_continue\", should_continue)\n", + " workflow.add_node(\"generate_startpop\", generate_startpop)\n", + " \n", + " # Add edges\n", + " workflow.add_edge(\"should_continue\", \"continue_questions\", \"get_next_question\")\n", + " workflow.add_edge(\"should_continue\", \"generate_startpop\", \"generate_startpop\")\n", + " workflow.add_edge(\"get_next_question\", \"process_response\")\n", + " workflow.add_edge(\"process_response\", \"should_continue\")\n", + " workflow.add_edge(\"generate_startpop\", END)\n", + " \n", + " return workflow.compile()\n", + "\n", + "def run_theme_practice(theme: str, resume_retriever, questions_retriever):\n", + " \"\"\"Runs a practice session for a specific theme\"\"\"\n", + " \n", + " practice_bot = create_practice_assistant(theme, resume_retriever, questions_retriever)\n", + " \n", + " # Initialize state\n", + " initial_state = PracticeState(\n", + " messages=[\n", + " SystemMessage(content=f\"Starting practice session for theme: {theme}\"),\n", + " HumanMessage(content=\"I'm ready to practice this theme.\")\n", + " ],\n", + " theme=theme\n", + " )\n", + " \n", + " return practice_bot.stream(initial_state)\n", + "\n", + "# Example usage\n", + "if __name__ == \"__main__\":\n", + " theme = \"Customer Service\"\n", + " \n", + " print(f\"\\nStarting practice session for theme: {theme}\")\n", + " print(\"I'll ask you several questions, then help create a STARTPOP response.\")\n", + " print(\"Type your responses when prompted, or 'quit' to end.\\n\")\n", + " \n", + " for state in run_theme_practice(theme, resume_retriever, questions_retriever):\n", + " if isinstance(state.messages[-1], AIMessage):\n", + " print(\"\\nAssistant:\", state.messages[-1].content)\n", + " \n", + " if not state.ready_for_startpop:\n", + " print(\"\\nYour response:\")\n", + " user_input = input(\"> \")\n", + " if user_input.lower() == 'quit':\n", + " break\n", + " state.messages.append(HumanMessage(content=user_input))\n", + " \n", + " if state.ready_for_startpop and len(state.messages) > 0:\n", + " print(\"\\nPractice complete! Here's your STARTPOP response for this theme.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### START POP AGENT" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "import os\n", + "\n", + "if not os.environ.get(\"OPENAI_API_KEY\"):\n", + " os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter API key for OpenAI: \")\n", + "\n", + "from langchain_openai import ChatOpenAI\n", + "\n", + "llm = ChatOpenAI(model=\"gpt-4o-mini\")\n", + "\n", + "\n", + "import getpass\n", + "import os\n", + "\n", + "if not os.environ.get(\"OPENAI_API_KEY\"):\n", + " os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter API key for OpenAI: \")\n", + "\n", + "from langchain_openai import OpenAIEmbeddings\n", + "\n", + "embeddings = OpenAIEmbeddings(model=\"text-embedding-3-large\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "pip install -qU langchain-core" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.vectorstores import InMemoryVectorStore\n", + "\n", + "vector_store = InMemoryVectorStore(embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_community.document_loaders import WebBaseLoader\n", + "from langchain_community.vectorstores import FAISS\n", + "from langchain_openai import OpenAIEmbeddings\n", + "from langchain_text_splitters import RecursiveCharacterTextSplitter\n", + "from langchain.schema import Document\n", + "import json\n", + "import os\n", + "\n", + "# Load questions and themes\n", + "question_path = \"../data/config_files/questions.json\"\n", + "theme_path = \"../data/config_files/theme_context.json\"\n", + "with open(question_path, \"r\") as f:\n", + " questions = json.load(f)\n", + "\n", + "with open(theme_path, \"r\") as f:\n", + " themes = json.load(f)\n", + "\n", + "def load_document(file_path: str):\n", + " extension = os.path.splitext(file_path)[1].lower()\n", + " \n", + " if extension in ['.doc', '.docx']:\n", + " # Convert .doc or .docx to PDF first\n", + " pdf_path = convert_word_to_pdf(file_path)\n", + " loader = PyPDFLoader(pdf_path)\n", + " elif extension == '.pdf':\n", + " loader = PyPDFLoader(file_path)\n", + " else:\n", + " raise ValueError(f\"Unsupported file type: {extension}. Only .pdf, .docx, and .doc are supported.\")\n", + " \n", + " return loader.load()\n", + "\n", + "# Create text splitter\n", + "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n", + " chunk_size=100, chunk_overlap=50\n", + ")\n", + "\n", + "# Load and split resume document\n", + "docs = load_document('../upload_folder/Resume_-_Erika_Kiviaho.pdf')\n", + "resume_splits = text_splitter.split_documents(docs)\n", + "\n", + "\n", + "# Prepare questions for vectorDB - Convert dictionary to Document objects\n", + "questions_docs = [\n", + " Document(\n", + " page_content=str(value),\n", + " metadata={\"question_id\": key}\n", + " )\n", + " for key, value in questions.items()\n", + "]\n", + "questions_splits = text_splitter.split_documents(questions_docs)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"[{'id': 1, 'question': 'Why do you want to be a firefighter?'}, {'id': 2, 'question': 'What have you done to prepare for a career in the Fire Service?'}, {'id': 3, 'question': 'Why do you want to work for this department?'}, {'id': 4, 'question': 'Name some of the traits, characteristics, or attributes of a good firefighter.'}, {'id': 5,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"3, 'question': 'Why do you want to work for this department?'}, {'id': 4, 'question': 'Name some of the traits, characteristics, or attributes of a good firefighter.'}, {'id': 5, 'question': 'What are some of the biggest challenges faced by the Fire Service today?'}, {'id': 6, 'question': 'Describe the emergency vs. non-emergency duties of a firefighter.'}, {'id': 7,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'What are some of the biggest challenges faced by the Fire Service today?'}, {'id': 6, 'question': 'Describe the emergency vs. non-emergency duties of a firefighter.'}, {'id': 7, 'question': 'Where do you see yourself in 1, 5, 10, 20 years?'}, {'id': 8, 'question': 'Describe the chain of command and your role in it.'}, {'id': 9, 'question':\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'Where do you see yourself in 1, 5, 10, 20 years?'}, {'id': 8, 'question': 'Describe the chain of command and your role in it.'}, {'id': 9, 'question': 'How do you handle stress, now and once you have the job?'}, {'id': 10, 'question': 'How do you think the role of the firefighter will be different in 5 years?'}, {'id': 11,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'How do you handle stress, now and once you have the job?'}, {'id': 10, 'question': 'How do you think the role of the firefighter will be different in 5 years?'}, {'id': 11, 'question': 'What is the organizational structure of our Fire Department?'}, {'id': 12, 'question': 'Why do you think honesty and integrity are important in the Fire Service?'}, {'id': 13, 'question': 'What\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'What is the organizational structure of our Fire Department?'}, {'id': 12, 'question': 'Why do you think honesty and integrity are important in the Fire Service?'}, {'id': 13, 'question': 'What are the advantages and disadvantages of similar vs diverse teams?'}, {'id': 14, 'question': 'List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.'}, {'id': 15, 'question': 'What\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"advantages and disadvantages of similar vs diverse teams?'}, {'id': 14, 'question': 'List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.'}, {'id': 15, 'question': 'What is the most important duty of a firefighter?'}, {'id': 16, 'question': 'What does leadership mean to you?'}, {'id': 17, 'question': 'What do you like most and least about a supervisor?'},\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"is the most important duty of a firefighter?'}, {'id': 16, 'question': 'What does leadership mean to you?'}, {'id': 17, 'question': 'What do you like most and least about a supervisor?'}, {'id': 18, 'question': 'What do you appreciate in a manager’s style?'}, {'id': 19, 'question': 'What are the six common leadership styles in the Fire Service?'}, {'id':\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"{'id': 18, 'question': 'What do you appreciate in a manager’s style?'}, {'id': 19, 'question': 'What are the six common leadership styles in the Fire Service?'}, {'id': 20, 'question': 'What do you like most and least about being a firefighter?'}, {'id': 21, 'question': 'How does diversity impact the Fire Service today?'}, {'id': 22, 'question': 'How\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"20, 'question': 'What do you like most and least about being a firefighter?'}, {'id': 21, 'question': 'How does diversity impact the Fire Service today?'}, {'id': 22, 'question': 'How would you make a positive impact regarding the diversity in the community?'}, {'id': 23, 'question': 'Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?'},\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"would you make a positive impact regarding the diversity in the community?'}, {'id': 23, 'question': 'Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?'}, {'id': 24, 'question': 'Public Education is important in the Fire Service. How would you provide this service?'}, {'id': 25, 'question': 'You are a probationary firefighter. How do you prepare\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"{'id': 24, 'question': 'Public Education is important in the Fire Service. How would you provide this service?'}, {'id': 25, 'question': 'You are a probationary firefighter. How do you prepare yourself?'}, {'id': 26, 'question': 'Why is respect so important, and what does it mean?'}, {'id': 27, 'question': 'Would you break a rule if asked to?'}, {'id': 28,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"{'id': 26, 'question': 'Why is respect so important, and what does it mean?'}, {'id': 27, 'question': 'Would you break a rule if asked to?'}, {'id': 28, 'question': 'What are potential sources of workplace conflict? How would you handle workplace conflict?'}, {'id': 29, 'question': 'Why should we hire you?'}, {'id': 30, 'question': 'What are your strengths\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'What are potential sources of workplace conflict? How would you handle workplace conflict?'}, {'id': 29, 'question': 'Why should we hire you?'}, {'id': 30, 'question': 'What are your strengths and weaknesses? (What would your boss say about you?)'}, {'id': 31, 'question': 'How do you want to be remembered at the end of your career?'}, {'id': 32, 'question': 'What skills do\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"(What would your boss say about you?)'}, {'id': 31, 'question': 'How do you want to be remembered at the end of your career?'}, {'id': 32, 'question': 'What skills do you bring to Dispatch?'}, {'id': 33, 'question': 'Walk me through a truck check.'}, {'id': 34, 'question': 'How do you define teamwork in the context of firefighting?'}, {'id':\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"bring to Dispatch?'}, {'id': 33, 'question': 'Walk me through a truck check.'}, {'id': 34, 'question': 'How do you define teamwork in the context of firefighting?'}, {'id': 35, 'question': 'What motivates you to perform well in stressful situations?'}, {'id': 36, 'question': 'Explain how you would handle feedback from a superior, especially if it was critical.'}, {'id':\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"35, 'question': 'What motivates you to perform well in stressful situations?'}, {'id': 36, 'question': 'Explain how you would handle feedback from a superior, especially if it was critical.'}, {'id': 37, 'question': 'What is your understanding of the core values of the Fire Service?'}, {'id': 38, 'question': 'Describe a time when you demonstrated initiative in the workplace.'}, {'id': 39,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"37, 'question': 'What is your understanding of the core values of the Fire Service?'}, {'id': 38, 'question': 'Describe a time when you demonstrated initiative in the workplace.'}, {'id': 39, 'question': 'How do you prioritize tasks during an emergency response?'}, {'id': 40, 'question': 'What role does technology play in modern firefighting, and how are you prepared for it?'}, {'id': 41,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'question': 'How do you prioritize tasks during an emergency response?'}, {'id': 40, 'question': 'What role does technology play in modern firefighting, and how are you prepared for it?'}, {'id': 41, 'question': 'How would you approach learning new skills and techniques required for this job?'}, {'id': 42, 'question': 'Explain how you balance personal and professional commitments in a demanding job.'}, {'id': 43,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"'question': 'How would you approach learning new skills and techniques required for this job?'}, {'id': 42, 'question': 'Explain how you balance personal and professional commitments in a demanding job.'}, {'id': 43, 'question': 'What strategies do you use to ensure continuous improvement in your work?'}, {'id': 44, 'question': 'How do you approach building trust and relationships within a new team?'}, {'id': 45,\"),\n", + " Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"43, 'question': 'What strategies do you use to ensure continuous improvement in your work?'}, {'id': 44, 'question': 'How do you approach building trust and relationships within a new team?'}, {'id': 45, 'question': 'What does a day in the life of a firefighter look like for both emergency and non-emergency activities?'}]\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"[{'id': 1, 'question': 'What would you do if a firefighter makes disparaging remarks in public about visible minorities?'}, {'id': 2, 'question': 'What would you do if a senior firefighter is making inappropriate, unwelcomed, bullying comments towards another firefighter?'}, {'id': 3, 'question': 'What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?'},\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"unwelcomed, bullying comments towards another firefighter?'}, {'id': 3, 'question': 'What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?'}, {'id': 4, 'question': 'What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?'}, {'id': 5, 'question': 'What would you do if your\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"4, 'question': 'What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?'}, {'id': 5, 'question': 'What would you do if your captain gives you a performance review that you are unhappy with?'}, {'id': 6, 'question': 'What would you do if you saw a firefighter put a valuable item in their pocket at a call?'}, {'id': 7, 'question':\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"a performance review that you are unhappy with?'}, {'id': 6, 'question': 'What would you do if you saw a firefighter put a valuable item in their pocket at a call?'}, {'id': 7, 'question': 'What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?'}, {'id': 8, 'question': 'What would you do if you noticed two firefighters\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"'What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?'}, {'id': 8, 'question': 'What would you do if you noticed two firefighters cheating on an exam?'}, {'id': 9, 'question': 'What would you do if you see two firefighters getting heated and about to fight?'}, {'id': 10, 'question': 'What would you do if you are\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"cheating on an exam?'}, {'id': 9, 'question': 'What would you do if you see two firefighters getting heated and about to fight?'}, {'id': 10, 'question': 'What would you do if you are confronted by an irate citizen and you are all by yourself?'}, {'id': 11, 'question': 'What would you do if you are on your way home after a shift and see a car accident or other emergency?'},\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"you are confronted by an irate citizen and you are all by yourself?'}, {'id': 11, 'question': 'What would you do if you are on your way home after a shift and see a car accident or other emergency?'}, {'id': 12, 'question': 'What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?'}, {'id': 13, 'question': 'What would you do if you notice\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content='{\\'id\\': 12, \\'question\\': \\'What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?\\'}, {\\'id\\': 13, \\'question\\': \\'What would you do if you notice one firefighter not being included in the group (e.g., coffee poured for everyone but them)?\\'}, {\\'id\\': 14, \\'question\\': \"What would you do if you are the apparatus driver and during your daily truck check you discover'),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content='one firefighter not being included in the group (e.g., coffee poured for everyone but them)?\\'}, {\\'id\\': 14, \\'question\\': \"What would you do if you are the apparatus driver and during your daily truck check you discover the emergency lights are not working, and your captain says, \\'Don’t worry about it. The next crew on duty will take care of it\\'?\"}, {\\'id\\': 15, \\'question\\': \\'What would you do if one'),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content='the emergency lights are not working, and your captain says, \\'Don’t worry about it. The next crew on duty will take care of it\\'?\"}, {\\'id\\': 15, \\'question\\': \\'What would you do if one member of the crew has a really negative attitude about training?\\'}, {\\'id\\': 16, \\'question\\': \\'What would you do if a fellow firefighter tells you they don’t want minorities, women, or LGBTQ+ individuals in the fire'),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"member of the crew has a really negative attitude about training?'}, {'id': 16, 'question': 'What would you do if a fellow firefighter tells you they don’t want minorities, women, or LGBTQ+ individuals in the fire service?'}, {'id': 17, 'question': 'What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?'},\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content=\"service?'}, {'id': 17, 'question': 'What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?'}, {'id': 18, 'question': 'What would you do if you are faced with conflicting orders from two supervisors at the scene of an emergency?'}]\")]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "questions_splits" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Index chunks\n", + "all_splits = questions_splits + resume_splits\n", + "\n", + "_ = vector_store.add_documents(documents=all_splits)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.graph import MessagesState, StateGraph\n", + "\n", + "graph_builder = StateGraph(MessagesState)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.tools import tool\n", + "\n", + "\n", + "@tool(response_format=\"content_and_artifact\")\n", + "def retrieve(query: str):\n", + " \"\"\"Retrieve information related to user resume and also sample general competency questions and situational questions\"\"\"\n", + " retrieved_docs = vector_store.similarity_search(query, k=2)\n", + " serialized = \"\\n\\n\".join(\n", + " (f\"Source: {doc.metadata}\\n\" f\"Content: {doc.page_content}\")\n", + " for doc in retrieved_docs\n", + " )\n", + " return serialized, retrieved_docs" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet’s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue – Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue – Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue – Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 – Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot’s Bay, ON 2023 – Present \\n• Member of Muskoka Lake’s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n• Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n• Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n• Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n• Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n• Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n• Required to constantly use problem solving, stress management, communication , and team working skills. \\n• Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 – Present \\n• Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka’s. \\n• Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n• Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n• Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\n '),\n", + " Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n• Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n• Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n• Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n• Functioned with team members from other departments and trained new hires about course procedures. \\n• Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 – 2022 \\n• Member of the city’s crew tasked with keeping municipal properties and public spaces in great condition. \\n• Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n• Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n• Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n• Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n• Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n• Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n• Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n• Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n• Ensured compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 – 2020 \\n• Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n• Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n• Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n• Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n• Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 – 2016 \\n• Played as a Forward and served as Assistant Captain for three years on the Varsity Women’s Hockey Team. \\n• Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n• Travelled to different universities serving as an ambassador for the school at various community events. \\n• Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n• Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n• Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 – Present \\n• Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 – Present \\n• Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n• Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 – Present \\n• Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 – Present \\n• Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n• Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n• Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "docs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"[Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\\\n \\\\n \\\\n1070 Hallet’s Road, MacTier, ON, P0C 1H0 \\\\nEkiviaho_9@hotmail.com \\\\n(705) 662 9735\\\\nEDUCATION \\\\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\\\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\\\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\\\n \\\\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\\\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\\\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\\\nNFPA 1006 Surface Water Rescue – Technician Level, Southwest Fire Academy 2023 \\\\nNFPA 1006 Common Passenger Vehicle Rescue – Technician Level, RS Rescue 2024 \\\\nNFPA 1006 Confined Space Rescue – Technician Level, Access Rescue 2024 \\\\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\\\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\\\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\\\n \\\\nFIRST AID AND LIFE SAFETY TRAINING \\\\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\\\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\\\nPsychological First Aid, John Hopkins University 2023 \\\\n \\\\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\\\nIMS 100 – Intro to Incident Management System, EMO 2023 \\\\n \\\\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\\\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\\\nPleasure Craft Operator License, Transport Canada 2023 \\\\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\\\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\\\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\\\n \\\\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\\\nAmerican Sign Language for First Responders, Humber College 2023 \\\\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\\\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\\\n \\\\nWORK EXPERIENCE \\\\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot’s Bay, ON 2023 – Present \\\\n• Member of Muskoka Lake’s Volunteer Fire Suppression Team training out of and responding from Station 1. \\\\n• Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\\\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\\\n• Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\\\n• Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\\\n• Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\\\n• Frequently interacts with the public presenting fire safety messages and providing emotional support . \\\\n• Required to constantly use problem solving, stress management, communication , and team working skills. \\\\n• Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\\\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\nLabourer Sundance Gardening, Muskoka, ON 2023 – Present \\\\n• Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka’s. \\\\n• Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\\\n• Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\\\n• Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\\\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\n '), Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\\\n• Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\\\n• Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\\\n• Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\\\n• Functioned with team members from other departments and trained new hires about course procedures. \\\\n• Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\\\n \\\\nLabourer City of Waterloo, Waterloo, ON 2020 – 2022 \\\\n• Member of the city’s crew tasked with keeping municipal properties and public spaces in great condition. \\\\n• Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\\\n• Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\\\n• Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\\\n• Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\\\n• Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\\\n• Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\\\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\\\n• Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\\\n• Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\\\n• Ensured compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\nBarista Starbucks, Somewhere, ON 2018 – 2020 \\\\n• Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\\\n• Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\\\n• Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\\\n• Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\\\n• Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\\\n \\\\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 – 2016 \\\\n• Played as a Forward and served as Assistant Captain for three years on the Varsity Women’s Hockey Team. \\\\n• Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\\\n• Travelled to different universities serving as an ambassador for the school at various community events. \\\\n• Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\\\n• Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\\\n• Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\\\n \\\\nVOLUNTEERING & COMMUNITY SERVICE \\\\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 – Present \\\\n• Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\\\n \\\\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 – Present \\\\n• Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\\\n• Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\\\n \\\\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 – Present \\\\n• Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\\\n \\\\nTeam Captain Canadian National Ringette Team 2012 – Present \\\\n• Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\\\n• Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\\\n• Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\\\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\\\n \\\\nHOBBIES & INTERESTS \\\\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\\\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\\\nFriends and Family. ')]\"" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(docs)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "from langchain_core.messages import SystemMessage\n", + "from langgraph.prebuilt import ToolNode\n", + "\n", + "\n", + "# Step 1: Generate an AIMessage that may include a tool-call to be sent.\n", + "def query_or_respond(state: MessagesState):\n", + " \"\"\"Generate tool call for retrieval or respond.\"\"\"\n", + " llm_with_tools = llm.bind_tools([retrieve])\n", + " response = llm_with_tools.invoke(state[\"messages\"])\n", + " # MessagesState appends messages to state instead of overwriting\n", + " return {\"messages\": [response]}\n", + "\n", + "\n", + "# Step 2: Execute the retrieval.\n", + "tools = ToolNode([retrieve])\n", + "\n", + "\n", + "# Step 3: Generate a response using the retrieved content.\n", + "def generate(state: MessagesState):\n", + " \"\"\"Generate answer.\"\"\"\n", + " # Get generated ToolMessages\n", + " recent_tool_messages = []\n", + " for message in reversed(state[\"messages\"]):\n", + " if message.type == \"tool\":\n", + " recent_tool_messages.append(message)\n", + " else:\n", + " break\n", + " tool_messages = recent_tool_messages[::-1]\n", + "\n", + " # Format into prompt\n", + " docs_content = \"\\n\\n\".join(doc.content for doc in tool_messages)\n", + " system_message_content = (\n", + " \"You are an assistant for question-answering tasks. \"\n", + " \"Use the following pieces of retrieved context to answer \"\n", + " \"the question. If you don't know the answer, say that you \"\n", + " \"don't know. Use three sentences maximum and keep the \"\n", + " \"answer concise.\"\n", + " \"\\n\\n\"\n", + " f\"{docs_content}\"\n", + " )\n", + " conversation_messages = [\n", + " message\n", + " for message in state[\"messages\"]\n", + " if message.type in (\"human\", \"system\")\n", + " or (message.type == \"ai\" and not message.tool_calls)\n", + " ]\n", + " prompt = [SystemMessage(system_message_content)] + conversation_messages\n", + "\n", + " # Run\n", + " response = llm.invoke(prompt)\n", + " return {\"messages\": [response]}" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.graph import END\n", + "from langgraph.prebuilt import ToolNode, tools_condition\n", + "\n", + "graph_builder.add_node(query_or_respond)\n", + "graph_builder.add_node(tools)\n", + "graph_builder.add_node(generate)\n", + "\n", + "graph_builder.set_entry_point(\"query_or_respond\")\n", + "graph_builder.add_conditional_edges(\n", + " \"query_or_respond\",\n", + " tools_condition,\n", + " {END: END, \"tools\": \"tools\"},\n", + ")\n", + "graph_builder.add_edge(\"tools\", \"generate\")\n", + "graph_builder.add_edge(\"generate\", END)\n", + "\n", + "graph = graph_builder.compile()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import Image, display\n", + "\n", + "display(Image(graph.get_graph().draw_mermaid_png()))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Hello\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Hello! How can I assist you today?\n" + ] + } + ], + "source": [ + "input_message = \"Hello\"\n", + "\n", + "for step in graph.stream(\n", + " {\"messages\": [{\"role\": \"user\", \"content\": input_message}]},\n", + " stream_mode=\"values\",\n", + "):\n", + " step[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Tell me the overall; experince of the user please?\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "Tool Calls:\n", + " retrieve (call_0bC6DeBL36EbRachQixDnqOO)\n", + " Call ID: call_0bC6DeBL36EbRachQixDnqOO\n", + " Args:\n", + " query: user overall experience\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: retrieve\n", + "\n", + "Source: {'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}\n", + "Content: • Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \n", + "and an ability to perform physically demanding work for long periods of time in adverse weather conditions. \n", + "• Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \n", + "• Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario.\n", + "\n", + "Source: {'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}\n", + "Content: American Sign Language for First Responders, Humber College 2023 \n", + "Accessibility for Ontarians with Disabilities, AODA.ca 2023 \n", + "LGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \n", + " \n", + "WORK EXPERIENCE\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "The user has experience in team building, maintaining small engine equipment, and performing physically demanding work in adverse weather conditions. They have interacted with various municipal departments, ensured road safety, and compliance with relevant acts. Additionally, they have completed training in American Sign Language for First Responders, accessibility, and LGBT2SQ+ inclusion.\n" + ] + } + ], + "source": [ + "input_message = \"Tell me the overall; experince of the user please?\"\n", + "\n", + "for step in graph.stream(\n", + " {\"messages\": [{\"role\": \"user\", \"content\": input_message}]},\n", + " stream_mode=\"values\",\n", + "):\n", + " step[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.checkpoint.memory import MemorySaver\n", + "\n", + "memory = MemorySaver()\n", + "graph = graph_builder.compile(checkpointer=memory)\n", + "\n", + "# Specify an ID for the thread\n", + "config = {\"configurable\": {\"thread_id\": \"abc123\"}}" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "Do you have access to the user resume \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Yes, I have access to a sample user resume. Would you like me to retrieve specific information or details from it?\n" + ] + } + ], + "source": [ + "input_message = \"Do you have access to the user resume \"\n", + "\n", + "for step in graph.stream(\n", + " {\"messages\": [{\"role\": \"user\", \"content\": input_message}]},\n", + " stream_mode=\"values\",\n", + " config=config,\n", + "):\n", + " step[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "================================\u001b[1m Human Message \u001b[0m=================================\n", + "\n", + "retrive the complete user resume please?\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "Tool Calls:\n", + " retrieve (call_LPnE2bdPbLhoFWYhfya6z3nr)\n", + " Call ID: call_LPnE2bdPbLhoFWYhfya6z3nr\n", + " Args:\n", + " query: user resume\n", + "=================================\u001b[1m Tool Message \u001b[0m=================================\n", + "Name: retrieve\n", + "\n", + "Source: {'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}\n", + "Content: (705) 662 9735\n", + "EDUCATION \n", + "College Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \n", + "University Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \n", + "Ontario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010\n", + "\n", + "Source: {'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}\n", + "Content: Erika Kiviaho \n", + " \n", + " \n", + "1070 Hallet’s Road, MacTier, ON, P0C 1H0 \n", + "Ekiviaho_9@hotmail.com \n", + "(705) 662 9735\n", + "EDUCATION \n", + "College Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "I’m sorry, but I cannot provide the complete user resume. However, I can summarize the information or answer questions based on the content available. Let me know what you need!\n" + ] + } + ], + "source": [ + "input_message = \"retrive the complete user resume please?\"\n", + "\n", + "for step in graph.stream(\n", + " {\"messages\": [{\"role\": \"user\", \"content\": input_message}]},\n", + " stream_mode=\"values\",\n", + " config=config,\n", + "):\n", + " step[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Straight RAG" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\n \\n \\n1070 Hallet’s Road, MacTier, ON, P0C 1H0 \\nEkiviaho_9@hotmail.com \\n(705) 662 9735\\nEDUCATION \\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\n \\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\nNFPA 1006 Surface Water Rescue – Technician Level, Southwest Fire Academy 2023 \\nNFPA 1006 Common Passenger Vehicle Rescue – Technician Level, RS Rescue 2024 \\nNFPA 1006 Confined Space Rescue – Technician Level, Access Rescue 2024 \\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\n \\nFIRST AID AND LIFE SAFETY TRAINING \\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\nPsychological First Aid, John Hopkins University 2023 \\n \\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\nIMS 100 – Intro to Incident Management System, EMO 2023 \\n \\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\nPleasure Craft Operator License, Transport Canada 2023 \\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\n \\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\nAmerican Sign Language for First Responders, Humber College 2023 \\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\n \\nWORK EXPERIENCE \\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot’s Bay, ON 2023 – Present \\n• Member of Muskoka Lake’s Volunteer Fire Suppression Team training out of and responding from Station 1. \\n• Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\n• Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\n• Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\n• Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\n• Frequently interacts with the public presenting fire safety messages and providing emotional support . \\n• Required to constantly use problem solving, stress management, communication , and team working skills. \\n• Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\nLabourer Sundance Gardening, Muskoka, ON 2023 – Present \\n• Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka’s. \\n• Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\n• Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\n• Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\n '),\n", + " Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\n• Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\n• Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\n• Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\n• Functioned with team members from other departments and trained new hires about course procedures. \\n• Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\n \\nLabourer City of Waterloo, Waterloo, ON 2020 – 2022 \\n• Member of the city’s crew tasked with keeping municipal properties and public spaces in great condition. \\n• Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\n• Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\n• Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\n• Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\n• Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\n• Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\n• Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\n• Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\n• Ensured compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\n \\nBarista Starbucks, Somewhere, ON 2018 – 2020 \\n• Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\n• Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\n• Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\n• Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\n• Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\n \\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 – 2016 \\n• Played as a Forward and served as Assistant Captain for three years on the Varsity Women’s Hockey Team. \\n• Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\n• Travelled to different universities serving as an ambassador for the school at various community events. \\n• Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\n• Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\n• Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\n \\nVOLUNTEERING & COMMUNITY SERVICE \\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 – Present \\n• Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\n \\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 – Present \\n• Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\n• Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\n \\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 – Present \\n• Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\n \\nTeam Captain Canadian National Ringette Team 2012 – Present \\n• Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\n• Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\n• Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\n \\nHOBBIES & INTERESTS \\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\nFriends and Family. ')]" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "docs" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Document(metadata={'question_id': 'General Competency Questions'}, page_content=\"[{'id': 1, 'question': 'Why do you want to be a firefighter?'}, {'id': 2, 'question': 'What have you done to prepare for a career in the Fire Service?'}, {'id': 3, 'question': 'Why do you want to work for this department?'}, {'id': 4, 'question': 'Name some of the traits, characteristics, or attributes of a good firefighter.'}, {'id': 5, 'question': 'What are some of the biggest challenges faced by the Fire Service today?'}, {'id': 6, 'question': 'Describe the emergency vs. non-emergency duties of a firefighter.'}, {'id': 7, 'question': 'Where do you see yourself in 1, 5, 10, 20 years?'}, {'id': 8, 'question': 'Describe the chain of command and your role in it.'}, {'id': 9, 'question': 'How do you handle stress, now and once you have the job?'}, {'id': 10, 'question': 'How do you think the role of the firefighter will be different in 5 years?'}, {'id': 11, 'question': 'What is the organizational structure of our Fire Department?'}, {'id': 12, 'question': 'Why do you think honesty and integrity are important in the Fire Service?'}, {'id': 13, 'question': 'What are the advantages and disadvantages of similar vs diverse teams?'}, {'id': 14, 'question': 'List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.'}, {'id': 15, 'question': 'What is the most important duty of a firefighter?'}, {'id': 16, 'question': 'What does leadership mean to you?'}, {'id': 17, 'question': 'What do you like most and least about a supervisor?'}, {'id': 18, 'question': 'What do you appreciate in a manager’s style?'}, {'id': 19, 'question': 'What are the six common leadership styles in the Fire Service?'}, {'id': 20, 'question': 'What do you like most and least about being a firefighter?'}, {'id': 21, 'question': 'How does diversity impact the Fire Service today?'}, {'id': 22, 'question': 'How would you make a positive impact regarding the diversity in the community?'}, {'id': 23, 'question': 'Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?'}, {'id': 24, 'question': 'Public Education is important in the Fire Service. How would you provide this service?'}, {'id': 25, 'question': 'You are a probationary firefighter. How do you prepare yourself?'}, {'id': 26, 'question': 'Why is respect so important, and what does it mean?'}, {'id': 27, 'question': 'Would you break a rule if asked to?'}, {'id': 28, 'question': 'What are potential sources of workplace conflict? How would you handle workplace conflict?'}, {'id': 29, 'question': 'Why should we hire you?'}, {'id': 30, 'question': 'What are your strengths and weaknesses? (What would your boss say about you?)'}, {'id': 31, 'question': 'How do you want to be remembered at the end of your career?'}, {'id': 32, 'question': 'What skills do you bring to Dispatch?'}, {'id': 33, 'question': 'Walk me through a truck check.'}, {'id': 34, 'question': 'How do you define teamwork in the context of firefighting?'}, {'id': 35, 'question': 'What motivates you to perform well in stressful situations?'}, {'id': 36, 'question': 'Explain how you would handle feedback from a superior, especially if it was critical.'}, {'id': 37, 'question': 'What is your understanding of the core values of the Fire Service?'}, {'id': 38, 'question': 'Describe a time when you demonstrated initiative in the workplace.'}, {'id': 39, 'question': 'How do you prioritize tasks during an emergency response?'}, {'id': 40, 'question': 'What role does technology play in modern firefighting, and how are you prepared for it?'}, {'id': 41, 'question': 'How would you approach learning new skills and techniques required for this job?'}, {'id': 42, 'question': 'Explain how you balance personal and professional commitments in a demanding job.'}, {'id': 43, 'question': 'What strategies do you use to ensure continuous improvement in your work?'}, {'id': 44, 'question': 'How do you approach building trust and relationships within a new team?'}, {'id': 45, 'question': 'What does a day in the life of a firefighter look like for both emergency and non-emergency activities?'}]\"),\n", + " Document(metadata={'question_id': 'Situational Questions'}, page_content='[{\\'id\\': 1, \\'question\\': \\'What would you do if a firefighter makes disparaging remarks in public about visible minorities?\\'}, {\\'id\\': 2, \\'question\\': \\'What would you do if a senior firefighter is making inappropriate, unwelcomed, bullying comments towards another firefighter?\\'}, {\\'id\\': 3, \\'question\\': \\'What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?\\'}, {\\'id\\': 4, \\'question\\': \\'What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?\\'}, {\\'id\\': 5, \\'question\\': \\'What would you do if your captain gives you a performance review that you are unhappy with?\\'}, {\\'id\\': 6, \\'question\\': \\'What would you do if you saw a firefighter put a valuable item in their pocket at a call?\\'}, {\\'id\\': 7, \\'question\\': \\'What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?\\'}, {\\'id\\': 8, \\'question\\': \\'What would you do if you noticed two firefighters cheating on an exam?\\'}, {\\'id\\': 9, \\'question\\': \\'What would you do if you see two firefighters getting heated and about to fight?\\'}, {\\'id\\': 10, \\'question\\': \\'What would you do if you are confronted by an irate citizen and you are all by yourself?\\'}, {\\'id\\': 11, \\'question\\': \\'What would you do if you are on your way home after a shift and see a car accident or other emergency?\\'}, {\\'id\\': 12, \\'question\\': \\'What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?\\'}, {\\'id\\': 13, \\'question\\': \\'What would you do if you notice one firefighter not being included in the group (e.g., coffee poured for everyone but them)?\\'}, {\\'id\\': 14, \\'question\\': \"What would you do if you are the apparatus driver and during your daily truck check you discover the emergency lights are not working, and your captain says, \\'Don’t worry about it. The next crew on duty will take care of it\\'?\"}, {\\'id\\': 15, \\'question\\': \\'What would you do if one member of the crew has a really negative attitude about training?\\'}, {\\'id\\': 16, \\'question\\': \\'What would you do if a fellow firefighter tells you they don’t want minorities, women, or LGBTQ+ individuals in the fire service?\\'}, {\\'id\\': 17, \\'question\\': \\'What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?\\'}, {\\'id\\': 18, \\'question\\': \\'What would you do if you are faced with conflicting orders from two supervisors at the scene of an emergency?\\'}]')]" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "questions_docs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [], + "source": [ + "import getpass\n", + "import os\n", + "\n", + "if not os.environ.get(\"OPENAI_API_KEY\"):\n", + " os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter API key for OpenAI: \")\n", + "\n", + "from langchain_openai import ChatOpenAI\n", + "\n", + "model = ChatOpenAI(model=\"gpt-4o-mini\")" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'id': 1,\n", + " 'theme': 'Disability Questions',\n", + " 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"},\n", + " {'id': 2,\n", + " 'theme': 'Leadership Skills Questions',\n", + " 'context': \"Leadership is not about having authority; it's about inspiring others to reach their full potential.\\n- Effective leaders lead by example, demonstrating integrity, accountability, and a commitment to teamwork.\\n- In the fire service, leadership is not confined to rank; every firefighter has the opportunity to lead and contribute to the success of the team.\\n- Adaptability and decisiveness are crucial qualities in leadership, especially in high-stress and rapidly changing environments.\\n- Leadership is also about fostering a culture of continuous learning and improvement, encouraging feedback, and promoting innovation.\\n- Potential Conclusions:\\no I've heard about the emphasis on leadership development within ______ Fire, and it's clear that the department values cultivating leaders at all levels. I'm eager to contribute to that culture and continue growing as a leader.\\no During my station visit, I observed how firefighters at ______ Fire take initiative and support each other, regardless of rank. That collaborative leadership approach is something I aspire to emulate and contribute to.\\no I've learned that leadership in the fire service is not just about giving orders; it's about empowering others, building trust, and fostering a sense of unity within the team. I'm excited about the opportunity to lead by example and positively influence my fellow firefighters at ______ Fire.\"},\n", + " {'id': 3,\n", + " 'theme': 'Conflict Questions',\n", + " 'context': 'Conflict is a huge problem in high performing teams.\\n- Creates a poisonous work environment, reduces efficiencies, and creates mental health issues.\\n- Those are serious issues and must be addressed as soon as they pop up.\\n- One of the best ways to address it through increasing the communication and giving people an opportunity to explain their opinions or viewpoints.\\n- I tend to think about the three T’s (teamwork, training and trust) and how important it is to fall back on those.\\n- Attempt to secure behaviour modification through voluntary compliance.\\n- Potential Conclusions:\\no I know that professionalism runs through the entire department here. ______\\no Firefighters are professional and committed to safe and respectful workplaces.\\no One thing about the fire service is that you all do a great job of communicating and creating a chain of command to help simplify complex problems\\no Its important to remember the values of the fire service and keep those in mind whenever conflicts arise.\\no Tie in stats and figures from your research on the department.'},\n", + " {'id': 4,\n", + " 'theme': 'Stress Questions',\n", + " 'context': 'My big takeaway is that stress is everywhere, and it affects everyone in different ways.\\n- The amount of mental health issues and stress levels are up exponentially with the community.\\n- Especially when you factor in the effects of COVID-19 and the lockdowns.\\n- That _________ situation made me realize that we must be supportive of one another and reduce the stigma.\\n- Potential Conclusions:\\no I know that the team members at _______ Fire are exposed to stressful situations on a regular basis, and it is critical that they be supportive to one another in order to maintain a strong team.\\no I have spoken to ______ about your mental health programs and can see that you really take the time to pour into each of your firefighter’s cup. I really admire that.\\no I looked into that _________ program that your department us'},\n", + " {'id': 5,\n", + " 'theme': 'Emergency Questions',\n", + " 'context': 'Emergencies can happen anywhere at anytime.\\n- Usually with little to no warning.\\n- During those times people fall back onto their training and most commonly practiced strategies.\\n- We need to ensure that our personnel are available and ready to answer the call whenever that happens in the community, and they are using the most effective strategies and techniques possible.\\n- Potential Conclusions:\\no I know that the expectation of _______ Fire is to train at least 2-3 hours per shift.\\no That works out to 14-21 hours per month. When you factor in running calls in between those training sessions there is a fair bit of opportunity for Firefighters to become very good at their jobs and be fully prepared.\\no Consistent commitment to training everything from the basics up to the complicated things 2-3 hours per shift is what makes the people on _____ Fire so good at their job.'},\n", + " {'id': 6,\n", + " 'theme': 'Mistake',\n", + " 'context': 'We all make mistakes. It is okay to make them. But it is not okay to not learn from them.\\n- Mistakes are just proof that you are trying your best.\\n- They are an opportunity for growth and for development.\\n- They are the things that help sharpen the knives in a drawer.\\n- The key is not to make the same mistake twice.\\n- Potential Conclusions:\\no I am certain that _______ Firefighters conduct regular follow-ups after calls.\\no Its important for everyone to check their ego and be accountable for the things they messed up on.\\no I know that Chief ______ promotes an open and transparent environment. He/She is not afraid to admit when they made a mistake. So, it is important for everyone in the department to follow suit.'},\n", + " {'id': 7,\n", + " 'theme': 'Cultural, Diversity, and Inclusion Questions',\n", + " 'context': 'Communities are becoming more and more diverse everyday. It is important for the Fire Service to recognize that.\\n- Steps can be taken every single day to create an environment that is inclusive and open to everyone regardless of their background, language, abilities, or self-identification.\\n- Public servants serve the public.\\n- No passing judgement on people. No racism, no homophobia, no misogyny.\\n- Treat everyone with respect and educate ourselves about the differences in our communities.\\n- Potential Conclusions:\\no ______ Fire is very professional and respectful. I have only seen and heard good things about how much of a concerted effort you are making to be more inclusive.\\no I spent some time looking at the Public Education pamphlets at station _____ and saw that they were offered in a bunch of different languages. That was amazing and I really think that shows the community how much you care about reducing the barriers to safety.\\no I spoke with _____ and learned about how enjoyable of an experience they have had working on your departmen'},\n", + " {'id': 8,\n", + " 'theme': 'Customer Service Questions',\n", + " 'context': 'Providing great customer service really just requires caring about people and trying to always make things better than you found it.\\n- Our communities are better served when they have people that are willing to sacrifice their time and energy.\\n- I personally enjoy going to places and working with people that provide great customer service. I would only expect that to be the level of service provided by firefighters.\\n- Potential Conclusions:\\no You can’t train people to care and its important for the fire service to hire people who innately have a desire to go the extra mile. It has to be in their DNA.\\no I know that _____ Fire has done a great job finding lots of those types of people and they constantly work towards fostering that characteristic in everyone brought into the organization.\\no Firefighters go above and beyond every shift. Its our job to serve the community and protect life, property'},\n", + " {'id': 9,\n", + " 'theme': 'Successful and Unsuccessful Team Questions',\n", + " 'context': 'Teamwork is necessary to assist in overcoming emergencies. Especially expanding ones. I understand how chain of commands works and the importance of monitoring the span of control as well.\\n- Great teamwork creates synergy in the workplace and makes environments happier, healthier, and safer.\\n- There is no “I†in team.\\n- All tasks are important no matter how big or small it may seem.\\n- Great teams are built by people that are committed to training and knowing their roles well.\\n- Need to train in order to create muscle memory and prevent “skills fadeâ€\\n- Potential Conclusions:\\no I know that Firefighting is a team sport and that _____ Fire does a great job in fostering that camaraderie.\\no I have seen the _____ Fire team play in _____ tournament and know that you guys applaud crews bonding over meals at the station.\\no I really appreciate the fact that you allow crews to train together and share insights learned across the department so that everyone gets better all the time.\\no Include stats and figures, following SOPs and safety protocols into the answer'},\n", + " {'id': 10,\n", + " 'theme': 'Disagree with a Supervisor Questions',\n", + " 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'},\n", + " {'id': 11,\n", + " 'theme': 'Rule Bending',\n", + " 'context': 'I do not bend rules that jeopardize health and safety or rules that test my ethics and morality.\\n- I know that the fire service has that same perspective.\\n- Therefore, all organizations need to have rules and all people in those organizations need to know them.\\n- This is why there are internal SOPs, OHSA, HTA, Fire Code, Criminal Code etc.\\n- Potential Conclusions:\\no I know that _____ Fire has a robust SOP package, and it is part of the training process for every new hire to go through them and get schooled up on the importance of them.\\no The onus is on me to spend time learning the ins and outs of this organization if I am blessed with the opportunity to work here.\\no Firefighters need to be rule followers. It is an inherently dangerous job and freelancing has no part o.'},\n", + " {'id': 12,\n", + " 'theme': 'Integrity Challenge Questions',\n", + " 'context': 'Integrity is the cornerstone of the fire service profession, guiding every action and decision.\\n- Firefighters are entrusted with public safety, making it imperative to uphold the highest ethical standards.\\n- In the fire service, we are governed by regulations such as the NFPA standards and the Ontario FPPA, which mandate strict compliance to ensure safety and well-being.\\n- These guidelines underscore the need for transparency and ethical conduct in all our actions.\\n- Potential Conclusions:\\no Integrity is not just a personal attribute; it is a professional necessity that ensures the effectiveness and reliability of our fire service operations.\\no When faced with an integrity challenge, it is essential to remain steadfast in ethical principles, even under pressure.\\no This experience reinforced my commitment to the values of the fire service and highlighted the importance of fostering a culture where integrity is paramount.\\no By upholding these standards, we not only protect ourselves and our colleagues but also maintain the trust and confidence of the communities we serve.'},\n", + " {'id': 13,\n", + " 'theme': 'Taking a Shortcut at work',\n", + " 'context': \"I believe in having strong work ethic. I was raised that way and my work experience to date proves that…\\n- I definitely do not take shortcuts around things that compromise health and safety or my ethics and morality.\\n- I never take shortcuts that compromise the health and safety of myself or others, or that challenge my ethical and moral values.\\n- I believe that the fire service shares this same perspective, prioritizing safety, ethics, and morality above all else.\\n- In my view, all organizations should establish clear rules, and it is essential for every member of those organizations to be aware of and follow these rules.\\n- This is why organizations have internal Standard Operating Procedures (SOPs), Occupational Health and Safety Act (OHSA) guidelines, Highway Traffic Act (HTA) regulations, Fire Codes, and even the Criminal Code when necessary.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they have a comprehensive set of Standard Operating Procedures (SOPs) that are diligently followed. During my training, I learned about the critical importance of these procedures and the reasons for adhering to them.\\no If I were fortunate enough to join this organization, I understand that it would be my responsibility to thoroughly acquaint myself with its rules and procedures. I'm committed to investing the necessary time and effort to ensure I comply with them.\\no In firefighting, there's no room for shortcuts. It's an inherently perilous job and deviating from established procedures can jeopardize lives. Rules are not just guidelines but safeguards that protect everyone and ensure a safe return from each mission.\"},\n", + " {'id': 14,\n", + " 'theme': 'Delivering Difficult Messages',\n", + " 'context': \"I do not shy away from the responsibility of delivering difficult messages when necessary, even though it may be uncomfortable. My commitment to honesty and ethical conduct remains unwavering.\\n- I believe that the fire service, like any responsible organization, understands the importance of addressing challenging issues head-on, which aligns with my perspective on this matter.\\n- In all organizations, there should be clear protocols and guidelines for delivering difficult messages effectively and sensitively, ensuring that the message is conveyed while respecting the dignity and feelings of the recipients.\\n- This is why organizations often have established procedures and communication guidelines to handle such situations professionally and ethically.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they prioritize open and honest communication. During my training, I learned about their approach to delivering difficult messages and the importance of doing so with empathy and professionalism.\\no If I were part of this organization, I would understand that delivering difficult messages might be a part of my role. I would be committed to following their established protocols and guidelines for addressing such situations.\\no In firefighting and similar high-stakes professions, effective communication, even in challenging circumstances, can be a matter of life and death. The rules and procedures in place are not just about following a script but ensuring that messages are conveyed in a way that respects the emotions and well-being of all involved parties.\"},\n", + " {'id': 15,\n", + " 'theme': 'Not Following SOPs/SOGs',\n", + " 'context': \"I have never deviated from established SOPs at work, as doing so can compromise safety, ethical standards, and the integrity of the organization.\\n- I understand that the fire service, like any responsible organization, places a high value on adherence to SOPs, which is consistent with my perspective.\\n- In every organization, it's crucial to have clear and well-documented SOPs that every member understands and follows. This ensures consistency, safety, and ethical conduct.\\n- This is why organizations implement internal SOPs and adhere to external regulations like OHSA, HTA, and Fire Codes to maintain high standards of operation.\\n- Potential conclusions:\\no I'm aware that at _____ Fire, strict adherence to SOPs is fundamental to their operational success. During my training, I gained a deep appreciation for the importance of following these procedures and the consequences of not doing so.\\no If I were to become part of this organization, I would fully understand the gravity of following SOPs. I would uphold these standards and would actively seek training and support to ensure compliance.\\no In firefighting and similar high-risk professions, disregarding SOPs is simply not an option. These procedures are in place to protect lives and property. Any deviation can have serious consequences, and rule adherence is non-negotiable.\"},\n", + " {'id': 16,\n", + " 'theme': 'Continuous Improvement',\n", + " 'context': \"Continuous improvement is about striving to be better every day, both as an individual and as part of a team.\\n- I believe that the fire service embodies this concept by constantly evolving through training, adopting new technologies, and learning from past experiences.\\n- Reflecting on one's performance and seeking feedback are essential components of continuous improvement, as they help identify strengths and areas for growth.\\n- Staying updated with new firefighting techniques, equipment, and regulations is crucial for maintaining effectiveness and safety in the field.\\n- Potential Conclusions:\\no I've seen how ______ Fire prioritizes ongoing training and professional development to ensure its firefighters remain at the forefront of the profession. I look forward to being part of an organization that values growth and innovation.\\no During my station visit, I was impressed by the emphasis on learning and improvement at ______ Fire. That environment aligns perfectly with my personal commitment to always better myself and support my team in doing the same.\\no I believe continuous improvement is not just about improving skills but also about fostering a culture where everyone strives to do better. At ______ Fire, I’m eager to contribute to that culture by embracing challenges, seeking feedback, and pursuing opportunities for growth.\"},\n", + " {'id': 17,\n", + " 'theme': 'Handling Sensitive Information',\n", + " 'context': 'Firefighters are often entrusted with sensitive information, whether it pertains to medical calls, emergency incidents, or personal details about community members.\\n- Maintaining confidentiality and discretion is critical for preserving trust and ensuring the dignity of individuals involved.\\n- Handling sensitive information responsibly requires understanding and adhering to organizational policies, as well as exercising sound judgment.\\n- Respecting privacy is a key component of professionalism, especially in a role as visible and impactful as firefighting.\\n- Potential Conclusions:\\no I understand that ______ Fire has clear guidelines and training around handling sensitive information. I respect and appreciate the importance of these protocols and would adhere to them without compromise.\\no If given the opportunity to join ______ Fire, I would uphold the highest standards of confidentiality and discretion, ensuring that sensitive information is treated with the respect it deserves.\\no Handling sensitive information with care is essential to maintaining the trust of the community and the integrity of the fire service. I’m committed to embodying these values and ensuring that all information is managed professionally and ethically.'},\n", + " {'id': 18,\n", + " 'theme': 'Solving a Problem',\n", + " 'context': \"I believe problem-solving is one of the most valuable skills in the fire service, as it often determines the success or failure of a critical situation.\\n- Effective problem-solving requires a clear assessment of the situation, evaluating available resources, and making informed decisions quickly.\\n- Firefighting often involves scenarios where unexpected challenges arise, and the ability to stay calm and address issues methodically is essential.\\n- Collaboration is a significant part of problem-solving, as no one firefighter has all the answers. Solutions come from teamwork and leveraging everyone's strengths.\\n- Potential Conclusions:\\no I understand that ______ Fire emphasizes critical thinking and problem-solving in their training programs. During my training, I honed these skills and learned how to approach challenges systematically and effectively.\\no If I were part of ______ Fire, I would actively apply my problem-solving abilities in both emergency and non-emergency situations, ensuring I work collaboratively with my team to find the best outcomes.\\no Solving problems in firefighting goes beyond emergencies; it's about addressing challenges proactively, whether it's equipment maintenance, community outreach, or operational efficiency. I'm committed to contributing to this problem-solving culture at ______ Fire.\"},\n", + " {'id': 19,\n", + " 'theme': 'Challenge Questions',\n", + " 'context': 'Life is full of challenges. It is important for firefighters to be the type of people that take those challenges head on and constantly work to find ways to overcome them.\\n- Grit, persistence, creative problem solving, and strong mental health are the keys to overcoming challenges.\\n- Life can change in a second. Its important to be adaptive and flexible.\\n- Potential Conclusions:\\no And I am certain that ______ Fire works very hard to meet every challenge and then overcome them.\\no I think about how you guys handled the ________ situation\\no or the recent fire at _______\\no and as an outsider looking in, I was thoroughly impressed with the way the department handled it.'}]" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "themes" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'General Competency Questions': [{'id': 1,\n", + " 'question': 'Why do you want to be a firefighter?'},\n", + " {'id': 2,\n", + " 'question': 'What have you done to prepare for a career in the Fire Service?'},\n", + " {'id': 3, 'question': 'Why do you want to work for this department?'},\n", + " {'id': 4,\n", + " 'question': 'Name some of the traits, characteristics, or attributes of a good firefighter.'},\n", + " {'id': 5,\n", + " 'question': 'What are some of the biggest challenges faced by the Fire Service today?'},\n", + " {'id': 6,\n", + " 'question': 'Describe the emergency vs. non-emergency duties of a firefighter.'},\n", + " {'id': 7, 'question': 'Where do you see yourself in 1, 5, 10, 20 years?'},\n", + " {'id': 8, 'question': 'Describe the chain of command and your role in it.'},\n", + " {'id': 9,\n", + " 'question': 'How do you handle stress, now and once you have the job?'},\n", + " {'id': 10,\n", + " 'question': 'How do you think the role of the firefighter will be different in 5 years?'},\n", + " {'id': 11,\n", + " 'question': 'What is the organizational structure of our Fire Department?'},\n", + " {'id': 12,\n", + " 'question': 'Why do you think honesty and integrity are important in the Fire Service?'},\n", + " {'id': 13,\n", + " 'question': 'What are the advantages and disadvantages of similar vs diverse teams?'},\n", + " {'id': 14,\n", + " 'question': 'List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.'},\n", + " {'id': 15, 'question': 'What is the most important duty of a firefighter?'},\n", + " {'id': 16, 'question': 'What does leadership mean to you?'},\n", + " {'id': 17,\n", + " 'question': 'What do you like most and least about a supervisor?'},\n", + " {'id': 18, 'question': 'What do you appreciate in a manager’s style?'},\n", + " {'id': 19,\n", + " 'question': 'What are the six common leadership styles in the Fire Service?'},\n", + " {'id': 20,\n", + " 'question': 'What do you like most and least about being a firefighter?'},\n", + " {'id': 21, 'question': 'How does diversity impact the Fire Service today?'},\n", + " {'id': 22,\n", + " 'question': 'How would you make a positive impact regarding the diversity in the community?'},\n", + " {'id': 23,\n", + " 'question': 'Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?'},\n", + " {'id': 24,\n", + " 'question': 'Public Education is important in the Fire Service. How would you provide this service?'},\n", + " {'id': 25,\n", + " 'question': 'You are a probationary firefighter. How do you prepare yourself?'},\n", + " {'id': 26,\n", + " 'question': 'Why is respect so important, and what does it mean?'},\n", + " {'id': 27, 'question': 'Would you break a rule if asked to?'},\n", + " {'id': 28,\n", + " 'question': 'What are potential sources of workplace conflict? How would you handle workplace conflict?'},\n", + " {'id': 29, 'question': 'Why should we hire you?'},\n", + " {'id': 30,\n", + " 'question': 'What are your strengths and weaknesses? (What would your boss say about you?)'},\n", + " {'id': 31,\n", + " 'question': 'How do you want to be remembered at the end of your career?'},\n", + " {'id': 32, 'question': 'What skills do you bring to Dispatch?'},\n", + " {'id': 33, 'question': 'Walk me through a truck check.'},\n", + " {'id': 34,\n", + " 'question': 'How do you define teamwork in the context of firefighting?'},\n", + " {'id': 35,\n", + " 'question': 'What motivates you to perform well in stressful situations?'},\n", + " {'id': 36,\n", + " 'question': 'Explain how you would handle feedback from a superior, especially if it was critical.'},\n", + " {'id': 37,\n", + " 'question': 'What is your understanding of the core values of the Fire Service?'},\n", + " {'id': 38,\n", + " 'question': 'Describe a time when you demonstrated initiative in the workplace.'},\n", + " {'id': 39,\n", + " 'question': 'How do you prioritize tasks during an emergency response?'},\n", + " {'id': 40,\n", + " 'question': 'What role does technology play in modern firefighting, and how are you prepared for it?'},\n", + " {'id': 41,\n", + " 'question': 'How would you approach learning new skills and techniques required for this job?'},\n", + " {'id': 42,\n", + " 'question': 'Explain how you balance personal and professional commitments in a demanding job.'},\n", + " {'id': 43,\n", + " 'question': 'What strategies do you use to ensure continuous improvement in your work?'},\n", + " {'id': 44,\n", + " 'question': 'How do you approach building trust and relationships within a new team?'},\n", + " {'id': 45,\n", + " 'question': 'What does a day in the life of a firefighter look like for both emergency and non-emergency activities?'}],\n", + " 'Situational Questions': [{'id': 1,\n", + " 'question': 'What would you do if a firefighter makes disparaging remarks in public about visible minorities?'},\n", + " {'id': 2,\n", + " 'question': 'What would you do if a senior firefighter is making inappropriate, unwelcomed, bullying comments towards another firefighter?'},\n", + " {'id': 3,\n", + " 'question': 'What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?'},\n", + " {'id': 4,\n", + " 'question': 'What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?'},\n", + " {'id': 5,\n", + " 'question': 'What would you do if your captain gives you a performance review that you are unhappy with?'},\n", + " {'id': 6,\n", + " 'question': 'What would you do if you saw a firefighter put a valuable item in their pocket at a call?'},\n", + " {'id': 7,\n", + " 'question': 'What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?'},\n", + " {'id': 8,\n", + " 'question': 'What would you do if you noticed two firefighters cheating on an exam?'},\n", + " {'id': 9,\n", + " 'question': 'What would you do if you see two firefighters getting heated and about to fight?'},\n", + " {'id': 10,\n", + " 'question': 'What would you do if you are confronted by an irate citizen and you are all by yourself?'},\n", + " {'id': 11,\n", + " 'question': 'What would you do if you are on your way home after a shift and see a car accident or other emergency?'},\n", + " {'id': 12,\n", + " 'question': 'What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?'},\n", + " {'id': 13,\n", + " 'question': 'What would you do if you notice one firefighter not being included in the group (e.g., coffee poured for everyone but them)?'},\n", + " {'id': 14,\n", + " 'question': \"What would you do if you are the apparatus driver and during your daily truck check you discover the emergency lights are not working, and your captain says, 'Don’t worry about it. The next crew on duty will take care of it'?\"},\n", + " {'id': 15,\n", + " 'question': 'What would you do if one member of the crew has a really negative attitude about training?'},\n", + " {'id': 16,\n", + " 'question': 'What would you do if a fellow firefighter tells you they don’t want minorities, women, or LGBTQ+ individuals in the fire service?'},\n", + " {'id': 17,\n", + " 'question': 'What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?'},\n", + " {'id': 18,\n", + " 'question': 'What would you do if you are faced with conflicting orders from two supervisors at the scene of an emergency?'}]}" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "questions" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'{\\n \"General Competency Questions\": [\\n {\\n \"id\": 1,\\n \"question\": \"Why do you want to be a firefighter?\"\\n },\\n {\\n \"id\": 2,\\n \"question\": \"What have you done to prepare for a career in the Fire Service?\"\\n },\\n {\\n \"id\": 3,\\n \"question\": \"Why do you want to work for this department?\"\\n },\\n {\\n \"id\": 4,\\n \"question\": \"Name some of the traits, characteristics, or attributes of a good firefighter.\"\\n },\\n {\\n \"id\": 5,\\n \"question\": \"What are some of the biggest challenges faced by the Fire Service today?\"\\n },\\n {\\n \"id\": 6,\\n \"question\": \"Describe the emergency vs. non-emergency duties of a firefighter.\"\\n },\\n {\\n \"id\": 7,\\n \"question\": \"Where do you see yourself in 1, 5, 10, 20 years?\"\\n },\\n {\\n \"id\": 8,\\n \"question\": \"Describe the chain of command and your role in it.\"\\n },\\n {\\n \"id\": 9,\\n \"question\": \"How do you handle stress, now and once you have the job?\"\\n },\\n {\\n \"id\": 10,\\n \"question\": \"How do you think the role of the firefighter will be different in 5 years?\"\\n },\\n {\\n \"id\": 11,\\n \"question\": \"What is the organizational structure of our Fire Department?\"\\n },\\n {\\n \"id\": 12,\\n \"question\": \"Why do you think honesty and integrity are important in the Fire Service?\"\\n },\\n {\\n \"id\": 13,\\n \"question\": \"What are the advantages and disadvantages of similar vs diverse teams?\"\\n },\\n {\\n \"id\": 14,\\n \"question\": \"List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.\"\\n },\\n {\\n \"id\": 15,\\n \"question\": \"What is the most important duty of a firefighter?\"\\n },\\n {\\n \"id\": 16,\\n \"question\": \"What does leadership mean to you?\"\\n },\\n {\\n \"id\": 17,\\n \"question\": \"What do you like most and least about a supervisor?\"\\n },\\n {\\n \"id\": 18,\\n \"question\": \"What do you appreciate in a manager\\\\u2019s style?\"\\n },\\n {\\n \"id\": 19,\\n \"question\": \"What are the six common leadership styles in the Fire Service?\"\\n },\\n {\\n \"id\": 20,\\n \"question\": \"What do you like most and least about being a firefighter?\"\\n },\\n {\\n \"id\": 21,\\n \"question\": \"How does diversity impact the Fire Service today?\"\\n },\\n {\\n \"id\": 22,\\n \"question\": \"How would you make a positive impact regarding the diversity in the community?\"\\n },\\n {\\n \"id\": 23,\\n \"question\": \"Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you\\\\u2019ll face?\"\\n },\\n {\\n \"id\": 24,\\n \"question\": \"Public Education is important in the Fire Service. How would you provide this service?\"\\n },\\n {\\n \"id\": 25,\\n \"question\": \"You are a probationary firefighter. How do you prepare yourself?\"\\n },\\n {\\n \"id\": 26,\\n \"question\": \"Why is respect so important, and what does it mean?\"\\n },\\n {\\n \"id\": 27,\\n \"question\": \"Would you break a rule if asked to?\"\\n },\\n {\\n \"id\": 28,\\n \"question\": \"What are potential sources of workplace conflict? How would you handle workplace conflict?\"\\n },\\n {\\n \"id\": 29,\\n \"question\": \"Why should we hire you?\"\\n },\\n {\\n \"id\": 30,\\n \"question\": \"What are your strengths and weaknesses? (What would your boss say about you?)\"\\n },\\n {\\n \"id\": 31,\\n \"question\": \"How do you want to be remembered at the end of your career?\"\\n },\\n {\\n \"id\": 32,\\n \"question\": \"What skills do you bring to Dispatch?\"\\n },\\n {\\n \"id\": 33,\\n \"question\": \"Walk me through a truck check.\"\\n },\\n {\\n \"id\": 34,\\n \"question\": \"How do you define teamwork in the context of firefighting?\"\\n },\\n {\\n \"id\": 35,\\n \"question\": \"What motivates you to perform well in stressful situations?\"\\n },\\n {\\n \"id\": 36,\\n \"question\": \"Explain how you would handle feedback from a superior, especially if it was critical.\"\\n },\\n {\\n \"id\": 37,\\n \"question\": \"What is your understanding of the core values of the Fire Service?\"\\n },\\n {\\n \"id\": 38,\\n \"question\": \"Describe a time when you demonstrated initiative in the workplace.\"\\n },\\n {\\n \"id\": 39,\\n \"question\": \"How do you prioritize tasks during an emergency response?\"\\n },\\n {\\n \"id\": 40,\\n \"question\": \"What role does technology play in modern firefighting, and how are you prepared for it?\"\\n },\\n {\\n \"id\": 41,\\n \"question\": \"How would you approach learning new skills and techniques required for this job?\"\\n },\\n {\\n \"id\": 42,\\n \"question\": \"Explain how you balance personal and professional commitments in a demanding job.\"\\n },\\n {\\n \"id\": 43,\\n \"question\": \"What strategies do you use to ensure continuous improvement in your work?\"\\n },\\n {\\n \"id\": 44,\\n \"question\": \"How do you approach building trust and relationships within a new team?\"\\n },\\n {\\n \"id\": 45,\\n \"question\": \"What does a day in the life of a firefighter look like for both emergency and non-emergency activities?\"\\n }\\n ],\\n \"Situational Questions\": [\\n {\\n \"id\": 1,\\n \"question\": \"What would you do if a firefighter makes disparaging remarks in public about visible minorities?\"\\n },\\n {\\n \"id\": 2,\\n \"question\": \"What would you do if a senior firefighter is making inappropriate, unwelcomed, bullying comments towards another firefighter?\"\\n },\\n {\\n \"id\": 3,\\n \"question\": \"What would you do if you believe that a fellow firefighter is unfit for duty (e.g., drugs, alcohol, medication)?\"\\n },\\n {\\n \"id\": 4,\\n \"question\": \"What would you do if you are following an order from your captain and a more senior officer gives you an alternate order?\"\\n },\\n {\\n \"id\": 5,\\n \"question\": \"What would you do if your captain gives you a performance review that you are unhappy with?\"\\n },\\n {\\n \"id\": 6,\\n \"question\": \"What would you do if you saw a firefighter put a valuable item in their pocket at a call?\"\\n },\\n {\\n \"id\": 7,\\n \"question\": \"What would you do if you noticed a fellow firefighter is not their usual self (moody, withdrawn, seething, etc.)?\"\\n },\\n {\\n \"id\": 8,\\n \"question\": \"What would you do if you noticed two firefighters cheating on an exam?\"\\n },\\n {\\n \"id\": 9,\\n \"question\": \"What would you do if you see two firefighters getting heated and about to fight?\"\\n },\\n {\\n \"id\": 10,\\n \"question\": \"What would you do if you are confronted by an irate citizen and you are all by yourself?\"\\n },\\n {\\n \"id\": 11,\\n \"question\": \"What would you do if you are on your way home after a shift and see a car accident or other emergency?\"\\n },\\n {\\n \"id\": 12,\\n \"question\": \"What would you do if you are assigned undesirable or dangerous tasks at an emergency scene or back in the station?\"\\n },\\n {\\n \"id\": 13,\\n \"question\": \"What would you do if you notice one firefighter not being included in the group (e.g., coffee poured for everyone but them)?\"\\n },\\n {\\n \"id\": 14,\\n \"question\": \"What would you do if you are the apparatus driver and during your daily truck check you discover the emergency lights are not working, and your captain says, \\'Don\\\\u2019t worry about it. The next crew on duty will take care of it\\'?\"\\n },\\n {\\n \"id\": 15,\\n \"question\": \"What would you do if one member of the crew has a really negative attitude about training?\"\\n },\\n {\\n \"id\": 16,\\n \"question\": \"What would you do if a fellow firefighter tells you they don\\\\u2019t want minorities, women, or LGBTQ+ individuals in the fire service?\"\\n },\\n {\\n \"id\": 17,\\n \"question\": \"What would you do if you respond to your first fire call, and your captain tells the crew to wear all PPE, but senior firefighters are not wearing all the necessary gear?\"\\n },\\n {\\n \"id\": 18,\\n \"question\": \"What would you do if you are faced with conflicting orders from two supervisors at the scene of an emergency?\"\\n }\\n ]\\n}'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import json\n", + "json.dumps(questions, indent=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + " " + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Disability Questions\n", + "Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\n", + "- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\n", + "- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\n", + "- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\n", + "- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\n", + "- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\n", + "- Potential Conclusions:\n", + "o I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\n", + "o I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\n", + "o I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "{\n", + " \"message\": \"Hi Erika! It's great to meet you. Let's talk about a time when you interacted with someone who had a disability, either in a professional or volunteer role. What was the situation, and how did you approach it?\",\n", + " \"end\": \"no\"\n", + "}\n", + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "{\n", + " \"message\": \"Thank you for sharing, Erika! Based on your experience as a volunteer firefighter and your training, can you describe a specific instance where you had to adapt your communication or care approach in a situation involving someone with a disability? What was your thought process behind it and how did you ensure they received the help they needed?\",\n", + " \"end\": \"no\"\n", + "}\n" + ] + } + ], + "source": [ + "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", + "current_theme = [x for x in themes if x[\"id\"] == 1][0][\"theme\"]\n", + "theme_context = [x for x in themes if x[\"id\"] == 1][0][\"context\"]\n", + "print(current_theme)\n", + "print(theme_context)\n", + "prompt_template = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"system\",\n", + " f\"\"\"You are a Fire Fighter Interview preparation assistant.\n", + "\n", + "Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you.\n", + "\n", + "### 7 Main Concepts:\n", + "- **High Performance Teams**\n", + "- **Situational Awareness**\n", + "- **Being a Great Problem Solver**\n", + "- **Customer Service**\n", + "- **Building Construction, Mechanical Aptitude**\n", + "- **Emergency Medicine Experience**\n", + "- **Mental and Physical Health**\n", + "\n", + "Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. \n", + "\n", + "We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. \n", + "\n", + "Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect?\n", + "\n", + "Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service.\n", + "\n", + "### 20 Important Themes\n", + "Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions:\n", + "- Customer Service\n", + "- Conflict\n", + "- Challenge\n", + "- Leadership\n", + "- Stress\n", + "- Successful Team\n", + "- Diversity\n", + "- Mistake\n", + "- Unsuccessful Team \n", + "- Disagreement\n", + "- Bent a Rule\n", + "- Delivered a Difficult Message\n", + "- Displayed Integrity\n", + "- Took a Shortcut\n", + "- Didn’t Follow the Rules\n", + "- Emergency Response\n", + "- Dealt with Disabilities\n", + "- Solved a Big Problem\n", + "- Continuous Improvement\n", + "- Handled Sensitive Information\n", + "\n", + "### Behavioral Question Starters\n", + "Behavioral questions usually start with phrases like:\n", + "- “Tell me a time when…â€\n", + "- “Can you tell me about a time when you…â€\n", + "- \"Describe a situation where you had to…\"\n", + "- \"Give me an example of how you…\"\n", + "- \"Have you ever been in a position where you needed to…\"\n", + "- \"Walk me through a time when you…\"\n", + "\n", + "Your goal is to engage in conversation with the user. You will be provided with the current theme, the resume of the user, and example general competency questions and behavioral questions.\n", + "\n", + "\n", + "### STARTPOP Framework\n", + "The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. \n", + "\n", + "Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life.\n", + "\n", + "#### Components of STARTPOP:\n", + "1. **Situation**: \n", + " - Set up the answer in the mind of the question asker. \n", + " - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long).\n", + " - Include dates, ages, places, and circumstances.\n", + "\n", + "2. **Task**: \n", + " - Explain what you needed to do and why you needed to do it.\n", + " - Recap the situation quickly from a different angle.\n", + "\n", + "3. **Actions**: \n", + " - Outline both the negative and the positive way of doing things.\n", + " - Show high moral character in every question.\n", + "\n", + "4. **Results**: \n", + " - Explain what happened as a result of your actions.\n", + " - Share results in a time-specific manner (e.g., “5 months later X happenedâ€).\n", + "\n", + "5. **Transitions**: \n", + " - Speak in a way that aligns with professional expectations.\n", + " - Ensure coherence in your responses.\n", + "\n", + "6. **Personal Lessons**: \n", + " - Discuss what you learned about yourself.\n", + " - Address any concerns the interviewers might have about hiring you.\n", + "\n", + "7. **Other People Observations**: \n", + " - Share insights about others in the situation.\n", + " - Keep it short and to the point.\n", + "\n", + "8. **Professional Connection**: \n", + " - Relate your experience directly to the fire service.\n", + " - Conclude strongly, avoiding phrases like “and so yeah…â€.\n", + "\n", + " Current theme {str(current_theme)}\n", + "\n", + " More context about the theme for Creating The Professional Connection (Lessons Learned): {str(theme_context)}\n", + "\n", + " \n", + "\n", + "Your task is to engage the user in conversation, ask relevant questions, that will ultimately help them prepare a strong STARTPOP response based on their experiences and the current theme.\n", + "YOU WILL BE PROVIDED WITH THE USER RESUME, ASK 1 QUESTION AT A TIME AND MAKE IT CONVERSATIONAL AND INTERESTING.\n", + "These responses will be saved and later used to generate a STARTPOP framework by US (DO NOT WORRY ABOUT THAT, WE WILL BE THE ONE TO GENERATE, JUST ENGAGE USER WITH QUESTION AND ANSWER).\n", + "Output format\n", + "\n", + "WILL BE IN JSON\n", + " message:\n", + " end: \"yes\" or \"no\" if you are done with asking questions and confident the responses are okay enough to prepare STARTPOP by us\n", + "\n", + "\"\"\",\n", + " ),\n", + " MessagesPlaceholder(variable_name=\"messages\"),\n", + " ]\n", + ")\n", + "\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.graph import START, MessagesState, StateGraph\n", + "workflow = StateGraph(state_schema=MessagesState)\n", + "\n", + "def call_model(state: MessagesState):\n", + " prompt = prompt_template.invoke(state)\n", + " response = model.invoke(prompt)\n", + " return {\"messages\": response}\n", + "\n", + "\n", + "workflow.add_edge(START, \"model\")\n", + "workflow.add_node(\"model\", call_model)\n", + "\n", + "memory = MemorySaver()\n", + "app = workflow.compile(checkpointer=memory)\n", + "\n", + "\n", + "config = {\"configurable\": {\"thread_id\": \"abc345\"}}\n", + "resume = f\"Resume {str(docs)}\"\n", + "cont = f\"Example general competency and behavioural questions {json.dumps(questions, indent=2)}\"\n", + "input_messages = [HumanMessage(resume)]\n", + "output = app.invoke({\"messages\": input_messages}, config)\n", + "output[\"messages\"][-1].pretty_print()\n", + "\n", + "input_messages = [HumanMessage(cont)]\n", + "output = app.invoke({\"messages\": input_messages}, config)\n", + "output[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "def format_questions_text(questions_dict,key):\n", + " \"\"\"Format questions as text with dashes.\"\"\"\n", + " formatted_text = \"\"\n", + " for question in questions_dict[key]:\n", + " formatted_text += f\"- {question['question']}\\n\"\n", + " return formatted_text.strip()\n", + "key = 'General Competency Questions'\n", + "formatted_questions = format_questions_text(questions,key)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'- Why do you want to be a firefighter?\\n- What have you done to prepare for a career in the Fire Service?\\n- Why do you want to work for this department?\\n- Name some of the traits, characteristics, or attributes of a good firefighter.\\n- What are some of the biggest challenges faced by the Fire Service today?\\n- Describe the emergency vs. non-emergency duties of a firefighter.\\n- Where do you see yourself in 1, 5, 10, 20 years?\\n- Describe the chain of command and your role in it.\\n- How do you handle stress, now and once you have the job?\\n- How do you think the role of the firefighter will be different in 5 years?\\n- What is the organizational structure of our Fire Department?\\n- Why do you think honesty and integrity are important in the Fire Service?\\n- What are the advantages and disadvantages of similar vs diverse teams?\\n- List in order of importance: Emergency Response, Public Education, Fire Standards/Enforcement.\\n- What is the most important duty of a firefighter?\\n- What does leadership mean to you?\\n- What do you like most and least about a supervisor?\\n- What do you appreciate in a manager’s style?\\n- What are the six common leadership styles in the Fire Service?\\n- What do you like most and least about being a firefighter?\\n- How does diversity impact the Fire Service today?\\n- How would you make a positive impact regarding the diversity in the community?\\n- Firefighters work 24-hour shifts. How have you prepared, and what challenges do you think you’ll face?\\n- Public Education is important in the Fire Service. How would you provide this service?\\n- You are a probationary firefighter. How do you prepare yourself?\\n- Why is respect so important, and what does it mean?\\n- Would you break a rule if asked to?\\n- What are potential sources of workplace conflict? How would you handle workplace conflict?\\n- Why should we hire you?\\n- What are your strengths and weaknesses? (What would your boss say about you?)\\n- How do you want to be remembered at the end of your career?\\n- What skills do you bring to Dispatch?\\n- Walk me through a truck check.\\n- How do you define teamwork in the context of firefighting?\\n- What motivates you to perform well in stressful situations?\\n- Explain how you would handle feedback from a superior, especially if it was critical.\\n- What is your understanding of the core values of the Fire Service?\\n- Describe a time when you demonstrated initiative in the workplace.\\n- How do you prioritize tasks during an emergency response?\\n- What role does technology play in modern firefighting, and how are you prepared for it?\\n- How would you approach learning new skills and techniques required for this job?\\n- Explain how you balance personal and professional commitments in a demanding job.\\n- What strategies do you use to ensure continuous improvement in your work?\\n- How do you approach building trust and relationships within a new team?\\n- What does a day in the life of a firefighter look like for both emergency and non-emergency activities?'" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "formatted_questions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Let's focus on the Customer Service theme first. Can you tell me about a time when you provided exceptional customer service, perhaps in your role as a firefighter or while working at Starbucks? What was the situation like?\n", + "False\n", + "```json\n", + "{\n", + " \"message\": \"That's great to hear! It sounds like you had a positive impact on your customers. Can you share a specific example of a situation where you went above and beyond to ensure a customer had a great experience?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"That's an excellent approach! Paying attention to detail and proactively asking customers what they need is crucial for great service. Can you tell me about a specific interaction where your attention to detail made a difference for a customer?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems you did not respond. If you're comfortable, let's continue discussing your customer service experiences. Can you recall a specific situation where your efforts were particularly appreciated by a customer?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"Hi! How can I assist you today? Are you ready to continue preparing for your firefighter interview?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"Great! Let's pick up where we left off. Can you share an example of a time you faced a challenge in your firefighting volunteer work? What was the situation, and how did you handle it?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems you've not responded. If you'd like to continue focusing on your interview preparation, can you tell me about a challenge you faced during your firefighting experience and how you managed it?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"I see you haven’t responded. If you need more time or want to discuss a different aspect of your interview preparation, just let me know! Are there any specific topics you’d like to cover?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems we have not connected in a while. If you're ready to continue your interview preparation, or if there's anything specific you'd like to focus on, please let me know!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"I see you may not be ready to continue right now. Whenever you're ready to resume or if you have any questions, feel free to reach out. I'm here to help!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems there might have been a typing error. If you have specific questions or topics to cover regarding your interview preparation, please share, and I'll be glad to assist!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"I see you're not responding right now. Whenever you're ready to continue, just let me know. I'm here to support you with your interview preparation!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems you might need more time. If you have any questions in the future or want to continue preparing for your interview, feel free to reach out anytime!\",\n", + " \"end\": \"yes\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"Of course! If you need to return for more practice or have questions later, feel free to reach out. Good luck with your interview!\",\n", + " \"end\": \"yes\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"Hi Erika! Let's start preparing your responses for the interview. Can you tell me about a time when you had to deliver a difficult message to a team member or during a situation related to your firefighting volunteer work?\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"It seems there hasn’t been a response. If you'd like to continue with your interview preparation, feel free to share a topic or question you'd like to discuss!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n", + "```json\n", + "{\n", + " \"message\": \"Hi there! If you're ready to dive back into your interview preparation, just let me know what aspect you'd like to focus on today!\",\n", + " \"end\": \"no\"\n", + "}\n", + "```\n" + ] + } + ], + "source": [ + "import json\n", + "from typing import List, Dict, Optional\n", + "from dataclasses import dataclass\n", + "from pathlib import Path\n", + "from datetime import datetime\n", + "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", + "from langchain_core.messages import HumanMessage, AIMessage\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.graph import START, MessagesState, StateGraph\n", + "\n", + "@dataclass\n", + "class Message:\n", + " role: str # 'human' or 'ai'\n", + " content: str\n", + " timestamp: str\n", + "\n", + "class FirefighterInterviewAssistant:\n", + " def __init__(self, model, conversation_storage_path: str = \"conversations.json\"):\n", + " \"\"\"\n", + " Initialize the Firefighter Interview Assistant.\n", + " \n", + " Args:\n", + " model: ChatOpenAI model instance\n", + " conversation_storage_path: Path to the JSON file storing conversations\n", + " \"\"\"\n", + " self.storage_path = Path(conversation_storage_path)\n", + " self.current_theme: Optional[Dict] = None\n", + " self.current_resume: Optional[str] = None\n", + " self.model = model\n", + " \n", + " # Initialize storage file if it doesn't exist\n", + " if not self.storage_path.exists():\n", + " self._save_conversations({})\n", + " \n", + " # Initialize LangGraph components\n", + " self.workflow = StateGraph(state_schema=MessagesState)\n", + " self.memory = MemorySaver()\n", + " \n", + " # Set up the prompt template\n", + " self.prompt_template = ChatPromptTemplate.from_messages([\n", + " (\n", + " \"system\",\n", + " f\"\"\"\n", + " You are a Fire Fighter Interview preparation assistant.\n", + "\n", + "Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you.\n", + "\n", + "### 7 Main Concepts:\n", + "- **High Performance Teams**\n", + "- **Situational Awareness**\n", + "- **Being a Great Problem Solver**\n", + "- **Customer Service**\n", + "- **Building Construction, Mechanical Aptitude**\n", + "- **Emergency Medicine Experience**\n", + "- **Mental and Physical Health**\n", + "\n", + "Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. \n", + "\n", + "We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. \n", + "\n", + "Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect?\n", + "\n", + "Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service.\n", + "\n", + "### 20 Important Themes\n", + "Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions:\n", + "- Customer Service\n", + "- Conflict\n", + "- Challenge\n", + "- Leadership\n", + "- Stress\n", + "- Successful Team\n", + "- Diversity\n", + "- Mistake\n", + "- Unsuccessful Team \n", + "- Disagreement\n", + "- Bent a Rule\n", + "- Delivered a Difficult Message\n", + "- Displayed Integrity\n", + "- Took a Shortcut\n", + "- Didn’t Follow the Rules\n", + "- Emergency Response\n", + "- Dealt with Disabilities\n", + "- Solved a Big Problem\n", + "- Continuous Improvement\n", + "- Handled Sensitive Information\n", + "\n", + "### Behavioral Question Starters\n", + "Behavioral questions usually start with phrases like:\n", + "- “Tell me a time when…â€\n", + "- “Can you tell me about a time when you…â€\n", + "- \"Describe a situation where you had to…\"\n", + "- \"Give me an example of how you…\"\n", + "- \"Have you ever been in a position where you needed to…\"\n", + "- \"Walk me through a time when you…\"\n", + "\n", + "Your goal is to engage in conversation with the user. You will be provided with the current theme, the resume of the user, and example general competency questions and behavioral questions.\n", + "\n", + "\n", + "### STARTPOP Framework\n", + "The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. \n", + "\n", + "Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life.\n", + "\n", + "#### Components of STARTPOP:\n", + "1. **Situation**: \n", + " - Set up the answer in the mind of the question asker. \n", + " - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long).\n", + " - Include dates, ages, places, and circumstances.\n", + "\n", + "2. **Task**: \n", + " - Explain what you needed to do and why you needed to do it.\n", + " - Recap the situation quickly from a different angle.\n", + "\n", + "3. **Actions**: \n", + " - Outline both the negative and the positive way of doing things.\n", + " - Show high moral character in every question.\n", + "\n", + "4. **Results**: \n", + " - Explain what happened as a result of your actions.\n", + " - Share results in a time-specific manner (e.g., “5 months later X happenedâ€).\n", + "\n", + "5. **Transitions**: \n", + " - Speak in a way that aligns with professional expectations.\n", + " - Ensure coherence in your responses.\n", + "\n", + "6. **Personal Lessons**: \n", + " - Discuss what you learned about yourself.\n", + " - Address any concerns the interviewers might have about hiring you.\n", + "\n", + "7. **Other People Observations**: \n", + " - Share insights about others in the situation.\n", + " - Keep it short and to the point.\n", + "\n", + "8. **Professional Connection**: \n", + " - Relate your experience directly to the fire service.\n", + " - Conclude strongly, avoiding phrases like “and so yeah…â€.\n", + " Current theme with More context about the theme for Creating The Professional Connection (Lessons Learned): {self.current_theme}\n", + " \n", + "Sample General Competency QUESTIONS and Situational Questions: {format_questions_text(questions,'General Competency Questions')}\n", + "Sample Situational Questions: {format_questions_text(questions,'Situational Questions')}\n", + "\n", + "Your task is to engage the user in conversation, ask relevant questions, that will ultimately help them prepare a strong STARTPOP response based on their experiences and the current theme.\n", + "YOU WILL BE PROVIDED WITH THE USER RESUME, ASK 1 QUESTION AT A TIME AND MAKE IT CONVERSATIONAL AND INTERESTING.\n", + "These responses will be saved and later used to generate a STARTPOP framework by US (DO NOT WORRY ABOUT THAT, WE WILL BE THE ONE TO GENERATE, JUST ENGAGE USER WITH QUESTION AND ANSWER).\n", + "Output format\n", + "\n", + "WILL BE IN JSON, avoid puttting ```json, before or after , return the excat json with nothing else\n", + " message:\n", + " end: \"yes\" or \"no\" if you are done with asking questions and confident the responses are okay enough to prepare STARTPOP by us\n", + "NOTE: DO NOT KEEP THE CONVERSATION , CAREFULL ANALYZE USER RESUME AND THE PROVIDED EXAMPLES QUESTIONS AND ALL CONTEXT , ASK RELEVANT QUESTION BASED ON THE THEME AND THAT IS ALL \n", + "\"\"\"\n", + " ),\n", + " MessagesPlaceholder(variable_name=\"messages\")\n", + " ])\n", + " \n", + " # Set up LangGraph workflow\n", + " self._setup_workflow()\n", + "\n", + " def _setup_workflow(self):\n", + " \"\"\"Setup LangGraph workflow\"\"\"\n", + " def call_model(state: MessagesState):\n", + " prompt = self.prompt_template.invoke(state)\n", + " response = self.model.invoke(prompt)\n", + " return {\"messages\": response}\n", + "\n", + " self.workflow.add_edge(START, \"model\")\n", + " self.workflow.add_node(\"model\", call_model)\n", + " self.app = self.workflow.compile(checkpointer=self.memory)\n", + "\n", + " def _convert_to_langchain_messages(self, messages: List[Message]) -> List[HumanMessage | AIMessage]:\n", + " \"\"\"Convert our Message objects to LangChain message objects\"\"\"\n", + " converted_messages = []\n", + " for msg in messages:\n", + " if msg.role == \"human\":\n", + " converted_messages.append(HumanMessage(content=msg.content))\n", + " else:\n", + " converted_messages.append(AIMessage(content=msg.content))\n", + " return converted_messages\n", + "\n", + " def start_conversation(self, conversation_id: str, resume: str, theme: Dict) -> Dict:\n", + " \"\"\"\n", + " Start a new conversation or load an existing one.\n", + " \"\"\"\n", + " self.current_conversation_id = conversation_id\n", + " self.current_resume = resume\n", + " self.current_theme = theme\n", + " \n", + " # Initialize conversation in storage\n", + " conversations = self._load_conversations()\n", + " if conversation_id not in conversations:\n", + " conversations[conversation_id] = {\n", + " \"resume\": resume,\n", + " \"theme\": theme,\n", + " \"messages\": []\n", + " }\n", + " self._save_conversations(conversations)\n", + " \n", + " # Initialize conversation with resume\n", + " config = {\"configurable\": {\"thread_id\": conversation_id}}\n", + " input_messages = [HumanMessage(content=f\"Resume: {resume}\")]\n", + " output = self.app.invoke({\"messages\": input_messages}, config)\n", + " \n", + " # Parse and store initial response\n", + " response = self._parse_ai_response(output[\"messages\"][-1].content)\n", + " self.add_message(\"ai\", response[\"message\"])\n", + " \n", + " return response\n", + "\n", + " def process_user_response(self, user_message: str) -> Dict:\n", + " \"\"\"\n", + " Process user response and generate AI response.\n", + " \"\"\"\n", + " # Add user message to conversation\n", + " self.add_message(\"human\", user_message)\n", + " \n", + " # Get conversation history and convert to LangChain messages\n", + " history = self.get_conversation_history()\n", + " messages = self._convert_to_langchain_messages(history)\n", + " \n", + " # Generate response using LangGraph\n", + " config = {\"configurable\": {\"thread_id\": self.current_conversation_id}}\n", + " output = self.app.invoke({\"messages\": messages}, config)\n", + " \n", + " # Parse and store AI response\n", + " response = self._parse_ai_response(output[\"messages\"][-1].content)\n", + " self.add_message(\"ai\", response[\"message\"])\n", + " \n", + " return response\n", + "\n", + " def _parse_ai_response(self, content: str) -> Dict:\n", + " \"\"\"Parse AI response content into expected format\"\"\"\n", + " try:\n", + " response = json.loads(content)\n", + " return {\n", + " \"message\": response.get(\"message\", \"\"),\n", + " \"end\": response.get(\"end\", \"no\") == \"yes\"\n", + " }\n", + " except json.JSONDecodeError:\n", + " return {\n", + " \"message\": content,\n", + " \"end\": False\n", + " }\n", + "\n", + " def add_message(self, role: str, content: str) -> None:\n", + " \"\"\"Add a message to the conversation history\"\"\"\n", + " if not hasattr(self, 'current_conversation_id'):\n", + " raise ValueError(\"No active conversation. Call start_conversation first.\")\n", + " \n", + " message_data = {\n", + " \"role\": role,\n", + " \"content\": content,\n", + " \"timestamp\": datetime.now().isoformat()\n", + " }\n", + " \n", + " conversations = self._load_conversations()\n", + " conversations[self.current_conversation_id][\"messages\"].append(message_data)\n", + " self._save_conversations(conversations)\n", + "\n", + " def get_conversation_history(self, conversation_id: Optional[str] = None) -> List[Message]:\n", + " \"\"\"Get the conversation history\"\"\"\n", + " conv_id = conversation_id or self.current_conversation_id\n", + " if not conv_id:\n", + " raise ValueError(\"No conversation ID provided or active\")\n", + " \n", + " conversations = self._load_conversations()\n", + " if conv_id not in conversations:\n", + " raise ValueError(f\"Conversation {conv_id} not found\")\n", + " \n", + " return [\n", + " Message(\n", + " role=msg[\"role\"],\n", + " content=msg[\"content\"],\n", + " timestamp=msg[\"timestamp\"]\n", + " )\n", + " for msg in conversations[conv_id][\"messages\"]\n", + " ]\n", + "\n", + " def _load_conversations(self) -> Dict:\n", + " \"\"\"Load conversations from storage file\"\"\"\n", + " try:\n", + " with open(self.storage_path, 'r') as f:\n", + " return json.load(f)\n", + " except FileNotFoundError:\n", + " return {}\n", + "\n", + " def _save_conversations(self, conversations: Dict) -> None:\n", + " \"\"\"Save conversations to storage file\"\"\"\n", + " with open(self.storage_path, 'w') as f:\n", + " json.dump(conversations, f, indent=2)\n", + "\n", + "\n", + "\n", + "from langchain_openai import ChatOpenAI\n", + "model = ChatOpenAI(model=\"gpt-4o-mini\")\n", + "\n", + "# Initialize the assistant\n", + "assistant = FirefighterInterviewAssistant(model)\n", + "\n", + "# Start a new conversation\n", + "theme = themes[0]\n", + "response = assistant.start_conversation(\n", + " conversation_id=\"user123\",\n", + " resume=f\"Resume {docs}\",\n", + " theme=theme\n", + ")\n", + "\n", + "print(response[\"message\"]) # Initial AI question\n", + "print(response[\"end\"]) # Conversation status\n", + "\n", + "# Process user response\n", + "while not response[\"end\"]:\n", + " user_input = input(\"Your response: \")\n", + " response = assistant.process_user_response(user_input)\n", + " print(response[\"message\"])\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'id': 1,\n", + " 'theme': 'Disability Questions',\n", + " 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"},\n", + " {'id': 2,\n", + " 'theme': 'Leadership Skills Questions',\n", + " 'context': \"Leadership is not about having authority; it's about inspiring others to reach their full potential.\\n- Effective leaders lead by example, demonstrating integrity, accountability, and a commitment to teamwork.\\n- In the fire service, leadership is not confined to rank; every firefighter has the opportunity to lead and contribute to the success of the team.\\n- Adaptability and decisiveness are crucial qualities in leadership, especially in high-stress and rapidly changing environments.\\n- Leadership is also about fostering a culture of continuous learning and improvement, encouraging feedback, and promoting innovation.\\n- Potential Conclusions:\\no I've heard about the emphasis on leadership development within ______ Fire, and it's clear that the department values cultivating leaders at all levels. I'm eager to contribute to that culture and continue growing as a leader.\\no During my station visit, I observed how firefighters at ______ Fire take initiative and support each other, regardless of rank. That collaborative leadership approach is something I aspire to emulate and contribute to.\\no I've learned that leadership in the fire service is not just about giving orders; it's about empowering others, building trust, and fostering a sense of unity within the team. I'm excited about the opportunity to lead by example and positively influence my fellow firefighters at ______ Fire.\"},\n", + " {'id': 3,\n", + " 'theme': 'Conflict Questions',\n", + " 'context': 'Conflict is a huge problem in high performing teams.\\n- Creates a poisonous work environment, reduces efficiencies, and creates mental health issues.\\n- Those are serious issues and must be addressed as soon as they pop up.\\n- One of the best ways to address it through increasing the communication and giving people an opportunity to explain their opinions or viewpoints.\\n- I tend to think about the three T’s (teamwork, training and trust) and how important it is to fall back on those.\\n- Attempt to secure behaviour modification through voluntary compliance.\\n- Potential Conclusions:\\no I know that professionalism runs through the entire department here. ______\\no Firefighters are professional and committed to safe and respectful workplaces.\\no One thing about the fire service is that you all do a great job of communicating and creating a chain of command to help simplify complex problems\\no Its important to remember the values of the fire service and keep those in mind whenever conflicts arise.\\no Tie in stats and figures from your research on the department.'},\n", + " {'id': 4,\n", + " 'theme': 'Stress Questions',\n", + " 'context': 'My big takeaway is that stress is everywhere, and it affects everyone in different ways.\\n- The amount of mental health issues and stress levels are up exponentially with the community.\\n- Especially when you factor in the effects of COVID-19 and the lockdowns.\\n- That _________ situation made me realize that we must be supportive of one another and reduce the stigma.\\n- Potential Conclusions:\\no I know that the team members at _______ Fire are exposed to stressful situations on a regular basis, and it is critical that they be supportive to one another in order to maintain a strong team.\\no I have spoken to ______ about your mental health programs and can see that you really take the time to pour into each of your firefighter’s cup. I really admire that.\\no I looked into that _________ program that your department us'},\n", + " {'id': 5,\n", + " 'theme': 'Emergency Questions',\n", + " 'context': 'Emergencies can happen anywhere at anytime.\\n- Usually with little to no warning.\\n- During those times people fall back onto their training and most commonly practiced strategies.\\n- We need to ensure that our personnel are available and ready to answer the call whenever that happens in the community, and they are using the most effective strategies and techniques possible.\\n- Potential Conclusions:\\no I know that the expectation of _______ Fire is to train at least 2-3 hours per shift.\\no That works out to 14-21 hours per month. When you factor in running calls in between those training sessions there is a fair bit of opportunity for Firefighters to become very good at their jobs and be fully prepared.\\no Consistent commitment to training everything from the basics up to the complicated things 2-3 hours per shift is what makes the people on _____ Fire so good at their job.'},\n", + " {'id': 6,\n", + " 'theme': 'Mistake',\n", + " 'context': 'We all make mistakes. It is okay to make them. But it is not okay to not learn from them.\\n- Mistakes are just proof that you are trying your best.\\n- They are an opportunity for growth and for development.\\n- They are the things that help sharpen the knives in a drawer.\\n- The key is not to make the same mistake twice.\\n- Potential Conclusions:\\no I am certain that _______ Firefighters conduct regular follow-ups after calls.\\no Its important for everyone to check their ego and be accountable for the things they messed up on.\\no I know that Chief ______ promotes an open and transparent environment. He/She is not afraid to admit when they made a mistake. So, it is important for everyone in the department to follow suit.'},\n", + " {'id': 7,\n", + " 'theme': 'Cultural, Diversity, and Inclusion Questions',\n", + " 'context': 'Communities are becoming more and more diverse everyday. It is important for the Fire Service to recognize that.\\n- Steps can be taken every single day to create an environment that is inclusive and open to everyone regardless of their background, language, abilities, or self-identification.\\n- Public servants serve the public.\\n- No passing judgement on people. No racism, no homophobia, no misogyny.\\n- Treat everyone with respect and educate ourselves about the differences in our communities.\\n- Potential Conclusions:\\no ______ Fire is very professional and respectful. I have only seen and heard good things about how much of a concerted effort you are making to be more inclusive.\\no I spent some time looking at the Public Education pamphlets at station _____ and saw that they were offered in a bunch of different languages. That was amazing and I really think that shows the community how much you care about reducing the barriers to safety.\\no I spoke with _____ and learned about how enjoyable of an experience they have had working on your departmen'},\n", + " {'id': 8,\n", + " 'theme': 'Customer Service Questions',\n", + " 'context': 'Providing great customer service really just requires caring about people and trying to always make things better than you found it.\\n- Our communities are better served when they have people that are willing to sacrifice their time and energy.\\n- I personally enjoy going to places and working with people that provide great customer service. I would only expect that to be the level of service provided by firefighters.\\n- Potential Conclusions:\\no You can’t train people to care and its important for the fire service to hire people who innately have a desire to go the extra mile. It has to be in their DNA.\\no I know that _____ Fire has done a great job finding lots of those types of people and they constantly work towards fostering that characteristic in everyone brought into the organization.\\no Firefighters go above and beyond every shift. Its our job to serve the community and protect life, property'},\n", + " {'id': 9,\n", + " 'theme': 'Successful and Unsuccessful Team Questions',\n", + " 'context': 'Teamwork is necessary to assist in overcoming emergencies. Especially expanding ones. I understand how chain of commands works and the importance of monitoring the span of control as well.\\n- Great teamwork creates synergy in the workplace and makes environments happier, healthier, and safer.\\n- There is no “I†in team.\\n- All tasks are important no matter how big or small it may seem.\\n- Great teams are built by people that are committed to training and knowing their roles well.\\n- Need to train in order to create muscle memory and prevent “skills fadeâ€\\n- Potential Conclusions:\\no I know that Firefighting is a team sport and that _____ Fire does a great job in fostering that camaraderie.\\no I have seen the _____ Fire team play in _____ tournament and know that you guys applaud crews bonding over meals at the station.\\no I really appreciate the fact that you allow crews to train together and share insights learned across the department so that everyone gets better all the time.\\no Include stats and figures, following SOPs and safety protocols into the answer'},\n", + " {'id': 10,\n", + " 'theme': 'Disagree with a Supervisor Questions',\n", + " 'context': 'Disagreements can and will happen but what matters is that the issues are addressed in a respectful and professional manner.\\n- I always recommend doing them in a private and non-confrontational manner\\n- With a focus on finding acceptable solutions that can be implemented effectively.\\n- The idea is to not let things linger and harbour because that creates a poisonous work environment.\\n- Potential Conclusions:\\no I understand my role in the chain of command and will always try my best to follow orders as they are given. But whenever a disagreement may come up it is important to show respect and listen to all sides.\\no _____ Fire works hard to promote captains and chiefs that are smart, capable and proven leaders. It is important to acknowledge that every time there is a potential disagreement. They may see things that I am not aware of.\\no _____ Fire works hard to minimize the number of disagreements in the workplace.'},\n", + " {'id': 11,\n", + " 'theme': 'Rule Bending',\n", + " 'context': 'I do not bend rules that jeopardize health and safety or rules that test my ethics and morality.\\n- I know that the fire service has that same perspective.\\n- Therefore, all organizations need to have rules and all people in those organizations need to know them.\\n- This is why there are internal SOPs, OHSA, HTA, Fire Code, Criminal Code etc.\\n- Potential Conclusions:\\no I know that _____ Fire has a robust SOP package, and it is part of the training process for every new hire to go through them and get schooled up on the importance of them.\\no The onus is on me to spend time learning the ins and outs of this organization if I am blessed with the opportunity to work here.\\no Firefighters need to be rule followers. It is an inherently dangerous job and freelancing has no part o.'},\n", + " {'id': 12,\n", + " 'theme': 'Integrity Challenge Questions',\n", + " 'context': 'Integrity is the cornerstone of the fire service profession, guiding every action and decision.\\n- Firefighters are entrusted with public safety, making it imperative to uphold the highest ethical standards.\\n- In the fire service, we are governed by regulations such as the NFPA standards and the Ontario FPPA, which mandate strict compliance to ensure safety and well-being.\\n- These guidelines underscore the need for transparency and ethical conduct in all our actions.\\n- Potential Conclusions:\\no Integrity is not just a personal attribute; it is a professional necessity that ensures the effectiveness and reliability of our fire service operations.\\no When faced with an integrity challenge, it is essential to remain steadfast in ethical principles, even under pressure.\\no This experience reinforced my commitment to the values of the fire service and highlighted the importance of fostering a culture where integrity is paramount.\\no By upholding these standards, we not only protect ourselves and our colleagues but also maintain the trust and confidence of the communities we serve.'},\n", + " {'id': 13,\n", + " 'theme': 'Taking a Shortcut at work',\n", + " 'context': \"I believe in having strong work ethic. I was raised that way and my work experience to date proves that…\\n- I definitely do not take shortcuts around things that compromise health and safety or my ethics and morality.\\n- I never take shortcuts that compromise the health and safety of myself or others, or that challenge my ethical and moral values.\\n- I believe that the fire service shares this same perspective, prioritizing safety, ethics, and morality above all else.\\n- In my view, all organizations should establish clear rules, and it is essential for every member of those organizations to be aware of and follow these rules.\\n- This is why organizations have internal Standard Operating Procedures (SOPs), Occupational Health and Safety Act (OHSA) guidelines, Highway Traffic Act (HTA) regulations, Fire Codes, and even the Criminal Code when necessary.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they have a comprehensive set of Standard Operating Procedures (SOPs) that are diligently followed. During my training, I learned about the critical importance of these procedures and the reasons for adhering to them.\\no If I were fortunate enough to join this organization, I understand that it would be my responsibility to thoroughly acquaint myself with its rules and procedures. I'm committed to investing the necessary time and effort to ensure I comply with them.\\no In firefighting, there's no room for shortcuts. It's an inherently perilous job and deviating from established procedures can jeopardize lives. Rules are not just guidelines but safeguards that protect everyone and ensure a safe return from each mission.\"},\n", + " {'id': 14,\n", + " 'theme': 'Delivering Difficult Messages',\n", + " 'context': \"I do not shy away from the responsibility of delivering difficult messages when necessary, even though it may be uncomfortable. My commitment to honesty and ethical conduct remains unwavering.\\n- I believe that the fire service, like any responsible organization, understands the importance of addressing challenging issues head-on, which aligns with my perspective on this matter.\\n- In all organizations, there should be clear protocols and guidelines for delivering difficult messages effectively and sensitively, ensuring that the message is conveyed while respecting the dignity and feelings of the recipients.\\n- This is why organizations often have established procedures and communication guidelines to handle such situations professionally and ethically.\\n- Potential Conclusions:\\no I'm aware that at _____ Fire, they prioritize open and honest communication. During my training, I learned about their approach to delivering difficult messages and the importance of doing so with empathy and professionalism.\\no If I were part of this organization, I would understand that delivering difficult messages might be a part of my role. I would be committed to following their established protocols and guidelines for addressing such situations.\\no In firefighting and similar high-stakes professions, effective communication, even in challenging circumstances, can be a matter of life and death. The rules and procedures in place are not just about following a script but ensuring that messages are conveyed in a way that respects the emotions and well-being of all involved parties.\"},\n", + " {'id': 15,\n", + " 'theme': 'Not Following SOPs/SOGs',\n", + " 'context': \"I have never deviated from established SOPs at work, as doing so can compromise safety, ethical standards, and the integrity of the organization.\\n- I understand that the fire service, like any responsible organization, places a high value on adherence to SOPs, which is consistent with my perspective.\\n- In every organization, it's crucial to have clear and well-documented SOPs that every member understands and follows. This ensures consistency, safety, and ethical conduct.\\n- This is why organizations implement internal SOPs and adhere to external regulations like OHSA, HTA, and Fire Codes to maintain high standards of operation.\\n- Potential conclusions:\\no I'm aware that at _____ Fire, strict adherence to SOPs is fundamental to their operational success. During my training, I gained a deep appreciation for the importance of following these procedures and the consequences of not doing so.\\no If I were to become part of this organization, I would fully understand the gravity of following SOPs. I would uphold these standards and would actively seek training and support to ensure compliance.\\no In firefighting and similar high-risk professions, disregarding SOPs is simply not an option. These procedures are in place to protect lives and property. Any deviation can have serious consequences, and rule adherence is non-negotiable.\"},\n", + " {'id': 16,\n", + " 'theme': 'Continuous Improvement',\n", + " 'context': \"Continuous improvement is about striving to be better every day, both as an individual and as part of a team.\\n- I believe that the fire service embodies this concept by constantly evolving through training, adopting new technologies, and learning from past experiences.\\n- Reflecting on one's performance and seeking feedback are essential components of continuous improvement, as they help identify strengths and areas for growth.\\n- Staying updated with new firefighting techniques, equipment, and regulations is crucial for maintaining effectiveness and safety in the field.\\n- Potential Conclusions:\\no I've seen how ______ Fire prioritizes ongoing training and professional development to ensure its firefighters remain at the forefront of the profession. I look forward to being part of an organization that values growth and innovation.\\no During my station visit, I was impressed by the emphasis on learning and improvement at ______ Fire. That environment aligns perfectly with my personal commitment to always better myself and support my team in doing the same.\\no I believe continuous improvement is not just about improving skills but also about fostering a culture where everyone strives to do better. At ______ Fire, I’m eager to contribute to that culture by embracing challenges, seeking feedback, and pursuing opportunities for growth.\"},\n", + " {'id': 17,\n", + " 'theme': 'Handling Sensitive Information',\n", + " 'context': 'Firefighters are often entrusted with sensitive information, whether it pertains to medical calls, emergency incidents, or personal details about community members.\\n- Maintaining confidentiality and discretion is critical for preserving trust and ensuring the dignity of individuals involved.\\n- Handling sensitive information responsibly requires understanding and adhering to organizational policies, as well as exercising sound judgment.\\n- Respecting privacy is a key component of professionalism, especially in a role as visible and impactful as firefighting.\\n- Potential Conclusions:\\no I understand that ______ Fire has clear guidelines and training around handling sensitive information. I respect and appreciate the importance of these protocols and would adhere to them without compromise.\\no If given the opportunity to join ______ Fire, I would uphold the highest standards of confidentiality and discretion, ensuring that sensitive information is treated with the respect it deserves.\\no Handling sensitive information with care is essential to maintaining the trust of the community and the integrity of the fire service. I’m committed to embodying these values and ensuring that all information is managed professionally and ethically.'},\n", + " {'id': 18,\n", + " 'theme': 'Solving a Problem',\n", + " 'context': \"I believe problem-solving is one of the most valuable skills in the fire service, as it often determines the success or failure of a critical situation.\\n- Effective problem-solving requires a clear assessment of the situation, evaluating available resources, and making informed decisions quickly.\\n- Firefighting often involves scenarios where unexpected challenges arise, and the ability to stay calm and address issues methodically is essential.\\n- Collaboration is a significant part of problem-solving, as no one firefighter has all the answers. Solutions come from teamwork and leveraging everyone's strengths.\\n- Potential Conclusions:\\no I understand that ______ Fire emphasizes critical thinking and problem-solving in their training programs. During my training, I honed these skills and learned how to approach challenges systematically and effectively.\\no If I were part of ______ Fire, I would actively apply my problem-solving abilities in both emergency and non-emergency situations, ensuring I work collaboratively with my team to find the best outcomes.\\no Solving problems in firefighting goes beyond emergencies; it's about addressing challenges proactively, whether it's equipment maintenance, community outreach, or operational efficiency. I'm committed to contributing to this problem-solving culture at ______ Fire.\"},\n", + " {'id': 19,\n", + " 'theme': 'Challenge Questions',\n", + " 'context': 'Life is full of challenges. It is important for firefighters to be the type of people that take those challenges head on and constantly work to find ways to overcome them.\\n- Grit, persistence, creative problem solving, and strong mental health are the keys to overcoming challenges.\\n- Life can change in a second. Its important to be adaptive and flexible.\\n- Potential Conclusions:\\no And I am certain that ______ Fire works very hard to meet every challenge and then overcome them.\\no I think about how you guys handled the ________ situation\\no or the recent fire at _______\\no and as an outsider looking in, I was thoroughly impressed with the way the department handled it.'}]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "themes" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hi Erika! Let's start preparing you for that interview. Can you tell me about a time when you had to deal with a difficult situation as a volunteer firefighter? What was the situation and how did you handle it?\n", + "False\n" + ] + }, + { + "ename": "TypeError", + "evalue": "Message.__init__() got an unexpected keyword argument 'additional_kwargs'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[8], line 323\u001b[0m\n\u001b[1;32m 321\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mend\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n\u001b[1;32m 322\u001b[0m user_input \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mYour response: \u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 323\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43massistant\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprocess_user_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43muser_input\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 324\u001b[0m \u001b[38;5;28mprint\u001b[39m(response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessage\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n", + "Cell \u001b[0;32mIn[8], line 224\u001b[0m, in \u001b[0;36mFirefighterInterviewAssistant.process_user_response\u001b[0;34m(self, user_message)\u001b[0m\n\u001b[1;32m 219\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madd_message(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhuman\u001b[39m\u001b[38;5;124m\"\u001b[39m, user_message)\n\u001b[1;32m 221\u001b[0m \u001b[38;5;66;03m# Prepare messages for model\u001b[39;00m\n\u001b[1;32m 222\u001b[0m messages \u001b[38;5;241m=\u001b[39m [HumanMessage(content\u001b[38;5;241m=\u001b[39mmsg\u001b[38;5;241m.\u001b[39mcontent) \u001b[38;5;28;01mif\u001b[39;00m msg\u001b[38;5;241m.\u001b[39mrole \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhuman\u001b[39m\u001b[38;5;124m\"\u001b[39m \n\u001b[1;32m 223\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m AIMessage(content\u001b[38;5;241m=\u001b[39mmsg\u001b[38;5;241m.\u001b[39mcontent) \n\u001b[0;32m--> 224\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m msg \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_conversation_history\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m]\n\u001b[1;32m 226\u001b[0m \u001b[38;5;66;03m# Generate response using LangGraph\u001b[39;00m\n\u001b[1;32m 227\u001b[0m config \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mconfigurable\u001b[39m\u001b[38;5;124m\"\u001b[39m: {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mthread_id\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcurrent_conversation_id}}\n", + "Cell \u001b[0;32mIn[8], line 282\u001b[0m, in \u001b[0;36mFirefighterInterviewAssistant.get_conversation_history\u001b[0;34m(self, conversation_id)\u001b[0m\n\u001b[1;32m 279\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m conv_id \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m conversations:\n\u001b[1;32m 280\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConversation \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconv_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m not found\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 282\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [\n\u001b[1;32m 283\u001b[0m Message(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mmsg) \u001b[38;5;28;01mfor\u001b[39;00m msg \u001b[38;5;129;01min\u001b[39;00m conversations[conv_id][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 284\u001b[0m ]\n", + "Cell \u001b[0;32mIn[8], line 283\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 279\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m conv_id \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m conversations:\n\u001b[1;32m 280\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConversation \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconv_id\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m not found\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 282\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [\n\u001b[0;32m--> 283\u001b[0m \u001b[43mMessage\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mmsg\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m msg \u001b[38;5;129;01min\u001b[39;00m conversations[conv_id][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m 284\u001b[0m ]\n", + "\u001b[0;31mTypeError\u001b[0m: Message.__init__() got an unexpected keyword argument 'additional_kwargs'" + ] + } + ], + "source": [ + "import json\n", + "from typing import List, Dict, Optional\n", + "from dataclasses import dataclass\n", + "from pathlib import Path\n", + "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", + "from langchain_core.messages import HumanMessage, AIMessage\n", + "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.graph import START, MessagesState, StateGraph\n", + "\n", + "@dataclass\n", + "class Message:\n", + " role: str # 'human' or 'ai'\n", + " content: str\n", + " timestamp: str\n", + "\n", + "class FirefighterInterviewAssistant:\n", + " def __init__(self, model, conversation_storage_path: str = \"conversations.json\"):\n", + " \"\"\"\n", + " Initialize the Firefighter Interview Assistant.\n", + " \n", + " Args:\n", + " model: ChatOpenAI model instance\n", + " conversation_storage_path: Path to the JSON file storing conversations\n", + " \"\"\"\n", + " self.storage_path = Path(conversation_storage_path)\n", + " self.current_theme: Optional[Dict] = None\n", + " self.current_resume: Optional[str] = None\n", + " self.model = model\n", + " \n", + " # Initialize storage file if it doesn't exist\n", + " if not self.storage_path.exists():\n", + " self._save_conversations({})\n", + " \n", + " # Initialize LangGraph components\n", + " self.workflow = StateGraph(state_schema=MessagesState)\n", + " self.memory = MemorySaver()\n", + " \n", + " # Set up the prompt template\n", + " self.prompt_template = ChatPromptTemplate.from_messages([\n", + " (\n", + " \"system\",\n", + " f\"\"\"\n", + " You are a Fire Fighter Interview preparation assistant.\n", + "\n", + "Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you.\n", + "\n", + "### 7 Main Concepts:\n", + "- **High Performance Teams**\n", + "- **Situational Awareness**\n", + "- **Being a Great Problem Solver**\n", + "- **Customer Service**\n", + "- **Building Construction, Mechanical Aptitude**\n", + "- **Emergency Medicine Experience**\n", + "- **Mental and Physical Health**\n", + "\n", + "Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. \n", + "\n", + "We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. \n", + "\n", + "Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect?\n", + "\n", + "Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service.\n", + "\n", + "### 20 Important Themes\n", + "Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions:\n", + "- Customer Service\n", + "- Conflict\n", + "- Challenge\n", + "- Leadership\n", + "- Stress\n", + "- Successful Team\n", + "- Diversity\n", + "- Mistake\n", + "- Unsuccessful Team \n", + "- Disagreement\n", + "- Bent a Rule\n", + "- Delivered a Difficult Message\n", + "- Displayed Integrity\n", + "- Took a Shortcut\n", + "- Didn’t Follow the Rules\n", + "- Emergency Response\n", + "- Dealt with Disabilities\n", + "- Solved a Big Problem\n", + "- Continuous Improvement\n", + "- Handled Sensitive Information\n", + "\n", + "### Behavioral Question Starters\n", + "Behavioral questions usually start with phrases like:\n", + "- “Tell me a time when…â€\n", + "- “Can you tell me about a time when you…â€\n", + "- \"Describe a situation where you had to…\"\n", + "- \"Give me an example of how you…\"\n", + "- \"Have you ever been in a position where you needed to…\"\n", + "- \"Walk me through a time when you…\"\n", + "\n", + "Your goal is to engage in conversation with the user. You will be provided with the current theme, the resume of the user, and example general competency questions and behavioral questions.\n", + "\n", + "\n", + "### STARTPOP Framework\n", + "The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. \n", + "\n", + "Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life.\n", + "\n", + "#### Components of STARTPOP:\n", + "1. **Situation**: \n", + " - Set up the answer in the mind of the question asker. \n", + " - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long).\n", + " - Include dates, ages, places, and circumstances.\n", + "\n", + "2. **Task**: \n", + " - Explain what you needed to do and why you needed to do it.\n", + " - Recap the situation quickly from a different angle.\n", + "\n", + "3. **Actions**: \n", + " - Outline both the negative and the positive way of doing things.\n", + " - Show high moral character in every question.\n", + "\n", + "4. **Results**: \n", + " - Explain what happened as a result of your actions.\n", + " - Share results in a time-specific manner (e.g., “5 months later X happenedâ€).\n", + "\n", + "5. **Transitions**: \n", + " - Speak in a way that aligns with professional expectations.\n", + " - Ensure coherence in your responses.\n", + "\n", + "6. **Personal Lessons**: \n", + " - Discuss what you learned about yourself.\n", + " - Address any concerns the interviewers might have about hiring you.\n", + "\n", + "7. **Other People Observations**: \n", + " - Share insights about others in the situation.\n", + " - Keep it short and to the point.\n", + "\n", + "8. **Professional Connection**: \n", + " - Relate your experience directly to the fire service.\n", + " - Conclude strongly, avoiding phrases like “and so yeah…â€.\n", + " [Your full system prompt content]\n", + " Current theme {self.current_theme}\n", + " \n", + "\n", + "\n", + "Your task is to engage the user in conversation, ask relevant questions, that will ultimately help them prepare a strong STARTPOP response based on their experiences and the current theme.\n", + "YOU WILL BE PROVIDED WITH THE USER RESUME, ASK 1 QUESTION AT A TIME AND MAKE IT CONVERSATIONAL AND INTERESTING.\n", + "These responses will be saved and later used to generate a STARTPOP framework by US (DO NOT WORRY ABOUT THAT, WE WILL BE THE ONE TO GENERATE, JUST ENGAGE USER WITH QUESTION AND ANSWER).\n", + "Output format\n", + "\n", + "WILL BE IN JSON, avoid putting \n", + " message:\n", + " end: \"yes\" or \"no\" if you are done with asking questions and confident the responses are okay enough to prepare STARTPOP by us\n", + "\n", + "\"\"\"\n", + " \n", + " ),\n", + " MessagesPlaceholder(variable_name=\"messages\")\n", + " ])\n", + " \n", + " # Set up LangGraph workflow\n", + " self._setup_workflow()\n", + "\n", + " def _setup_workflow(self):\n", + " \"\"\"Setup LangGraph workflow\"\"\"\n", + " def call_model(state: MessagesState):\n", + " prompt = self.prompt_template.invoke(state)\n", + " response = self.model.invoke(prompt)\n", + " return {\"messages\": response}\n", + "\n", + " self.workflow.add_edge(START, \"model\")\n", + " self.workflow.add_node(\"model\", call_model)\n", + " self.app = self.workflow.compile(checkpointer=self.memory)\n", + "\n", + " def start_conversation(self, conversation_id: str, resume: str, theme: Dict) -> Dict:\n", + " \"\"\"\n", + " Start a new conversation or load an existing one.\n", + " \n", + " Args:\n", + " conversation_id: Unique identifier for the conversation\n", + " resume: User's resume content\n", + " theme: Current theme dictionary with 'theme' and 'context' keys\n", + " \n", + " Returns:\n", + " Dict containing initial AI response\n", + " \"\"\"\n", + " self.current_conversation_id = conversation_id\n", + " self.current_resume = resume\n", + " self.current_theme = theme\n", + " \n", + " # Initialize conversation in storage\n", + " conversations = self._load_conversations()\n", + " if conversation_id not in conversations:\n", + " conversations[conversation_id] = {\n", + " \"resume\": resume,\n", + " \"theme\": theme,\n", + " \"messages\": []\n", + " }\n", + " self._save_conversations(conversations)\n", + " \n", + " # Initialize conversation with resume\n", + " config = {\"configurable\": {\"thread_id\": conversation_id}}\n", + " input_messages = [HumanMessage(content=f\"Resume: {resume}\")]\n", + " output = self.app.invoke({\"messages\": input_messages}, config)\n", + " \n", + " # Parse and store initial response\n", + " response = self._parse_ai_response(output[\"messages\"][-1].content)\n", + " self.add_message(\"ai\", response[\"message\"])\n", + " \n", + " return response\n", + "\n", + " def process_user_response(self, user_message: str) -> Dict:\n", + " \"\"\"\n", + " Process user response and generate AI response.\n", + " \n", + " Args:\n", + " user_message: User's message content\n", + " \n", + " Returns:\n", + " Dict containing AI response and conversation status\n", + " \"\"\"\n", + " # Add user message to conversation\n", + " self.add_message(\"human\", user_message)\n", + " \n", + " # Prepare messages for model\n", + " messages = [HumanMessage(content=msg.content) if msg.role == \"human\" \n", + " else AIMessage(content=msg.content) \n", + " for msg in self.get_conversation_history()]\n", + " \n", + " # Generate response using LangGraph\n", + " config = {\"configurable\": {\"thread_id\": self.current_conversation_id}}\n", + " output = self.app.invoke({\"messages\": messages}, config)\n", + " \n", + " # Parse and store AI response\n", + " response = self._parse_ai_response(output[\"messages\"][-1].content)\n", + " self.add_message(\"ai\", response[\"message\"])\n", + " \n", + " return response\n", + "\n", + " def _parse_ai_response(self, content: str) -> Dict:\n", + " \"\"\"Parse AI response content into expected format\"\"\"\n", + " try:\n", + " response = json.loads(content)\n", + " return {\n", + " \"message\": response.get(\"message\", \"\"),\n", + " \"end\": response.get(\"end\", \"no\") == \"yes\"\n", + " }\n", + " except json.JSONDecodeError:\n", + " return {\n", + " \"message\": content,\n", + " \"end\": \"no\"\n", + " }\n", + "\n", + " def add_message(self, role: str, content: str) -> None:\n", + " \"\"\"[Previous implementation remains the same]\"\"\"\n", + " if not hasattr(self, 'current_conversation_id'):\n", + " raise ValueError(\"No active conversation. Call start_conversation first.\")\n", + " \n", + " from datetime import datetime\n", + " message = Message(\n", + " role=role,\n", + " content=content,\n", + " timestamp=datetime.now().isoformat()\n", + " )\n", + " \n", + " conversations = self._load_conversations()\n", + " conversations[self.current_conversation_id][\"messages\"].append({\n", + " \"role\": message.role,\n", + " \"content\": message.content,\n", + " \"timestamp\": message.timestamp\n", + " })\n", + " \n", + " self._save_conversations(conversations)\n", + "\n", + " # [Previous helper methods remain the same]\n", + " def get_conversation_history(self, conversation_id: Optional[str] = None) -> List[Message]:\n", + " \"\"\"[Previous implementation remains the same]\"\"\"\n", + " conv_id = conversation_id or self.current_conversation_id\n", + " if not conv_id:\n", + " raise ValueError(\"No conversation ID provided or active\")\n", + " \n", + " conversations = self._load_conversations()\n", + " if conv_id not in conversations:\n", + " raise ValueError(f\"Conversation {conv_id} not found\")\n", + " \n", + " return [\n", + " Message(**msg) for msg in conversations[conv_id][\"messages\"]\n", + " ]\n", + "\n", + " def _load_conversations(self) -> Dict:\n", + " \"\"\"[Previous implementation remains the same]\"\"\"\n", + " try:\n", + " with open(self.storage_path, 'r') as f:\n", + " return json.load(f)\n", + " except FileNotFoundError:\n", + " return {}\n", + "\n", + " def _save_conversations(self, conversations: Dict) -> None:\n", + " \"\"\"[Previous implementation remains the same]\"\"\"\n", + " with open(self.storage_path, 'w') as f:\n", + " json.dump(conversations, f, indent=2)\n", + "\n", + "\n", + "\n", + "\n", + "# Initialize OpenAI model\n", + "from langchain_openai import ChatOpenAI\n", + "model = ChatOpenAI(model=\"gpt-4o-mini\")\n", + "\n", + "# Initialize the assistant\n", + "assistant = FirefighterInterviewAssistant(model)\n", + "\n", + "# Start a new conversation\n", + "theme = themes[0]\n", + "response = assistant.start_conversation(\n", + " conversation_id=\"user123\",\n", + " resume=f\"Resume {docs}\",\n", + " theme=theme\n", + ")\n", + "\n", + "print(response[\"message\"]) # Initial AI question\n", + "print(response[\"end\"]) # Conversation status\n", + "\n", + "# Process user response\n", + "while not response[\"end\"]:\n", + " user_input = input(\"Your response: \")\n", + " response = assistant.process_user_response(user_input)\n", + " print(response[\"message\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': 1,\n", + " 'theme': 'Disability Questions',\n", + " 'context': \"Firefighters respond to lots of medical calls, many of which involve visible and invisible disabilities.\\n- It's critical to be aware of the unique needs of people with physical health issues and mental health challenges.\\n- Firefighters must provide compassionate care to everyone and giving respect to all regardless of their abilities.\\n- As first responders, firefighters are often the first point of contact for vulnerable individuals, and how they interact can make a lasting impact on the person’s well-being.\\n- Firefighters should be well-trained to recognize different disabilities and adapt their approach to ensure effective communication and assistance, especially for those with cognitive or sensory impairments.\\n- This requires empathy, patience, and a strong understanding of mental health and physical disabilities, along with the proper use of equipment and techniques to ensure safety and dignity for everyone involved.\\n- Potential Conclusions:\\no I know that ______ Fire has a strong reputation for responding with compassion and professionalism to individuals with disabilities, ensuring that they feel respected and supported during emergencies.\\no I admire the commitment that ______ Fire has shown in ensuring firefighters are trained to work with all members of the community, including those with both visible and invisible disabilities.\\no I've seen firsthand how important it is for firefighters to provide inclusive care during medical emergencies. I would be honored to join ______ Fire in continuing to up\"}" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "themes[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_19308/4105662605.py:62: PydanticDeprecatedSince20: The `dict` method is deprecated; use `model_dump` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/\n", + " \"resume\": [doc.dict() for doc in resume_docs],\n", + "/tmp/ipykernel_19308/4105662605.py:122: PydanticDeprecatedSince20: The `dict` method is deprecated; use `model_dump` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/\n", + " self.conversations[conversation_id][\"messages\"].append(response.dict())\n" + ] + }, + { + "ename": "JSONDecodeError", + "evalue": "Expecting value: line 1 column 1 (char 0)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mJSONDecodeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[65], line 157\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[38;5;66;03m# Start or continue a conversation\u001b[39;00m\n\u001b[1;32m 156\u001b[0m conversation_id \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124muser123\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m--> 157\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43massistant\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstart_conversation\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 158\u001b[0m \u001b[43m \u001b[49m\u001b[43mconversation_id\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconversation_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 159\u001b[0m \u001b[43m \u001b[49m\u001b[43mresume_docs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Your resume documents\u001b[39;49;00m\n\u001b[1;32m 160\u001b[0m \u001b[43m \u001b[49m\u001b[43mtheme\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mthemes\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Current theme\u001b[39;49;00m\n\u001b[1;32m 161\u001b[0m \u001b[43m)\u001b[49m\n\u001b[1;32m 163\u001b[0m \u001b[38;5;66;03m# Add user message and get response\u001b[39;00m\n\u001b[1;32m 164\u001b[0m response \u001b[38;5;241m=\u001b[39m assistant\u001b[38;5;241m.\u001b[39madd_message(\n\u001b[1;32m 165\u001b[0m conversation_id\u001b[38;5;241m=\u001b[39mconversation_id,\n\u001b[1;32m 166\u001b[0m message\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mI have experience working in customer service.\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 167\u001b[0m is_human\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[1;32m 168\u001b[0m )\n", + "Cell \u001b[0;32mIn[65], line 76\u001b[0m, in \u001b[0;36mFirefighterInterviewAssistant.start_conversation\u001b[0;34m(self, conversation_id, resume_docs, theme)\u001b[0m\n\u001b[1;32m 70\u001b[0m messages \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m 71\u001b[0m HumanMessage(content\u001b[38;5;241m=\u001b[39mresume_content),\n\u001b[1;32m 72\u001b[0m HumanMessage(content\u001b[38;5;241m=\u001b[39mtheme_content)\n\u001b[1;32m 73\u001b[0m ]\n\u001b[1;32m 75\u001b[0m \u001b[38;5;66;03m# Get initial response\u001b[39;00m\n\u001b[0;32m---> 76\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_get_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconversation_id\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 77\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n", + "Cell \u001b[0;32mIn[65], line 125\u001b[0m, in \u001b[0;36mFirefighterInterviewAssistant._get_response\u001b[0;34m(self, conversation_id, new_messages)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconversations[conversation_id][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mappend(response\u001b[38;5;241m.\u001b[39mdict())\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msave_conversations()\n\u001b[0;32m--> 125\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mjson\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mloads\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcontent\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/usr/lib/python3.10/json/__init__.py:346\u001b[0m, in \u001b[0;36mloads\u001b[0;34m(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)\u001b[0m\n\u001b[1;32m 341\u001b[0m s \u001b[38;5;241m=\u001b[39m s\u001b[38;5;241m.\u001b[39mdecode(detect_encoding(s), \u001b[38;5;124m'\u001b[39m\u001b[38;5;124msurrogatepass\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 343\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\u001b[38;5;28mcls\u001b[39m \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m object_hook \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m\n\u001b[1;32m 344\u001b[0m parse_int \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m parse_float \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m\n\u001b[1;32m 345\u001b[0m parse_constant \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m object_pairs_hook \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m kw):\n\u001b[0;32m--> 346\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_default_decoder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdecode\u001b[49m\u001b[43m(\u001b[49m\u001b[43ms\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 347\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mcls\u001b[39m \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 348\u001b[0m \u001b[38;5;28mcls\u001b[39m \u001b[38;5;241m=\u001b[39m JSONDecoder\n", + "File \u001b[0;32m/usr/lib/python3.10/json/decoder.py:337\u001b[0m, in \u001b[0;36mJSONDecoder.decode\u001b[0;34m(self, s, _w)\u001b[0m\n\u001b[1;32m 332\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mdecode\u001b[39m(\u001b[38;5;28mself\u001b[39m, s, _w\u001b[38;5;241m=\u001b[39mWHITESPACE\u001b[38;5;241m.\u001b[39mmatch):\n\u001b[1;32m 333\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Return the Python representation of ``s`` (a ``str`` instance\u001b[39;00m\n\u001b[1;32m 334\u001b[0m \u001b[38;5;124;03m containing a JSON document).\u001b[39;00m\n\u001b[1;32m 335\u001b[0m \n\u001b[1;32m 336\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 337\u001b[0m obj, end \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraw_decode\u001b[49m\u001b[43m(\u001b[49m\u001b[43ms\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43midx\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_w\u001b[49m\u001b[43m(\u001b[49m\u001b[43ms\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mend\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 338\u001b[0m end \u001b[38;5;241m=\u001b[39m _w(s, end)\u001b[38;5;241m.\u001b[39mend()\n\u001b[1;32m 339\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m end \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mlen\u001b[39m(s):\n", + "File \u001b[0;32m/usr/lib/python3.10/json/decoder.py:355\u001b[0m, in \u001b[0;36mJSONDecoder.raw_decode\u001b[0;34m(self, s, idx)\u001b[0m\n\u001b[1;32m 353\u001b[0m obj, end \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mscan_once(s, idx)\n\u001b[1;32m 354\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[0;32m--> 355\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m JSONDecodeError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mExpecting value\u001b[39m\u001b[38;5;124m\"\u001b[39m, s, err\u001b[38;5;241m.\u001b[39mvalue) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 356\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m obj, end\n", + "\u001b[0;31mJSONDecodeError\u001b[0m: Expecting value: line 1 column 1 (char 0)" + ] + } + ], + "source": [ + "from typing import List, Dict, Optional\n", + "from langchain_core.messages import HumanMessage, AIMessage, SystemMessage\n", + "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n", + "from langchain_openai import ChatOpenAI\n", + "from langchain.schema import Document\n", + "import json\n", + "import os\n", + "\n", + "class FirefighterInterviewAssistant:\n", + " def __init__(self, model_name: str = \"gpt-4-turbo-preview\"):\n", + " \"\"\"Initialize the interview assistant.\n", + " \n", + " Args:\n", + " model_name (str): The OpenAI model to use\n", + " \"\"\"\n", + " self.model = ChatOpenAI(model_name=model_name)\n", + " self.conversations_file = \"conversations.json\"\n", + " self.load_conversations()\n", + " \n", + " # Core system prompt template\n", + " self.prompt_template = ChatPromptTemplate.from_messages([\n", + " (\n", + " \"system\",\n", + " \"\"\"You are a Fire Fighter Interview preparation assistant.\n", + " // ... existing system prompt content ...\n", + " Output format:\n", + " WILL BE IN JSON\n", + " message:\n", + " end: \"yes\" or \"no\" if you are done with asking questions and confident the responses are okay enough to prepare STARTPOP\n", + " \"\"\"\n", + " ),\n", + " MessagesPlaceholder(variable_name=\"messages\")\n", + " ])\n", + "\n", + " def load_conversations(self):\n", + " \"\"\"Load existing conversations from JSON file\"\"\"\n", + " if os.path.exists(self.conversations_file):\n", + " with open(self.conversations_file, 'r') as f:\n", + " self.conversations = json.load(f)\n", + " else:\n", + " self.conversations = {}\n", + "\n", + " def save_conversations(self):\n", + " \"\"\"Save conversations to JSON file\"\"\"\n", + " with open(self.conversations_file, 'w') as f:\n", + " json.dump(self.conversations, f, indent=2)\n", + "\n", + " def start_conversation(self, conversation_id: str, resume_docs: List[Document], theme: Dict) -> Dict:\n", + " \"\"\"Start a new conversation or continue existing one.\n", + " \n", + " Args:\n", + " conversation_id (str): Unique identifier for the conversation\n", + " resume_docs (List[Document]): List of resume documents\n", + " theme (Dict): Current theme information\n", + " \n", + " Returns:\n", + " Dict: Initial response from the assistant\n", + " \"\"\"\n", + " if conversation_id not in self.conversations:\n", + " self.conversations[conversation_id] = {\n", + " \"messages\": [],\n", + " \"resume\": [doc.dict() for doc in resume_docs],\n", + " \"theme\": theme\n", + " }\n", + " \n", + " # Initialize with resume and theme context\n", + " resume_content = f\"Resume {str(resume_docs)}\"\n", + " theme_content = f\"Current theme: {theme['theme']}\\nContext: {theme['context']}\"\n", + " \n", + " messages = [\n", + " HumanMessage(content=resume_content),\n", + " HumanMessage(content=theme_content)\n", + " ]\n", + " \n", + " # Get initial response\n", + " response = self._get_response(conversation_id, messages)\n", + " return response\n", + "\n", + " def add_message(self, conversation_id: str, message: str, is_human: bool = True) -> Dict:\n", + " \"\"\"Add a message to the conversation and get response.\n", + " \n", + " Args:\n", + " conversation_id (str): Conversation identifier\n", + " message (str): Message content\n", + " is_human (bool): Whether the message is from human (True) or AI (False)\n", + " \n", + " Returns:\n", + " Dict: Response from the assistant\n", + " \"\"\"\n", + " if conversation_id not in self.conversations:\n", + " raise ValueError(f\"Conversation {conversation_id} not found\")\n", + " \n", + " message_obj = HumanMessage(content=message) if is_human else AIMessage(content=message)\n", + " self.conversations[conversation_id][\"messages\"].append(message_obj.dict())\n", + " \n", + " # Get response if human message\n", + " if is_human:\n", + " return self._get_response(conversation_id, [message_obj])\n", + " return {\"message\": \"Message added\", \"end\": \"no\"}\n", + "\n", + "\n", + "\n", + " def _get_response(self, conversation_id: str, new_messages: List) -> Dict:\n", + " \"\"\"Get response from the model.\n", + " \n", + " Args:\n", + " conversation_id (str): Conversation identifier\n", + " new_messages (List): New messages to process\n", + " \n", + " Returns:\n", + " Dict: Response from the assistant\n", + " \"\"\"\n", + " # Combine existing and new messages\n", + " all_messages = [\n", + " self._convert_to_message(msg) \n", + " for msg in self.conversations[conversation_id][\"messages\"]\n", + " ] + new_messages\n", + " \n", + " # Get response from model\n", + " prompt = self.prompt_template.invoke({\"messages\": all_messages})\n", + " response = self.model.invoke(prompt)\n", + " \n", + " # Save response\n", + " self.conversations[conversation_id][\"messages\"].append(response.dict())\n", + " self.save_conversations()\n", + " \n", + " return json.loads(response.content)\n", + "\n", + " def _convert_to_message(self, message_dict: Dict):\n", + " \"\"\"Convert dictionary to appropriate message type\"\"\"\n", + " if message_dict[\"type\"] == \"human\":\n", + " return HumanMessage(**message_dict)\n", + " elif message_dict[\"type\"] == \"ai\":\n", + " return AIMessage(**message_dict)\n", + " elif message_dict[\"type\"] == \"system\":\n", + " return SystemMessage(**message_dict)\n", + " else:\n", + " raise ValueError(f\"Unknown message type: {message_dict['type']}\")\n", + "\n", + " def get_conversation_history(self, conversation_id: str) -> List[Dict]:\n", + " \"\"\"Get the full conversation history.\n", + " \n", + " Args:\n", + " conversation_id (str): Conversation identifier\n", + " \n", + " Returns:\n", + " List[Dict]: List of messages in the conversation\n", + " \"\"\"\n", + " if conversation_id not in self.conversations:\n", + " raise ValueError(f\"Conversation {conversation_id} not found\")\n", + " return self.conversations[conversation_id][\"messages\"]\n", + "\n", + "\n", + "# Initialize the assistant\n", + "assistant = FirefighterInterviewAssistant()\n", + "\n", + "# Start or continue a conversation\n", + "conversation_id = \"user123\"\n", + "response = assistant.start_conversation(\n", + " conversation_id=conversation_id,\n", + " resume_docs=docs, # Your resume documents\n", + " theme=themes[0] # Current theme\n", + ")\n", + "\n", + "# Add user message and get response\n", + "response = assistant.add_message(\n", + " conversation_id=conversation_id,\n", + " message=\"I have experience working in customer service.\",\n", + " is_human=True\n", + ")\n", + "\n", + "# Get conversation history\n", + "history = assistant.get_conversation_history(conversation_id)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'messages': [HumanMessage(content=\"Resume [Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 0}, page_content='Erika Kiviaho \\\\n \\\\n \\\\n1070 Hallet’s Road, MacTier, ON, P0C 1H0 \\\\nEkiviaho_9@hotmail.com \\\\n(705) 662 9735\\\\nEDUCATION \\\\nCollege Certificate, NFPA 1001 Level 1 & 2 Pre-Service Firefighter Program, FESTI (IFSAC) 2023 \\\\nUniversity Degree, General Bachelor of Arts, Wilfrid Laurier University 2016 \\\\nOntario Secondary School Diploma (OSSD), Lively District Secondary School, Sudbury, ON 2010 \\\\n \\\\nFIREFIGHTER EDUCATION AND CERTIFICATIONS \\\\nOFAI Stage 1, 2, 3 and Swim Test Candidate Testing Program Certificate 2023 \\\\nNFPA 1001 Level 1 & 2 Pre-Service Firefighter Training Program, FESTI (IFSAC) 2023 \\\\nNFPA 1006 Surface Water Rescue – Technician Level, Southwest Fire Academy 2023 \\\\nNFPA 1006 Common Passenger Vehicle Rescue – Technician Level, RS Rescue 2024 \\\\nNFPA 1006 Confined Space Rescue – Technician Level, Access Rescue 2024 \\\\nNFPA 1035 Fire & Life Safety Educator, Conestoga College (IFSAC) 2024 \\\\nNFPA 1072 Hazardous Materials - Awareness & Operations Level, Lambton College (IFSAC) 2023 \\\\nSuppression Tactics in Single Family Homes, UL Fire Safety Research Institute 2023 \\\\n \\\\nFIRST AID AND LIFE SAFETY TRAINING \\\\nEmergency Medical Responder + CPR Level BLS (HCP), Canadian Red Cross 2023 \\\\nStandard First Aid, BLS and CPR Level C, Canadian Red Cross 2023 \\\\nPsychological First Aid, John Hopkins University 2023 \\\\n \\\\nEMERGENCY MANAGEMENT ONTARIO EDUCATION \\\\nIMS 100 – Intro to Incident Management System, EMO 2023 \\\\n \\\\nEMERGENCY RESPONSE PREPARATION AND SAFETY TRAINING \\\\nOntario DZ License (with airbrakes) Training, Transport Training Centres of Canada 2023 \\\\nPleasure Craft Operator License, Transport Canada 2023 \\\\nWHIMS 2015, Workplace Safety Compliance Centre 2023 \\\\nWorking at Heights, Workplace Safety Compliance Centre 2023 \\\\nAsbestos Safety Awareness, Workplace Safety Compliance Centre 2023 \\\\n \\\\nEQUITY, DIVERSITY, INCLUSION AND LANGUAGE TRAINING \\\\nAmerican Sign Language for First Responders, Humber College 2023 \\\\nAccessibility for Ontarians with Disabilities, AODA.ca 2023 \\\\nLGBT2SQ+ Inclusion Training, Canadian Police Knowledge Network 2023 \\\\n \\\\nWORK EXPERIENCE \\\\nVolunteer Firefighter Muskoka Lakes Fire Department, Foot’s Bay, ON 2023 – Present \\\\n• Member of Muskoka Lake’s Volunteer Fire Suppression Team training out of and responding from Station 1. \\\\n• Works closely with firefighting crew under the guidance and direction of our Captain and Chiefs to respond to \\\\na variety of emergency situations (such as medical emergencies, car accidents and fully involved house fires). \\\\n• Maintains excellent rate of attendance for active calls, training days and community volunteering events. \\\\n• Responsible for operating, maintaining, servicing equipment, and performing physically demanding labour. \\\\n• Performs daily inspections, truck and apparatus circle checks, documents and restocks inventory. \\\\n• Frequently interacts with the public presenting fire safety messages and providing emotional support . \\\\n• Required to constantly use problem solving, stress management, communication , and team working skills. \\\\n• Complies with the Fire Protection and Prevention Act of Ontario and Section 21 Guidelines. \\\\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\nLabourer Sundance Gardening, Muskoka, ON 2023 – Present \\\\n• Worked on a crew of landscaping professionals servicing residential cottage clients across the Muskoka’s. \\\\n• Responsible for building rock beds, building flower beds, cutting grass, planting trees and watering plants. \\\\n• Frequently drove, loaded, and unloaded large pick-up trucks, cube vans, trailers and used power tools. \\\\n• Performed daily inventory checks, inspection of workspace, tools, and equipment, and read shift briefings. \\\\n• Ensures compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\n '), Document(metadata={'source': '../upload_folder/Resume_-_Erika_Kiviaho.pdf', 'page': 1}, page_content='Turf Maintenance Crew Weston Golf & Country Club, Toronto, ON 2022 \\\\n• Performs lawn mowing, aeration, dethatching, mulching, garden design, sodding, and other lawncare services. \\\\n• Built and maintained tee boxes, fairways, bunker (sand traps), greens, cart paths, cleaned hazards and ponds. \\\\n• Worked with hazardous chemicals following company Standard Operating Procedures and WHIMS 2015. \\\\n• Functioned with team members from other departments and trained new hires about course procedures. \\\\n• Uses strong customer service, communication, team working and problem-solving skills to meet course needs. \\\\n \\\\nLabourer City of Waterloo, Waterloo, ON 2020 – 2022 \\\\n• Member of the city’s crew tasked with keeping municipal properties and public spaces in great condition. \\\\n• Performed a variety of duties like landscaping, grass cutting, building maintenance, road work and water works. \\\\n• Interacted with citizens and facility rental customers to ensure that they enjoyed their experience on grounds. \\\\n• Frequently used strong customer service and problem-solving skills in order to respond to citizen complaints. \\\\n• Operated a variety of vehicles ranging from pick-up trucks and ride-on mowers to dump trucks and front loaders. \\\\n• Performed daily truck checks, inventory, equipment checks, used power tools and small engine equipment. \\\\n• Demonstrated a strong understanding of team building, the usage and maintenance of small engine equipment, \\\\nand an ability to perform physically demanding work for long periods of time in adverse weather conditions. \\\\n• Interacted with a number of other municipal departments (ie. Fire & Emergency Services, Water & Recreation) \\\\n• Maintained road safety and ensured compliance with the Highway Traffic Act and the Municipal Act of Ontario. \\\\n• Ensured compliance with the Occupational Health and Safety Act – Section 28 Duties of Workers. \\\\n \\\\nBarista Starbucks, Somewhere, ON 2018 – 2020 \\\\n• Provided exceptional customer service and built strong relationships with clients, vendors and suppliers. \\\\n• Demonstrated active listening skills while recommending featured beverages, promotions, and upcoming events. \\\\n• Operated the register with accuracy during open/close functions, managing day -end balances and cash deposits. \\\\n• Trained new team members in coffee preparation, customer interactions, and upheld high cleanliness standards. \\\\n• Collaborated with colleagues to support back-of-house operations, ensuring a seamless and efficient workflow. \\\\n \\\\nVarsity Student Athlete Wilfrid Laurier Golden Hawks, Waterloo, ON 2010 – 2016 \\\\n• Played as a Forward and served as Assistant Captain for three years on the Varsity Women’s Hockey Team. \\\\n• Responsible for maintaining physical fitness, mental fortitude and building relationships with teammates. \\\\n• Travelled to different universities serving as an ambassador for the school at various community events. \\\\n• Operated in high stress environments and used situational awareness to ensure safety and achieve team goals. \\\\n• Demonstrated ability to follow directions, stay committed to training fundamental skills and building camaraderie. \\\\n• Acted as a leader and mentor, provided guidance to junior team members, and supported coaching staff orders. \\\\n \\\\nVOLUNTEERING & COMMUNITY SERVICE \\\\nConstruction and Build Volunteer Habitat for Humanity, Toronto, ON 2023 – Present \\\\n• Uses power tools and manual labour to help provide low-income families with safe and clean, affordable housing. \\\\n \\\\nCoach & Trainer Waterloo Ringette Association, Waterloo, ON 2022 – Present \\\\n• Responsible for building fitness and skill development programs for young ringette players aged 7 to 18. \\\\n• Frequently used strong communication, initiative, motivation, and team building skills to help break barriers. \\\\n \\\\nCouncil Member & Mentor Ringette Canada Athletes Council 2020 – Present \\\\n• Developed policies and procedures to help protect ringette players and to advocate for important needs/concerns. \\\\n \\\\nTeam Captain Canadian National Ringette Team 2012 – Present \\\\n• Travelled to different countries and experienced a wide variety of diverse cultures and languages. \\\\n• Demonstrated ability to be an ambassador in the community through frequent appearances at team events. \\\\n• Frequently interacted with fans and team/tournament sponsors; overcame language barriers through the use of \\\\ncompassion, empathy, effective verbal, and non-verbal communication skills. \\\\n \\\\nHOBBIES & INTERESTS \\\\nRingette, Hockey, Outdoors Activities, Weightlifting, Running, Travel, Cooking, BBQing, Exploring Different Cultures \\\\nthrough Food and Music, Construction DIY Projects, Reading, Movies, Listening to Music/Podcasts, Hanging out with \\\\nFriends and Family. ')]\", additional_kwargs={}, response_metadata={}, id='9df650fe-6ac3-4a13-af42-3f33619c4ea0'),\n", + " AIMessage(content=\"Hi Erika! It's great to meet you, and thank you for sharing your resume. You have a solid background with various experiences that can really lend themselves well to the firefighter interview.\\n\\nLet's start by focusing on the **20 Themes**. Which theme would you like to discuss today? For example, we could explore themes like **Customer Service**, **Conflict**, **Challenge**, or any one of the others. This will help us hone in on specific experiences you've encountered that align with the **7 Main Concepts of Firefighting**.\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 107, 'prompt_tokens': 3225, 'total_tokens': 3332, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_72ed7ab54c', 'finish_reason': 'stop', 'logprobs': None}, id='run-5421de84-9594-45d4-96af-5e0495287f6a-0', usage_metadata={'input_tokens': 3225, 'output_tokens': 107, 'total_tokens': 3332, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}),\n", + " HumanMessage(content='customer service', additional_kwargs={}, response_metadata={}, id='90f3dd69-6420-4f6d-bc26-b95b4828eea0'),\n", + " AIMessage(content=\"Great choice, Erika! Customer service is a crucial aspect of firefighting, as you'll be interacting with the public during high-stress situations. Let's delve into that theme.\\n\\nTo construct a strong **STARTPOP** response around customer service, I have a few questions for you:\\n\\n1. Can you recall a specific situation where you provided exceptional customer service in a high-pressure environment? What was happening at the time?\\n \\n2. What actions did you take that demonstrated your commitment to excellent service? \\n\\n3. What was the outcome of your actions, both for the customer and for yourself? \\n\\n4. Did you learn any important lessons from that experience that you could apply to your role as a firefighter? \\n\\n5. Can you share any observations about how your team or others responded to your customer service in that situation?\\n\\nFeel free to provide details from your past experiences, and we'll work together to shape them into a strong response!\", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 186, 'prompt_tokens': 3341, 'total_tokens': 3527, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_72ed7ab54c', 'finish_reason': 'stop', 'logprobs': None}, id='run-9a0161a1-aaf4-49cc-a379-385419da3108-0', usage_metadata={'input_tokens': 3341, 'output_tokens': 186, 'total_tokens': 3527, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "output" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Great choice, Erika! Customer service is a crucial aspect of firefighting, as you'll be interacting with the public during high-stress situations. Let's delve into that theme.\n", + "\n", + "To construct a strong **STARTPOP** response around customer service, I have a few questions for you:\n", + "\n", + "1. Can you recall a specific situation where you provided exceptional customer service in a high-pressure environment? What was happening at the time?\n", + " \n", + "2. What actions did you take that demonstrated your commitment to excellent service? \n", + "\n", + "3. What was the outcome of your actions, both for the customer and for yourself? \n", + "\n", + "4. Did you learn any important lessons from that experience that you could apply to your role as a firefighter? \n", + "\n", + "5. Can you share any observations about how your team or others responded to your customer service in that situation?\n", + "\n", + "Feel free to provide details from your past experiences, and we'll work together to shape them into a strong response!\n" + ] + } + ], + "source": [ + "config = {\"configurable\": {\"thread_id\": \"abc345\"}}\n", + "query = f\"customer service\"\n", + "\n", + "input_messages = [HumanMessage(query)]\n", + "output = app.invoke({\"messages\": input_messages}, config)\n", + "output[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "from langgraph.checkpoint.memory import MemorySaver\n", + "from langgraph.graph import START, MessagesState, StateGraph\n", + "workflow = StateGraph(state_schema=MessagesState)\n", + "\n", + "def call_model(state: MessagesState):\n", + " prompt = prompt_template.invoke(state)\n", + " response = model.invoke(prompt)\n", + " return {\"messages\": response}\n", + "\n", + "\n", + "workflow.add_edge(START, \"model\")\n", + "workflow.add_node(\"model\", call_model)\n", + "\n", + "memory = MemorySaver()\n", + "app = workflow.compile(checkpointer=memory)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Hi Jim! How can I assist you today?\n" + ] + } + ], + "source": [ + "config = {\"configurable\": {\"thread_id\": \"abc345\"}}\n", + "query = \"Hi! I'm Jim.\"\n", + "\n", + "input_messages = [HumanMessage(query)]\n", + "output = app.invoke({\"messages\": input_messages}, config)\n", + "output[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "prompt_template = ChatPromptTemplate.from_messages(\n", + " [\n", + " (\n", + " \"system\",\n", + " \"You are a helpful assistant. Answer all questions to the best of your ability in {language}.\",\n", + " ),\n", + " MessagesPlaceholder(variable_name=\"messages\"),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==================================\u001b[1m Ai Message \u001b[0m==================================\n", + "\n", + "Your name is Jim. How can I help you today, Jim?\n" + ] + } + ], + "source": [ + "query = \"What is my name?\"\n", + "\n", + "input_messages = [HumanMessage(query)]\n", + "output = app.invoke({\"messages\": input_messages}, config)\n", + "output[\"messages\"][-1].pretty_print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..07fd597 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,23 @@ +openai +pandas +python-dotenv +fastapi +uvicorn +langchain-community +langchain-openai +pydantic +pypdf +pypandoc +Spire.Doc +plum-dispatch==1.7.4 +scikit-learn +werkzeug +python-multipart +langgraph +tiktoken +langchainhub +chromadb +langchain +langchain-text-splitters +beautifulsoup4 +langchain-core \ No newline at end of file diff --git a/scripts/generate_pdf.py b/scripts/generate_pdf.py new file mode 100644 index 0000000..34b5806 --- /dev/null +++ b/scripts/generate_pdf.py @@ -0,0 +1,101 @@ +from reportlab.lib import colors +from reportlab.lib.pagesizes import letter +from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle +from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak +from reportlab.lib.enums import TA_CENTER, TA_LEFT +from io import BytesIO + + +def create_pdf(data, output_filename=None): + try: + # Create a BytesIO buffer to store the PDF + buffer = BytesIO() + + # Create the PDF document using the buffer + doc = SimpleDocTemplate(buffer, pagesize=letter) + styles = getSampleStyleSheet() + + # All content will use the same font size + STANDARD_FONT_SIZE = 12 + + # Create custom styles with consistent font size + styles.add(ParagraphStyle( + name='ThemeTitle', + fontSize=STANDARD_FONT_SIZE, + alignment=TA_CENTER, + spaceAfter=15, + fontName='Helvetica-Bold', # Bold style + leading=14 # Line spacing (1.0) + )) + + styles.add(ParagraphStyle( + name='QuestionTitle', + fontSize=STANDARD_FONT_SIZE, + alignment=TA_LEFT, + spaceAfter=10, + fontName='Helvetica-Bold', + leading=14, + textColor=colors.black + )) + + styles.add(ParagraphStyle( + name='SectionTitle', + fontSize=STANDARD_FONT_SIZE, + alignment=TA_LEFT, + spaceAfter=4, + fontName='Helvetica-Bold', + leading=14 + )) + + styles.add(ParagraphStyle( + name='NormalText', + fontSize=STANDARD_FONT_SIZE, + alignment=TA_LEFT, + spaceAfter=2, + leftIndent=20, + leading=14, + fontName='Helvetica' # Regular font + )) + + # Build the document content + story = [] + + # Add theme title on first page + if data: + theme_title = data.get('theme_title', 'No Title Provided') + story.append(Paragraph(f"THEME: {theme_title.upper()}", styles['ThemeTitle'])) + story.append(Spacer(1, 10)) + + # Process each question data + for i, item in enumerate(data if isinstance(data, list) else [data]): + story.append(Paragraph(f"{item['question']}", styles['QuestionTitle'])) + + # Add each section with proper handling + sections = ['Situation', 'Task', 'Action', 'Results and Transitions', 'Personal Lessons', + 'Observations of Others', 'Professional Connection'] + for section in sections: + story.append(Paragraph(f"{section}:", styles['SectionTitle'])) + for point in item.get(section, []): + story.append(Paragraph(f"• {point}", styles['NormalText'])) + + # Add a page break after each question except the last one + if i < len(data) - 1: + story.append(PageBreak()) + + # Build the PDF into the buffer + doc.build(story) + + # Get the PDF content from the buffer + pdf_content = buffer.getvalue() + buffer.close() + + # If output_filename is provided, also save to file + if output_filename: + with open(output_filename, 'wb') as f: + f.write(pdf_content) + + return pdf_content + + except Exception as e: + print(f"Error: {e}") + return {} diff --git a/scripts/generate_quiz.py b/scripts/generate_quiz.py new file mode 100644 index 0000000..c0bd820 --- /dev/null +++ b/scripts/generate_quiz.py @@ -0,0 +1,175 @@ +import os +import requests +from dotenv import load_dotenv +from langchain_openai import ChatOpenAI +from langchain_core.prompts.prompt import PromptTemplate +from langchain_core.output_parsers import StrOutputParser, JsonOutputParser +from langchain_openai import OpenAIEmbeddings +from langchain_core.documents import Document +from uuid import uuid4 +import json +import getpass +import numpy as np +from concurrent.futures import ThreadPoolExecutor, as_completed +from sklearn.metrics.pairwise import cosine_similarity +from typing import List +import time +from datetime import datetime +import pytz +import logging +load_dotenv() + +os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY") + +llm_temp = ChatOpenAI(model="gpt-4o-mini", temperature=0.7) + +def generate_quiz(startpop_pdf, quiz_type=None) -> dict: + try: + # Define prompt for summarizing and extracting the required fields + quiz_prompt = PromptTemplate( + template="""<|begin_of_text|><|start_header_id|>system<|end_header_id|> + You are a Fire Fighter Interview preparation assistant that generates QUIZ for user based on STARTPOP FORMAT PDF BASED on + + IN THE STARTPOP FORMAT PDF, each theme has its own questions with corresponding STARTPOP framework for each question. + + Your responsibility is to carefully analyze the provided PDF data and then generate a quiz for the user. + You will also be provided with the type of quiz. + + There are three different types of quizzes namely: + + 1- Single line text inputs + 2- Multiple Choice questions + 3- True or False questions + + For each quiz type, return the following JSON format: + + 1. For Single Line Text Inputs: + - A list of objects, each with {{"question": "Your question", "correct_answer": "Your correct answer"}} + + 2. For Multiple Choice Questions: + - A list of objects, each with {{"question": "Your question", "options": ["Option 1", "Option 2"], "correct_answer": "Correct Option"}} + + 3. For True or False Questions: + - A list of objects, each with {{"question": "Your question", "options": ["True", "False"], "correct_answer": "True or False"}} + + Each response should also include a field called "quiz_type" which can be either 1, 2, or 3 respectively. + + Return just the JSON output without any other explanation or comments. + + TO KNOW MORE ABOUT THE PROJECT READ BELOW + ----START------ + Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you. + + ### 7 Main Concepts: + - **High Performance Teams** + - **Situational Awareness** + - **Being a Great Problem Solver** + - **Customer Service** + - **Building Construction, Mechanical Aptitude** + - **Emergency Medicine Experience** + - **Mental and Physical Health** + + Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. + + We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. + + Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect? + + Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service. + + ### 20 Important Themes + Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions: + - Customer Service + - Conflict + - Challenge + - Leadership + - Stress + - Successful Team + - Diversity + - Mistake + - Unsuccessful Team + - Disagreement + - Bent a Rule + - Delivered a Difficult Message + - Displayed Integrity + - Took a Shortcut + - Didn’t Follow the Rules + - Emergency Response + - Dealt with Disabilities + - Solved a Big Problem + - Continuous Improvement + - Handled Sensitive Information + + ### Behavioral Question Starters + Behavioral questions usually start with phrases like: + - “Tell me a time when…†+ - “Can you tell me about a time when you…†+ - "Describe a situation where you had to…" + - "Give me an example of how you…" + - "Have you ever been in a position where you needed to…" + - "Walk me through a time when you…" + + ### STARTPOP Framework + The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. + + Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life. + + #### Components of STARTPOP: + 1. **Situation**: + - Set up the answer in the mind of the question asker. + - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long). + - Include dates, ages, places, and circumstances. + + 2. **Task**: + - Explain what you needed to do and why you needed to do it. + - Recap the situation quickly from a different angle. + + 3. **Actions**: + - Outline both the negative and the positive way of doing things. + - Show high moral character in every question. + + 4. **Results**: + - Explain what happened as a result of your actions. + - Share results in a time-specific manner (e.g., “5 months later X happenedâ€). + + 5. **Transitions**: + - Speak in a way that aligns with professional expectations. + - Ensure coherence in your responses. + + 6. **Personal Lessons**: + - Discuss what you learned about yourself. + - Address any concerns the interviewers might have about hiring you. + + 7. **Other People Observations**: + - Share insights about others in the situation. + - Keep it short and to the point. + + 8. **Professional Connection**: + - Relate your experience directly to the fire service. + - Conclude strongly, avoiding phrases like “and so yeah…â€. + ----END------ + + NOTE: THE QUIZ FOCUES ON BULIDNG USER CONFIDENCE BY ANANLYZING THE QUESTIONS AND FRAMEWORK FOR EACH QUESTION IN THE STARTPOP FRAMEWORK PDF,SOLELY USE THIS PDF PROVIDED BY THE USER + BASED ON THIS FRAMEWORK , CREATE INTERVIEW BASED QUIZ FOR FIRE FIGHTING ROLE BY ANALYZING THIS DOCUMENT + NOTE : THE QUIZ SHOULD NOT BE BASED ON STARTPOP FRAMEWORK ITSELF BUT ANALYZE THE STARTPOP FRAMEWORK PRESENTED TO GENERATE INTERVIEW BASED QUIZ + e.g "The STARTPOP framework is specifically designed for firefighter interviews", THIS KIND OF QUESTION SHOULD NOT BE ASKED IN THE QUIZ.... + Thank you for your thorough and precise processing! + STARTPOP FULL PDF :{startpop_pdf} + question type : {quiz_type} + P + <|eot_id|><|start_header_id|>user<|end_header_id|>""", + input_variables=["startpop_pdf", "quiz_type", "question"], + ) + + # Pipeline to process the prompt and parse output + quiz_router = quiz_prompt | llm_temp | JsonOutputParser() + + # Call the pipeline and generate the cohesive output + output = quiz_router.invoke({"startpop_pdf": startpop_pdf, "quiz_type": quiz_type, "question": "Your question here"}) + + return output + except Exception as e: + print(f"Error:{e}") + return {} + + diff --git a/scripts/generate_theme.py b/scripts/generate_theme.py new file mode 100644 index 0000000..a358042 --- /dev/null +++ b/scripts/generate_theme.py @@ -0,0 +1,239 @@ +import os +import requests +from dotenv import load_dotenv +from langchain_openai import ChatOpenAI +from langchain_core.prompts.prompt import PromptTemplate +from langchain_core.output_parsers import StrOutputParser, JsonOutputParser +from langchain_openai import OpenAIEmbeddings +from langchain_core.documents import Document +from uuid import uuid4 +import json +import getpass +import numpy as np +from concurrent.futures import ThreadPoolExecutor, as_completed +from sklearn.metrics.pairwise import cosine_similarity +from typing import List +import time +from datetime import datetime +import pytz +import logging +load_dotenv() + +os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY") + +llm_temp = ChatOpenAI(model="gpt-4o-mini", temperature=0.7) + +def generate_theme(conversation_data,resume,full_history,feedback=None, previous_result=None) -> dict: + try: + # Define prompt for summarizing and extracting the required fields + theme_prompt = PromptTemplate( + template="""<|begin_of_text|><|start_header_id|>system<|end_header_id|> + You are a Fire Fighter Interview preparation assistant that generates STARTPOP FORMAT BASED on user interaction with AI. + You will be provided with the current theme, user interaction with AI (alongside user resume), and data. + +Your responsibility is to carefully analyze user interaction with AI, the theme, and the user RESUME to generate a STARTPOP format for the theme. +NOTE: A SINGLE QUESTION IS GENERATED WITH DETAILED STARTPOP FORMAT +NOTE: For more Context, user full work history may also be provided +TO KNOW MORE ABOUT THE PROJECT READ BELOW +---START------ +Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you. + +### 7 Main Concepts: +- **High Performance Teams** +- **Situational Awareness** +- **Being a Great Problem Solver** +- **Customer Service** +- **Building Construction, Mechanical Aptitude** +- **Emergency Medicine Experience** +- **Mental and Physical Health** + +Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. + +We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. + +Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect? + +Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service. + +### 20 Important Themes +Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions: +- Customer Service +- Conflict +- Challenge +- Leadership +- Stress +- Successful Team +- Diversity +- Mistake +- Unsuccessful Team +- Disagreement +- Bent a Rule +- Delivered a Difficult Message +- Displayed Integrity +- Took a Shortcut +- Didn’t Follow the Rules +- Emergency Response +- Dealt with Disabilities +- Solved a Big Problem +- Continuous Improvement +- Handled Sensitive Information + +### Behavioral Question Starters +Behavioral questions usually start with phrases like: +- “Tell me a time when…†+- “Can you tell me about a time when you…†+- "Describe a situation where you had to…" +- "Give me an example of how you…" +- "Have you ever been in a position where you needed to…" +- "Walk me through a time when you…" + +### STARTPOP Framework +The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. + +Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life. + +#### Components of STARTPOP: +1. **Situation**: + - Set up the answer in the mind of the question asker. + - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long). + - Include dates, ages, places, and circumstances. + +2. **Task**: + - Explain what you needed to do and why you needed to do it. + - Recap the situation quickly from a different angle. + +3. **Actions**: + - Outline both the negative and the positive way of doing things. + - Show high moral character in every question. + +4. **Results**: + - Explain what happened as a result of your actions. + - Share results in a time-specific manner (e.g., “5 months later X happenedâ€). + +5. **Transitions**: + - Speak in a way that aligns with professional expectations. + - Ensure coherence in your responses. + +6. **Personal Lessons**: + - Discuss what you learned about yourself. + - Address any concerns the interviewers might have about hiring you. + +7. **Other People Observations**: + - Share insights about others in the situation. + - Keep it short and to the point. + +8. **Professional Connection**: + - Relate your experience directly to the fire service. + - Conclude strongly, avoiding phrases like “and so yeah…â€. + +EXAMPLE STARTPOP + +question: Tell me a time when you made a MISTAKE how did you fix it? (Eaves Cleaning Mistake) +Situation: +• In the Fall my business, Tiger Building Services, does a lot of eavestrough cleaning. +• Back in 2019 I was working with an employee in my truck. We were working nicely to hit my daily revenue target. +• We got to the last job of the day; we were tired and running out of sunlight. But I really wanted to squeeze it in. +• We have procedures to follow in order to work safely and effectively. My goal is to be as low impact as possible. +• I made a mistake when we used the handheld blowers on their eaves to blow out the debris without checking how +wet the debris was or the ground around the back of the house. It made a muddy mess all over their white deck. +• They were livid. Swearing and completely unhappy with how we were doing the work. I take ownership of my +mistakes and realized I screwed up by using blowers instead of hand bombing it. +Task: +• My task was to defuse the situation and clean up the mess as quickly as possible. +• I had to do it because as the owner of the company it was my reputation on the line. We got the job through one +of the apps that we use to fill out our schedule and it is imperative that I make sure their customers have good +experiences with us so that we keep our top position on the app. +• I am also a man of integrity and try to be always empathetic, so I felt obligated to correct the mistake. +Action: +• The wrong approach would have been to match the customers energy and just as belligerent and abrasive. It +would have escalated the situation to a point where things could have gotten ugly and pretty physical. +• It would have also been wrong to just ignore or make fun of the customer and the problem we created, or to just +pack our ladders and tools and run away as quickly as possible. +• The correct approach was to get off the roof safely and speak with the customer on the ground eye to eye. +• I made sure to do that and then apologized for the mess that we made. I empathized with them and the way they +were feeling. I told them that it was our mistake, and we will work to correct it immediately. +• I switched our strategy. Told the employee to clean use their hand for the gutters while I cleaned the deck. +Results and Transitions: +• It was a losing situation for me in the short run. The job ended up taking a bit longer than expected and I actually +told them that we would waive the fees due to the inconveniences we created. +• After we finished up, I gave her a plan of action. She would get the eaves cleaning for free, and we would return +the following day with our soft wash system to make sure that she had a sparkling clean deck also free of charge. +• The next morning when we finished the free soft wash, she was happy with the resolution plan and Jiffy was +impressed with our ability to correct the mistake and alleviate the situation. +Personal Lessons: +• What I learned about myself was that I do make mistakes, but I am the type of person that owns up to it. +• I am also honest and empathetic, and I can perform in stressful situations and that I could de-escalate tense +situations, to be adaptable and think quickly on the fly. +• I used the LAST tactic for good customer service: Listened, Apologized, Solved the problem, then thanked them. +• I took the full brunt of their anger, made an action plan that instantly calmed the situation and then acted on it to +make them happy with the service. +Observations of Others: +• What I learned about other people is that people are entitled to their reactions, emotions, and feelings. +• I respect those emotions and have learned that following actionable game plans will help avoid or resolve issues. +• I know the term proper planning prevents poor performance is applicable here. +• There is a reason organization’s have SOPs and SOGs. They are there to be followed in order to avoid mistakes. +Professional Connection: +• My biggest takeaway was it is okay to make mistakes, but it is not okay to not learn from them. +• I know that the team on Markham Fire sometimes makes mistakes on the firegrounds, but they are also the type +of people that own up to their mistake and learn from them. +• I also know that Chief Grant promotes having an open and transparent organization that is not afraid from +admitting an error or correcting it. + +---END------ + + +JSON Output Requirements: Generate a list of well-structured JSON output STARTPOP with question and correcpoding STARTPPOP with the following fields: + - theme_title: The title the theme provided + - question: The question + - Situation: A bulleted list of texts as seen in examples + - Task: A bulleted list of texts as seen in examples + - Action: A bulleted list of texts as seen in examples + - Personal Lessons: A bulleted list of texts as seen in examples + - Results and Transitions: A bulleted list of texts as seen in examples + - Observations of Others: A bulleted list of texts as seen in examples + - Professional Connection: A bulleted list of texts as seen in examples + +Review Process: + - Carefully review all news items to confirm they align with the specified theme and meet relevance criteria. + - Ensure the JSON format is flawless, comprehensive, and well-structured, with all fields included and correctly formatted. + +NOTE: 1. you MAY BE PROVIDED WITH FEEDBACK AND PREVIOUS RESULT, MEANING AI HAS GENERATED STARTPOP BEFORE AND MAYBE USER IS NOT SATISFIED WITH THE RESULT THEN YOU GENERATE A NEW ONE BASED ON THE FEEDBACK +NOTE: Each question will have a correpoding STARTPOP feilds +Return just the JSON output without any other explanation or comments. + +Thank you for your thorough and precise processing! + CONVERSATION DATA :{conversation_data} + FEEDBACK: {feedback} + PREVIOUS RESULT: {previous_result} + USER RESUME : {resume} + FULL WORK HISTORY : {full_history} + <|eot_id|><|start_header_id|>user<|end_header_id|> + + RULES FOR GENERATING EACH COMPONENT - FOLLOW THESE RULES THOROUGHLY MAKE SURE YOUR OUTPUT IS WELL DETAILED + + THE FRAME WORK MUST BE DETAILED WITH THE FOLLWWING RULES + 1. Situation : 75 - 100 words + 2. Task: 50 words + 3. Actions: 2 Negative actions and 2 positive actions + 4. Results: 25 - 5o words + 5. Personal Lessons : 25 - 50 words + 6. Observation of others: 25 words + 7. Professional connections: 25 - 50 words and in addition to the 25-50 words: + - Connect to the theme of questions (Be creative here) + - Ask to be part of their team(be creattive here) + """, + input_variables=["resume","conversation_data", "feedback", "previous_result","full_history"], + ) + + # Pipeline to process the prompt and parse output + theme_router = theme_prompt | llm_temp | JsonOutputParser() + + # Call the pipeline and generate the cohesive output + output = theme_router.invoke({"conversation_data": conversation_data, "feedback": feedback, "previous_result": previous_result,"resume":resume,"full_history":full_history}) + + print(f"Output : {output}") + return output + + except Exception as e: + print(f"Error:{e}") + return {} \ No newline at end of file diff --git a/src/llm.py b/src/llm.py new file mode 100644 index 0000000..7ab1106 --- /dev/null +++ b/src/llm.py @@ -0,0 +1,197 @@ +import json +from typing import List, Dict, Optional, TypedDict, Sequence, Annotated +from dataclasses import dataclass +from pathlib import Path +from datetime import datetime +from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder +from langchain_core.messages import HumanMessage, AIMessage, BaseMessage +from langgraph.checkpoint.memory import MemorySaver +from langgraph.graph import START, MessagesState, StateGraph +from utils.utils import format_questions_text +from src.prompts import chat_prompt +from langchain_openai import ChatOpenAI +@dataclass +class Message: + role: str # 'human' or 'ai' + content: str + timestamp: str + +QUESTIONS_PATH = "./data/config_files/questions.json" +with open(QUESTIONS_PATH, "r") as f: + questions = json.load(f) + +prompt_template = None +MODEL = "gpt-4o-mini" +def initialize_workflow(model) -> StateGraph: + """Initialize LangGraph workflow""" + workflow = StateGraph(state_schema=MessagesState) + memory = MemorySaver() + + def call_model(state: MessagesState): + prompt = prompt_template.invoke({"messages": state["messages"], "language": state["language"]}) + response = model.invoke(prompt) + return {"messages": [response]} + + workflow.add_edge(START, "model") + workflow.add_node("model", call_model) + return workflow.compile(checkpointer=memory) + + +def setup_prompt_template(theme: int, resume: str) -> ChatPromptTemplate: + """Set up the prompt template""" + return ChatPromptTemplate.from_messages([ + ("system", chat_prompt(theme, resume)), + MessagesPlaceholder(variable_name="messages") + ]) + +def parse_ai_response(content: str) -> Dict: + """Parse AI response content into expected format""" + try: + response = json.loads(content) + return { + "message": response.get("message", ""), + "end": response.get("end", "no") == "yes" + } + except json.JSONDecodeError: + return { + "message": content, + "end": False + } + +def add_message(storage_path: Path, conversation_id: str, role: str, content: str) -> None: + """Add a message to the conversation history""" + message_data = { + "role": role, + "content": content, + "timestamp": datetime.now().isoformat() + } + + conversations = load_conversations(storage_path) + if conversation_id not in conversations: + conversations[conversation_id] = {"messages": []} + conversations[conversation_id]["messages"].append(message_data) + save_conversations(storage_path, conversations) + + +def get_conversation_history(conversation_id: str, storage_path: Path) -> List[Message]: + """Get the conversation history""" + conversations = load_conversations(storage_path) + if conversation_id not in conversations: + return None + + return [ + Message( + role=msg["role"], + content=msg["content"], + timestamp=msg["timestamp"] + ) + for msg in conversations[conversation_id]["messages"] + ] + +def load_conversations(storage_path: Path) -> Dict: + """Load conversations from storage file""" + try: + with open(storage_path, 'r') as f: + return json.load(f) + except FileNotFoundError: + return {} + +def save_conversations(storage_path: Path, conversations: Dict) -> None: + """Save conversations to storage file""" + with open(storage_path, 'w') as f: + json.dump(conversations, f, indent=2) + +def convert_to_langchain_messages(messages: List[Message]) -> List[HumanMessage | AIMessage]: + """Convert our Message objects to LangChain message objects""" + converted_messages = [] + for msg in messages: + if msg.role == "human": + converted_messages.append(HumanMessage(content=msg.content)) + else: + converted_messages.append(AIMessage(content=msg.content)) + return converted_messages + + +def ai_chat(query: str, conversation_id: str, theme_id: int, resume: str) -> str: + """Main chat function that processes queries and manages conversation""" + storage_path = Path("conversations.json") + + class State(TypedDict): + messages: Annotated[Sequence[BaseMessage], "The messages in the conversation"] + language: str + # Initialize model and workflow + model = ChatOpenAI(model=MODEL) + workflow = StateGraph(state_schema=State) + + + + def call_model(state: State): + prompt_template = setup_prompt_template(theme_id, resume) + prompt = prompt_template.invoke({ + "messages": state["messages"], + "language": state["language"] + }) + response = model.invoke(prompt) + return {"messages": [response]} + + workflow.add_edge(START, "model") + workflow.add_node("model", call_model) + + memory = MemorySaver() + app = workflow.compile(checkpointer=memory) + + # Get conversation history + history = get_conversation_history(conversation_id, storage_path) + + config = {"configurable": {"thread_id": conversation_id}} + language = "English" + + if not history: + # New conversation + input_messages = [HumanMessage(content=query)] if query else [HumanMessage(content="Let's get started")] + output = app.invoke( + {"messages": input_messages, "language": language}, + config + ) + else: + # Existing conversation + history = convert_to_langchain_messages(history) + input_messages = history + [HumanMessage(content=query)] if query else history + output = app.invoke( + {"messages": input_messages, "language": language}, + config + ) + + # Store messages + if query: + add_message(storage_path, conversation_id, "human", query) + add_message(storage_path, conversation_id, "ai", output["messages"][-1].content) + + return output["messages"][-1].content + + +# Example usage: +if __name__ == "__main__": + # Sample resume + sample_resume = """ + John Doe + EMT-B Certified + 5 years experience as volunteer firefighter + Bachelor's in Fire Science + """ + + # Sample conversation + conversation_id = "12345" + theme_id = 1 # Customer Service theme + + # Start conversation + + + # Continue conversation + follow_up = ai_chat( + query="What was my last questions?", + conversation_id=conversation_id, + theme_id=theme_id, + resume=sample_resume + ) + print("AI:", follow_up) diff --git a/src/prompts.py b/src/prompts.py new file mode 100644 index 0000000..6d5daad --- /dev/null +++ b/src/prompts.py @@ -0,0 +1,134 @@ +import json +from typing import List, Dict, Optional +from dataclasses import dataclass +from utils.utils import format_questions_text, format_theme_text +@dataclass +class Message: + role: str # 'human' or 'ai' + content: str + timestamp: str + + + +QUESTIONS_PATH = "./data/config_files/questions.json" +with open(QUESTIONS_PATH, "r") as f: + questions = json.load(f) + +def chat_prompt(theme,resume): + return f""" + You are a Fire Fighter Interview preparation assistant. + +Throughout most Probationary Firefighter Interviews, they will be evaluating a ton of things. Typically, they want to see how you align with the **7 Main Concepts of Firefighting**. They are also watching how nervous you are, your communication skills, and your overall general competence for the role. At the end of the day, you want them to like you. + +### 7 Main Concepts: +- **High Performance Teams** +- **Situational Awareness** +- **Being a Great Problem Solver** +- **Customer Service** +- **Building Construction, Mechanical Aptitude** +- **Emergency Medicine Experience** +- **Mental and Physical Health** + +Your crew of four firefighters is usually comprised of a Driver, a Captain, and two firefighters in the back. That is a High-Performance Team. + +We are frequently dispatched to calls that require using our understanding of Building Construction Concepts, Mechanical Aptitude, and Emergency Medical Experience. When you respond to an emergency event that is inherently dangerous (like a vehicle fire, a car accident in a slanted ditch, a person trapped under a machine, a house fire, or a chemical suicide), you need to use your Situational Awareness to keep that crew safe. + +Sometimes the tools, training, and tactics that you have been taught work perfectly. Sometimes they don’t. Can you be a Good Problem Solver to quickly come up with something to make the situation better for the people, places, and environments that we protect? + +Ultimately, your crew will be serving the public, and the chiefs need to know that you can be trained to be above their desired standard so that you give the public great Customer Service. + +### 20 Important Themes +Consider the 7 concepts to be the soil. All of your stories grow out of that soil. But not every story works for every question. You need to handpick the right one at the right times to give them. Sort of like how you handpick flowers out of the soil. You NEED to have **20 different flowers** so that you are fully prepared for whatever behavioral question they throw at you. These are the **20 Themes** that you would use for behavioral questions: +- Customer Service +- Conflict +- Challenge +- Leadership +- Stress +- Successful Team +- Diversity +- Mistake +- Unsuccessful Team +- Disagreement +- Bent a Rule +- Delivered a Difficult Message +- Displayed Integrity +- Took a Shortcut +- Didn’t Follow the Rules +- Emergency Response +- Dealt with Disabilities +- Solved a Big Problem +- Continuous Improvement +- Handled Sensitive Information + +### Behavioral Question Starters +Behavioral questions usually start with phrases like: +- “Tell me a time when…†+- “Can you tell me about a time when you…†+- "Describe a situation where you had to…" +- "Give me an example of how you…" +- "Have you ever been in a position where you needed to…" +- "Walk me through a time when you…" + +Your goal is to engage in conversation with the user. You will be provided with the current theme, the resume of the user, and example general competency questions and behavioral questions. +USER_RESUME FROM START TO END : +--- START --- +{resume} +--- END --- + +### STARTPOP Framework +The STAR Format is what most people tell you to do in order to answer a firefighter interview question. It’s a great framework. I highly recommend it. I just advise that you pump it up even further. I call it **STARTPOP**. + +Try and pull from different parts of your life. My Chief Training Officer told me that he enjoys candidates that are able to use different experiences to answer the questions. Listening to someone drone on and on about a singular time or type of event in their life is a massive turn-off to the interview panel. That’s a bad thing. Just like most things, variety is the spice of life. + +#### Components of STARTPOP: +1. **Situation**: + - Set up the answer in the mind of the question asker. + - Your storytelling skills matter here. It has to be concise and impactful (no more than 25 seconds long). + - Include dates, ages, places, and circumstances. + +2. **Task**: + - Explain what you needed to do and why you needed to do it. + - Recap the situation quickly from a different angle. + +3. **Actions**: + - Outline both the negative and the positive way of doing things. + - Show high moral character in every question. + +4. **Results**: + - Explain what happened as a result of your actions. + - Share results in a time-specific manner (e.g., “5 months later X happenedâ€). + +5. **Transitions**: + - Speak in a way that aligns with professional expectations. + - Ensure coherence in your responses. + +6. **Personal Lessons**: + - Discuss what you learned about yourself. + - Address any concerns the interviewers might have about hiring you. + +7. **Other People Observations**: + - Share insights about others in the situation. + - Keep it short and to the point. + +8. **Professional Connection**: + - Relate your experience directly to the fire service. + - Conclude strongly, avoiding phrases like “and so yeah…â€. + Current theme with More context about the theme for Creating The Professional Connection (Lessons Learned): {format_theme_text(theme)} + +Sample General Competency QUESTIONS and Situational Questions: {format_questions_text(questions,'General Competency Questions')} +Sample Situational Questions: {format_questions_text(questions,'Situational Questions')} + +Your task is to engage the user in conversation, ask relevant questions, that will ultimately help them prepare a strong STARTPOP response based on their experiences and the current theme. +YOU WILL BE PROVIDED WITH THE USER RESUME, ASK 1 QUESTION AT A TIME AND MAKE IT CONVERSATIONAL AND INTERESTING. +These responses will be saved and later used to generate a STARTPOP framework by US (DO NOT WORRY ABOUT THAT, WE WILL BE THE ONE TO GENERATE, JUST ENGAGE USER WITH QUESTION AND ANSWER). +Output format +CUURENT TEHEME USER IS INTERESTED IN {format_theme_text(theme)} +NOTE: !!! EXPLICITLY FOCUS ON THE CURRENT THEME SPECIFIED +WILL BE IN JSON, avoid puttting ```json, before or after , return the excat json with nothing else + message: + end: "yes" or "no" if you are done with asking questions and confident the responses are okay enough to prepare STARTPOP by us +NOTE: DO NOT KEEP THE CONVERSATION , CAREFULL ANALYZE USER RESUME AND THE PROVIDED EXAMPLES QUESTIONS AND ALL CONTEXT , ASK RELEVANT QUESTION BASED ON THE THEME AND THAT IS ALL +""" + + + diff --git a/test.py b/test.py new file mode 100644 index 0000000..a6a9c06 --- /dev/null +++ b/test.py @@ -0,0 +1,195 @@ +import json +from typing import List, Dict, Optional, TypedDict, Sequence, Annotated +from dataclasses import dataclass +from pathlib import Path +from datetime import datetime +from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder +from langchain_core.messages import HumanMessage, AIMessage, BaseMessage +from langgraph.checkpoint.memory import MemorySaver +from langgraph.graph import START, MessagesState, StateGraph +from utils.utils import format_questions_text +from src.prompts import chat_prompt +from langchain_openai import ChatOpenAI +@dataclass +class Message: + role: str # 'human' or 'ai' + content: str + timestamp: str + +QUESTIONS_PATH = "./data/config_files/questions.json" +with open(QUESTIONS_PATH, "r") as f: + questions = json.load(f) + +prompt_template = None +MODEL = "gpt-4o" +def initialize_workflow(model) -> StateGraph: + """Initialize LangGraph workflow""" + workflow = StateGraph(state_schema=MessagesState) + memory = MemorySaver() + + def call_model(state: MessagesState): + prompt = prompt_template.invoke({"messages": state["messages"], "language": state["language"]}) + response = model.invoke(prompt) + return {"messages": [response]} + + workflow.add_edge(START, "model") + workflow.add_node("model", call_model) + return workflow.compile(checkpointer=memory) + + +def setup_prompt_template(theme: int, resume: str) -> ChatPromptTemplate: + """Set up the prompt template""" + return ChatPromptTemplate.from_messages([ + ("system", chat_prompt(theme, resume)), + MessagesPlaceholder(variable_name="messages") + ]) + +def parse_ai_response(content: str) -> Dict: + """Parse AI response content into expected format""" + try: + response = json.loads(content) + return { + "message": response.get("message", ""), + "end": response.get("end", "no") == "yes" + } + except json.JSONDecodeError: + return { + "message": content, + "end": False + } + +def add_message(storage_path: Path, conversation_id: str, role: str, content: str) -> None: + """Add a message to the conversation history""" + message_data = { + "role": role, + "content": content, + "timestamp": datetime.now().isoformat() + } + + conversations = load_conversations(storage_path) + if conversation_id not in conversations: + conversations[conversation_id] = {"messages": []} + conversations[conversation_id]["messages"].append(message_data) + save_conversations(storage_path, conversations) + + +def get_conversation_history(conversation_id: str, storage_path: Path) -> List[Message]: + """Get the conversation history""" + conversations = load_conversations(storage_path) + if conversation_id not in conversations: + return None + + return [ + Message( + role=msg["role"], + content=msg["content"], + timestamp=msg["timestamp"] + ) + for msg in conversations[conversation_id]["messages"] + ] + +def load_conversations(storage_path: Path) -> Dict: + """Load conversations from storage file""" + try: + with open(storage_path, 'r') as f: + return json.load(f) + except FileNotFoundError: + return {} + +def save_conversations(storage_path: Path, conversations: Dict) -> None: + """Save conversations to storage file""" + with open(storage_path, 'w') as f: + json.dump(conversations, f, indent=2) + +def convert_to_langchain_messages(messages: List[Message]) -> List[HumanMessage | AIMessage]: + """Convert our Message objects to LangChain message objects""" + converted_messages = [] + for msg in messages: + if msg.role == "human": + converted_messages.append(HumanMessage(content=msg.content)) + else: + converted_messages.append(AIMessage(content=msg.content)) + return converted_messages +def ai_chat(query: str, conversation_id: str, theme_id: int, resume: str) -> str: + """Main chat function that processes queries and manages conversation""" + storage_path = Path("conversations.json") + + class State(TypedDict): + messages: Annotated[Sequence[BaseMessage], "The messages in the conversation"] + language: str + # Initialize model and workflow + model = ChatOpenAI(model=MODEL) + workflow = StateGraph(state_schema=State) + + + + def call_model(state: State): + prompt_template = setup_prompt_template(theme_id, resume) + prompt = prompt_template.invoke({ + "messages": state["messages"], + "language": state["language"] + }) + response = model.invoke(prompt) + return {"messages": [response]} + + workflow.add_edge(START, "model") + workflow.add_node("model", call_model) + + memory = MemorySaver() + app = workflow.compile(checkpointer=memory) + + # Get conversation history + history = get_conversation_history(conversation_id, storage_path) + + config = {"configurable": {"thread_id": conversation_id}} + language = "English" + + if not history: + # New conversation + input_messages = [HumanMessage(content=query)] if query else [HumanMessage(content="Let's get started")] + output = app.invoke( + {"messages": input_messages, "language": language}, + config + ) + else: + # Existing conversation + history = convert_to_langchain_messages(history) + input_messages = history + [HumanMessage(content=query)] if query else history + output = app.invoke( + {"messages": input_messages, "language": language}, + config + ) + + # Store messages + if query: + add_message(storage_path, conversation_id, "human", query) + add_message(storage_path, conversation_id, "ai", output["messages"][-1].content) + + return output["messages"][-1].content + + +# Example usage: +if __name__ == "__main__": + # Sample resume + sample_resume = """ + John Doe + EMT-B Certified + 5 years experience as volunteer firefighter + Bachelor's in Fire Science + """ + + # Sample conversation + conversation_id = "12345" + theme_id = 1 # Customer Service theme + + # Start conversation + + + # Continue conversation + follow_up = ai_chat( + query="What was my last questions?", + conversation_id=conversation_id, + theme_id=theme_id, + resume=sample_resume + ) + print("AI:", follow_up) diff --git a/upload_folder/Resume_-_Erika_Kiviaho.pdf b/upload_folder/Resume_-_Erika_Kiviaho.pdf new file mode 100644 index 0000000000000000000000000000000000000000..768cdde90bacf9a189959a1dc094ebbb49dfb986 GIT binary patch literal 169090 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%0Dm$gPnHAla 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 iE%E>29eyQ;6@mNi6rO)zwu%?T{|e%Uah&#- str: + """ + Convert a .doc or .docx file to PDF using Spire.Doc. + + Args: + doc_path (str): The path to the .doc or .docx file. + + Returns: + str: The path to the converted PDF file. + """ + pdf_path = os.path.splitext(doc_path)[0] + '.pdf' + + # Create a Document object + document = Document() + # Load the Word document + document.LoadFromFile(doc_path) + # Save as PDF + document.SaveToFile(pdf_path, FileFormat.PDF) + document.Close() + + return pdf_path + +def load_document(file_path: str): + """ + Utility function to load a PDF, DOCX, or DOC file by first converting it to PDF. + + Args: + file_path (str): The path to the file to load. + + Returns: + List[Document]: A list of Document objects representing the contents of the file. + """ + + try: + extension = os.path.splitext(file_path)[1].lower() + + if extension in ['.doc', '.docx']: + # Convert .doc or .docx to PDF first + pdf_path = convert_word_to_pdf(file_path) + loader = PyPDFLoader(pdf_path) + elif extension == '.pdf': + loader = PyPDFLoader(file_path) + else: + raise ValueError(f"Unsupported file type: {extension}. Only .pdf, .docx, and .doc are supported.") + + return loader.load() + except Exception as e: + print(f"Error loading document: {str(e)}") + return None \ No newline at end of file diff --git a/utils/utils.py b/utils/utils.py new file mode 100644 index 0000000..467db7b --- /dev/null +++ b/utils/utils.py @@ -0,0 +1,73 @@ +import os +import requests +import json +from PyPDF2 import PdfReader + +base_path = os.path.join("data", "config_files") +THEME_CONTEXT_PATH = os.path.join(base_path, "theme_context.json") + +with open(THEME_CONTEXT_PATH, "r") as f: + themes = json.load(f) + +def delete_file(file_path): + try: + os.remove(file_path) + print(f"Deleted file: {file_path}") + except OSError as e: + print(f"Error deleting file {file_path}: {e}") + + + +def delete_all_files_in_directory(directory_path): + try: + for filename in os.listdir(directory_path): + file_path = os.path.join(directory_path, filename) + if os.path.isfile(file_path): + os.remove(file_path) + print(f"Deleted file: {file_path}") + except OSError as e: + print(f"Error deleting files in {directory_path}: {e}") + + +def format_questions_text(questions_dict,key): + """Format questions as text with dashes.""" + formatted_text = "" + for question in questions_dict[key]: + formatted_text += f"- {question['question']}\n" + return formatted_text.strip() + + + +def format_theme_text(theme_id): + """Format questions as text with dashes.""" + formatted_text = "" + matching_themes = [t for t in themes if t["id"] == theme_id] + current_theme = matching_themes[0] + formatted_text += f"- {current_theme['id']}\n" + formatted_text += f"- {current_theme['theme']}\n" + formatted_text += f"- {current_theme['context']}\n" + + return formatted_text.strip() + + + +def download_pdf_and_extract_text(url: str) -> str: + # Create a temporary file path + temp_file_path = 'temp.pdf' + + # Download the PDF from the URL + response = requests.get(url) + response.raise_for_status() # Raise an error for bad responses + with open(temp_file_path, 'wb') as f: + f.write(response.content) + + # Load the PDF + reader = PdfReader(temp_file_path) + + # Extract text from all pages and combine into one text + combined_text = "\n\n".join(page.extract_text() for page in reader.pages if page.extract_text()) + + # Delete the temporary file + os.remove(temp_file_path) + + return combined_text \ No newline at end of file