Spaces:
Runtime error
Runtime error
| # 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 | |
| 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.""") | |