File size: 7,941 Bytes
3822987
 
 
 
 
 
 
 
 
 
 
 
 
65a47c4
3822987
65a47c4
3822987
 
65a47c4
3822987
65a47c4
3822987
 
 
65a47c4
3822987
 
 
 
 
65a47c4
3822987
 
65a47c4
3822987
65a47c4
 
 
 
 
 
 
 
 
 
 
3822987
65a47c4
3822987
 
 
 
 
 
65a47c4
 
 
3822987
65a47c4
3822987
 
65a47c4
 
 
 
 
 
 
 
3822987
 
65a47c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3822987
 
65a47c4
 
 
 
3822987
65a47c4
 
 
 
3822987
 
 
 
65a47c4
 
3822987
65a47c4
3822987
65a47c4
 
 
 
 
 
 
 
 
 
 
 
 
3822987
65a47c4
 
 
3822987
65a47c4
3822987
 
 
65a47c4
3822987
65a47c4
3822987
65a47c4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3822987
 
65a47c4
3822987
 
 
 
65a47c4
 
 
 
 
 
 
3822987
 
 
 
 
65a47c4
3822987
 
65a47c4
 
 
8631f90
63fbb09
65a47c4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import pysqlite3
import sys
sys.modules["sqlite3"] = sys.modules.pop("pysqlite3")

import streamlit as st
from uuid import uuid4
from langchain_cohere import CohereEmbeddings
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_cohere import ChatCohere
import random

# Streamlit app
st.title("Resume Matcher")

# Sidebar for API key input and user details
with st.sidebar:
    with st.form(key="user_details_form", clear_on_submit=True):
        
        # Field for API key
        st.header("Cohere API Key")
        st.markdown("You can get your API key from [Cohere's website](https://dashboard.cohere.com/).")
        api_key = st.text_input("Enter your Cohere API Key", type="password")

        # Check if name and contact are already in session state
        if "name" not in st.session_state:
            st.session_state["name"] = ""
        if "contact" not in st.session_state:
            st.session_state["contact"] = ""

        # Generate or retrieve a unique user ID
        if "user_id" not in st.session_state:
            st.session_state["user_id"] = str(random.randint(1000000000, 9999999999))
        
        user_id = st.session_state["user_id"]
        
        st.header("Enter Your Details")
        name = st.text_input("Name", st.session_state["name"])
        contact = st.text_input("Contact - Email, Number, links, etc", st.session_state["contact"])
        skills = st.text_area("Skills - Technical, Soft, etc (one per line)", "")
        experience = st.text_area("Experience - Company Name, Duration, Role, Responsibilities etc (one per line)", "")
        education = st.text_area("Education - Degree Name, University Name, Duration etc (one per line)", "")
        project = st.text_area("Projects - Name, Features etc (one per line)", "")

        submit_button = st.form_submit_button(label="Save")
    
    if submit_button:
        if all([api_key, name, contact, skills, experience, education, project]):
            st.session_state["api_key"] = api_key
            st.session_state["name"] = name
            st.session_state["contact"] = contact
            st.session_state["skills"] = skills
            st.session_state["experience"] = experience
            st.session_state["education"] = education
            st.session_state["project"] = project
            st.session_state["saved"] = True
            st.success("Details saved successfully!")
        else:
            st.warning("Please fill out all fields.")

# Check if the user has saved the details
if st.session_state.get("saved", False):
    # Convert inputs to lists (split by new lines)
    skills_list = [s.strip() for s in st.session_state["skills"].splitlines() if s.strip()]
    experience_list = [e.strip() for e in st.session_state["experience"].splitlines() if e.strip()]
    education_list = [e.strip() for e in st.session_state["education"].splitlines() if e.strip()]
    project_list = [p.strip() for p in st.session_state["project"].splitlines() if p.strip()]

    # Initialize Cohere Embeddings
    embedding_model = CohereEmbeddings(cohere_api_key=st.session_state["api_key"], model="embed-english-light-v3.0")

    # Initialize Chroma vector store
    vector_store = Chroma(
        collection_name="user_data",
        embedding_function=embedding_model,
        persist_directory="chroma"
    )

    # Create documents for skills, experience, education, and projects
    skill_documents = [
        Document(
            page_content=skill,
            metadata={"user_id": user_id, "type": "skill"},
            id=str(uuid4())
        )
        for skill in skills_list
    ]

    experience_documents = [
        Document(
            page_content=exp,
            metadata={"user_id": user_id, "type": "experience"},
            id=str(uuid4())
        )
        for exp in experience_list
    ]

    education_documents = [
        Document(
            page_content=edu,
            metadata={"user_id": user_id, "type": "education"},
            id=str(uuid4())
        )
        for edu in education_list
    ]

    project_documents = [
        Document(
            page_content=proj,
            metadata={"user_id": user_id, "type": "project"},
            id=str(uuid4())
        )
        for proj in project_list
    ]

    # Add documents to the vector store
    vector_store.add_documents(documents=skill_documents)
    vector_store.add_documents(documents=experience_documents)
    vector_store.add_documents(documents=education_documents)
    vector_store.add_documents(documents=project_documents)

    # Main app layout for job description and resume generation
    job_description = st.text_area("Job Description", "")

    if st.button("Generate Resume"):
        def remove_duplicates(results):
            seen = set()
            unique_results = []
            for result in results:
                content = result.page_content
                if content not in seen:
                    unique_results.append(result)
                    seen.add(content)
            return unique_results
        
        # Retrieve relevant information
        relevant_skills = vector_store.similarity_search_by_vector(
            embedding=embedding_model.embed_query(job_description), k=10, filter={"type": "skill"}
        )

        relevant_experience = vector_store.similarity_search_by_vector(
            embedding=embedding_model.embed_query(job_description), k=4, filter={"type": "experience"}
        )
        
        relevant_education = vector_store.similarity_search_by_vector(
            embedding=embedding_model.embed_query(job_description), k=4, filter={"type": "education"}
        )

        relevant_project = vector_store.similarity_search_by_vector(
            embedding=embedding_model.embed_query(job_description), k=4, filter={"type": "project"}
        )

        # Format the relevant information
        skills_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_skills)])
        experience_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_experience)])
        education_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_education)])
        project_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_project)])

        # Create a system prompt to generate a resume
        system_prompt = f"""
        Generate a resume with the following details:

        Guidelines:
        Be specific and use active voice.
        Avoid errors, passive language, and personal pronouns.
        Ensure consistency and readability.

        Avoid:
        Spelling/grammar errors, missing contact info, poor organization.

        Action Verbs Examples:
        Leadership: Led, Managed
        Communication: Presented, Promoted
        Technical: Engineered, Programmed
        Organizational: Organized, Implemented

        Details:
        Job Description: {job_description}
        Name: {st.session_state['name']}
        Contact: {st.session_state['contact']}
        Projects: {project_content}
        Skills: {skills_content}
        Experience: {experience_content}
        Education: {education_content}

        Formatting:
        Start with name and contact.
        List experience, education, projects and skills in order.
        Use headings and bullet points.

        Instruction:
        Do not add any extra text or headings from yourself; use only the provided details.
        """

        # Initialize ChatCohere
        chat_model = ChatCohere(cohere_api_key=st.session_state["api_key"])

        # Generate the resume
        resume_output = chat_model.invoke(input=system_prompt)

        # Display the generated resume
        st.subheader("Generated Resume")
        st.write(resume_output.content)

else:
    st.info("Please fill out your details in the sidebar and click Save to proceed.")