| import streamlit as st |
| from dotenv import load_dotenv |
| from langchain_google_genai import GoogleGenerativeAI |
| from langchain_core.prompts import PromptTemplate |
| from langchain_core.output_parsers import JsonOutputParser |
| from langchain_core.runnables import RunnableParallel |
|
|
| load_dotenv() |
|
|
| st.set_page_config(page_title="Job Application Intelligence", page_icon="π§ ", layout="centered") |
| st.title("π§ Job Application Intelligence System") |
| st.caption("Resume vs Job Description β Parallel AI Brain") |
|
|
| |
| llm = GoogleGenerativeAI(model="gemini-2.5-flash", temperature=0.2) |
|
|
| |
| match_prompt = PromptTemplate.from_template(""" |
| You are an ATS system. |
| Given Resume and Job Description, calculate skill match percentage (0-100). |
| Return ONLY JSON: |
| {{ |
| "match_percentage": number |
| }} |
| |
| Resume: |
| {resume} |
| |
| Job Description: |
| {jd} |
| """) |
|
|
| missing_prompt = PromptTemplate.from_template(""" |
| You are a recruiter. |
| Find missing skills from resume compared to job description. |
| Return ONLY JSON: |
| {{ |
| "missing_skills": [ "skill1", "skill2" ] |
| }} |
| |
| Resume: |
| {resume} |
| |
| Job Description: |
| {jd} |
| """) |
|
|
| improve_prompt = PromptTemplate.from_template(""" |
| You are a career coach. |
| Suggest improvements to the resume for this job. |
| Return ONLY JSON: |
| {{ |
| "improvement_suggestions": [ "point1", "point2" ] |
| }} |
| |
| Resume: |
| {resume} |
| |
| Job Description: |
| {jd} |
| """) |
|
|
| cover_prompt = PromptTemplate.from_template(""" |
| You are an HR professional. |
| Write a short 3-line professional cover note for this job. |
| Return ONLY JSON: |
| {{ |
| "cover_note": "3 lines cover note" |
| }} |
| |
| Resume: |
| {resume} |
| |
| Job Description: |
| {jd} |
| """) |
|
|
| parser = JsonOutputParser() |
|
|
| parallel_chain = RunnableParallel({ |
| "match": match_prompt | llm | parser, |
| "missing": missing_prompt | llm | parser, |
| "improve": improve_prompt | llm | parser, |
| "cover": cover_prompt | llm | parser, |
| }) |
|
|
| |
| resume_text = st.text_area("π Paste your Resume", height=180) |
| jd_text = st.text_area("π Paste Job Description", height=180) |
|
|
| if st.button("Analyze Resume vs JD π"): |
| if not resume_text.strip() or not jd_text.strip(): |
| st.warning("Please provide both Resume and Job Description.") |
| else: |
| with st.spinner("Analyzing with Parallel AI Brain..."): |
| result = parallel_chain.invoke({ |
| "resume": resume_text, |
| "jd": jd_text |
| }) |
|
|
| st.subheader("π Results") |
|
|
| st.metric("Match Percentage", f"{result['match']['match_percentage']}%") |
|
|
| st.markdown("### β Missing Skills") |
| st.write(result["missing"]["missing_skills"]) |
|
|
| st.markdown("### βοΈ Improvement Suggestions") |
| for i, point in enumerate(result["improve"]["improvement_suggestions"], 1): |
| st.write(f"{i}. {point}") |
|
|
| st.markdown("### π¨ Custom Cover Note") |
| st.info(result["cover"]["cover_note"]) |
|
|