# langchain: https://python.langchain.com/ from dataclasses import dataclass import streamlit as st from langchain.callbacks import get_openai_callback from langchain.memory import ConversationBufferMemory from langchain.chains import RetrievalQA, ConversationChain from langchain.prompts.prompt import PromptTemplate from prompts.prompts import templates from typing import Literal from langchain.vectorstores import FAISS from langchain.text_splitter import NLTKTextSplitter from PyPDF2 import PdfReader from prompts.prompt_selector import prompt_sector from streamlit_lottie import st_lottie import json from IPython.display import Audio import nltk from langchain_google_genai import ChatGoogleGenerativeAI import getpass import os from langchain_google_genai import GoogleGenerativeAIEmbeddings @dataclass class Message: """Class for keeping track of interview history.""" origin: Literal["human", "ai"] message: str def save_vector(resume): """embeddings""" nltk.download('punkt') pdf_reader = PdfReader(resume) text = "" for page in pdf_reader.pages: text += page.extract_text() # Split the document into chunks text_splitter = NLTKTextSplitter() texts = text_splitter.split_text(text) embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") docsearch = FAISS.from_texts(texts, embeddings) return docsearch def initialize_session_state_resume(position, resume): # convert resume to embeddings if 'docsearch' not in st.session_state: st.session_state.docserch = save_vector(resume) # retriever for resume screen if 'retriever' not in st.session_state: st.session_state.retriever = st.session_state.docserch.as_retriever(search_type="similarity") # prompt for retrieving information if 'chain_type_kwargs' not in st.session_state: st.session_state.chain_type_kwargs = prompt_sector(position, templates) # interview history if "resume_history" not in st.session_state: st.session_state.resume_history = [] st.session_state.resume_history.append(Message(origin="ai", message="Hello, I am your interivewer today. I will ask you some questions regarding your resume and your experience. Please start by saying hello or introducing yourself. Note: The maximum length of your answer is 4097 tokens!")) # token count if "token_count" not in st.session_state: st.session_state.token_count = 0 # memory buffer for resume screen if "resume_memory" not in st.session_state: st.session_state.resume_memory = ConversationBufferMemory(human_prefix = "Candidate: ", ai_prefix = "Interviewer") # guideline for resume screen if "resume_guideline" not in st.session_state: llm = ChatGoogleGenerativeAI( model="gemini-pro") st.session_state.resume_guideline = RetrievalQA.from_chain_type( llm=llm, chain_type_kwargs=st.session_state.chain_type_kwargs, chain_type='stuff', retriever=st.session_state.retriever, memory = st.session_state.resume_memory).run("Create an interview guideline and prepare only two questions for each topic. Make sure the questions tests the knowledge") # llm chain for resume screen if "resume_screen" not in st.session_state: llm = ChatGoogleGenerativeAI( model="gemini-pro") PROMPT = PromptTemplate( input_variables=["history", "input"], template= """I want you to act as an interviewer strictly following the guideline in the current conversation. Ask me questions and wait for my answers like a human. Do not write explanations. Candidate has no assess to the guideline. Only ask one question at a time. Do ask follow-up questions if you think it's necessary. Do not ask the same question. Do not repeat the question. Candidate has no assess to the guideline. You name is GPTInterviewer. I want you to only reply as an interviewer. Do not write all the conversation at once. Candiate has no assess to the guideline. Current Conversation: {history} Candidate: {input} AI: """) st.session_state.resume_screen = ConversationChain(prompt=PROMPT, llm = llm, memory = st.session_state.resume_memory) # llm chain for generating feedback if "resume_feedback" not in st.session_state: llm = ChatGoogleGenerativeAI( model="gemini-pro") st.session_state.resume_feedback = ConversationChain( prompt=PromptTemplate(input_variables=["history","input"], template=templates.feedback_template), llm=llm, memory=st.session_state.resume_memory, ) def answer_call_back(): '''callback function for answering user input''' # user input human_answer = st.session_state.answer st.session_state.history.append( Message("human", human_answer) ) # OpenAI answer and save to history llm_answer = st.session_state.resume_screen.run(human_answer) st.session_state.history.append( Message("ai", llm_answer) ) st.session_state.token_count += len(llm_answer.split()) return llm_answer if "GOOGLE_API_KEY" not in os.environ: os.environ["GOOGLE_API_KEY"] = "AIzaSyCA4__JMC_ZIQ9xQegIj5LOMLhSSrn3pMw" def app(): st.title("Resume Screen") st.session_state.history = [] with open('job_description.json', 'r') as f: jd = json.load(f) position = jd resume = st.file_uploader("Upload your resume", type=["pdf"]) #st.toast("4097 tokens is roughly equivalent to around 800 to 1000 words or 3 minutes of speech. Please keep your answer within this limit.") if position and resume: # intialize session state initialize_session_state_resume(position, resume) credit_card_placeholder = st.empty() col1, col2 = st.columns(2) with col1: feedback = st.button("Get Interview Feedback") with col2: guideline = st.button("Show me interview guideline!") chat_placeholder = st.container() answer_placeholder = st.container() audio = None # if submit email adress, get interview feedback imediately if guideline: st.markdown(st.session_state.resume_guideline) if feedback: evaluation = st.session_state.resume_feedback.run("please give evalution regarding the interview") st.markdown(evaluation) st.download_button(label="Download Interview Feedback", data=evaluation, file_name="interview_feedback.txt") st.stop() else: with answer_placeholder: voice: bool = st.checkbox("I would like to speak with AI Interviewer!") if voice: print("voice") #st.warning("An UnboundLocalError will occur if the microphone fails to record.") else: answer = st.chat_input("Your answer") if answer: st.session_state['answer'] = answer audio = answer_call_back() with chat_placeholder: for answer in st.session_state.resume_history: if answer.origin == 'ai': if audio: with st.chat_message("assistant"): st.write(answer.message) st.write(audio) else: with st.chat_message("assistant"): st.write(answer.message) else: with st.chat_message("user"): st.write(answer.message) credit_card_placeholder.caption(f""" Progress: {int(len(st.session_state.resume_history) / 50 * 100)}% completed.""")