| from crewai import Agent, Task | |
| def cv_parsing_task(cv_path: str, agent: Agent): | |
| return Task( | |
| description=f""" | |
| Read and extract all information from the CV located at: {cv_path} | |
| Extract: | |
| - Full name and contact info | |
| - All skills (technical and soft) | |
| - Work experience with roles, companies, durations | |
| - Projects with tech stacks used | |
| - Education | |
| - Certifications | |
| Return structured, detailed summary of the entire CV. | |
| """, | |
| expected_output="Structured summary of candidate's CV including skills, experience, projects, education.", | |
| agent=agent | |
| ) | |
| def jd_analysis_task(jd_source: str, agent: Agent): | |
| return Task( | |
| description=f""" | |
| Extract full job description details from: {jd_source} | |
| If it's a URL, scrape the page content. | |
| IMPORTANT: If the scraped content contains navigation menus, footers, "Sign in" prompts, | |
| "Similar jobs" sections, or other website UI noise, IGNORE all of that. | |
| Focus ONLY on the actual job description content. | |
| Extract: | |
| - Job title and seniority level | |
| - Required skills (must-have) | |
| - Nice-to-have skills | |
| - Key responsibilities | |
| - Years of experience required | |
| - Any specific tools, frameworks, or domain knowledge mentioned | |
| Return a structured breakdown of the job requirements. | |
| Keep your response concise β focus on the extracted requirements only. | |
| """, | |
| expected_output="Structured breakdown of job role, required skills, responsibilities, and experience needed.", | |
| agent=agent | |
| ) | |
| def company_research_task(company_name: str, city: str, agent: Agent): | |
| return Task( | |
| description=f""" | |
| Research the company: {company_name} located in {city}. | |
| Make sure results are specific to this company in {city}, not other companies with similar names. | |
| Find: | |
| - What the company does and their main products | |
| - Tech stack they use | |
| - Engineering culture and team size if available | |
| - Recent news, funding, or major launches | |
| - What kind of problems they are solving | |
| Return a concise but informative company profile. | |
| Keep response under 500 words to stay within token limits. | |
| """, | |
| expected_output="Company profile covering products, tech stack, culture, and recent activities.", | |
| agent=agent | |
| ) | |
| def gap_analysis_task(agent: Agent, cv_task: Task, jd_task: Task): | |
| return Task( | |
| description=""" | |
| Using the CV summary and JD breakdown from previous tasks: | |
| - List skills present in JD but missing from CV | |
| - Identify weak or surface-level mentions that need strengthening | |
| - Highlight experience gaps (years, domain, seniority) | |
| - Rate overall match as: Strong / Moderate / Weak with reasoning | |
| Be specific and honest β don't sugarcoat gaps. | |
| Formatting rules: use ## for section headers, - for bullet points. | |
| Do not use *** or excessive bold. Plain readable text only. | |
| """, | |
| expected_output="Detailed gap analysis with missing skills, weak areas, experience gaps, and overall match rating.", | |
| context=[cv_task, jd_task], | |
| agent=agent | |
| ) | |
| def cv_optimization_task(agent: Agent, cv_task: Task, jd_task: Task, gap_task: Task, company_task: Task): | |
| return Task( | |
| description=""" | |
| Using the gap analysis and company research from previous tasks: | |
| - Suggest exact keywords and skills to add to the CV | |
| - Recommend which existing bullet points to rewrite and how | |
| - Suggest ATS-friendly improvements | |
| - Prioritize suggestions by impact β what will catch recruiter eyes first | |
| - Tailor suggestions to the specific company's culture and tech stack | |
| Be specific β give exact phrases to add, not vague advice. | |
| Formatting rules: use ## for section headers, - for bullet points. | |
| Do not use *** or excessive bold. Plain readable text only. | |
| """, | |
| expected_output="Prioritized list of specific CV improvements, keywords to add, and bullet point rewrites.", | |
| context=[cv_task, jd_task, gap_task, company_task], | |
| agent=agent | |
| ) | |
| def outreach_writing_task(agent: Agent, cv_task: Task, jd_task: Task, gap_task: Task, company_task: Task): | |
| return Task( | |
| description=""" | |
| Using all previous context β CV, JD, company research, and gap analysis: | |
| Write a personalized cold outreach message to the hiring manager. | |
| - Keep it under 150 words | |
| - Open with something specific about the company (not generic) | |
| - Connect candidate's strongest relevant experience to the role | |
| - End with a clear, low-friction call to action | |
| - Tone: confident, professional, human β not salesy | |
| Write one LinkedIn message version and one email version. | |
| Formatting rules: use ## LinkedIn Message and ## Email as headers. | |
| Do not use *** or excessive bold. Plain readable text only. | |
| """, | |
| expected_output="Two outreach messages β LinkedIn DM (under 150 words) and email version with subject line.", | |
| context=[cv_task, jd_task, gap_task, company_task], | |
| agent=agent | |
| ) | |