Spaces:
Sleeping
Sleeping
""" | |
Career Agent - Intelligent CV and Cover Letter Generator | |
======================================================== | |
An AI agent that autonomously analyzes job postings and candidate profiles | |
to create tailored application documents using multi-step reasoning. | |
Author: Career Agent Team | |
Version: 1.1 - SambaNova Edition | |
""" | |
import os | |
import logging | |
import gradio as gr | |
from typing import Optional, Dict, Any | |
from dotenv import load_dotenv | |
from openai import OpenAI | |
# Configure logging | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
# Load environment variables | |
load_dotenv() | |
# === SambaNova API Integration === | |
class SambaNovaClient: | |
"""SambaNova client using OpenAI SDK.""" | |
def __init__(self, api_key: str, model_name: str = "Meta-Llama-3.3-70B-Instruct"): | |
self.client = OpenAI( | |
api_key=api_key, | |
base_url="https://api.sambanova.ai/v1" | |
) | |
self.model_name = model_name | |
def generate(self, prompt: str, system_prompt: str = "You are a helpful assistant.") -> str: | |
"""Generate response using SambaNova API.""" | |
try: | |
response = self.client.chat.completions.create( | |
model=self.model_name, | |
messages=[ | |
{"role": "system", "content": system_prompt}, | |
{"role": "user", "content": prompt} | |
], | |
temperature=0.1, | |
top_p=0.1, | |
max_tokens=3000 | |
) | |
return response.choices[0].message.content or "" | |
except Exception as e: | |
logger.error(f"SambaNova API call failed: {e}") | |
return f"β API Error: {str(e)}" | |
# === Analysis Functions === | |
def analyze_candidate_profile(client: SambaNovaClient, user_info: str) -> str: | |
"""Analyzes the candidate's profile to extract insights and positioning.""" | |
system_prompt = "You are a senior career strategist with expertise in talent assessment and professional positioning." | |
prompt = f""" | |
Analyze this candidate profile in detail: | |
{user_info} | |
Provide a comprehensive analysis including: | |
- Experience level and career stage assessment | |
- Core competencies and unique value propositions | |
- Industry expertise and domain knowledge | |
- Leadership capabilities and soft skills evidence | |
- Career trajectory and growth potential | |
- Strategic positioning opportunities | |
- Areas of competitive advantage | |
Format your response as a structured professional assessment with clear sections. | |
""" | |
return client.generate(prompt, system_prompt) | |
def research_job_posting(client: SambaNovaClient, job_description: str) -> str: | |
"""Analyzes the job posting for strategic application guidance.""" | |
system_prompt = "You are an expert recruiter and talent acquisition specialist with deep knowledge of job market trends." | |
prompt = f""" | |
Conduct a comprehensive analysis of this job posting: | |
{job_description} | |
Extract and analyze: | |
- Must-have vs nice-to-have qualifications | |
- Technical skills and experience requirements breakdown | |
- Company culture indicators and values alignment | |
- Key responsibilities and success metrics | |
- Career growth and advancement signals | |
- Compensation and benefits analysis | |
- Critical ATS keywords and industry terminology | |
- Hiring urgency and competition level indicators | |
- Decision-maker priorities and pain points | |
Provide strategic intelligence for optimal application positioning. | |
""" | |
return client.generate(prompt, system_prompt) | |
def assess_fit_and_strategy(client: SambaNovaClient, profile_analysis: str, job_research: str) -> str: | |
"""Evaluates fit between candidate and job, develops application strategy.""" | |
system_prompt = "You are a strategic career consultant specializing in job application optimization and candidate positioning." | |
prompt = f""" | |
Based on the candidate analysis and job research below, develop a comprehensive application strategy: | |
CANDIDATE ANALYSIS: | |
{profile_analysis} | |
JOB INTELLIGENCE: | |
{job_research} | |
Provide detailed strategic assessment: | |
- Overall fit percentage with detailed justification | |
- Top 5 strongest selling points to emphasize | |
- Potential concerns and mitigation strategies | |
- Unique value proposition development | |
- Competitive differentiation approach | |
- Key messaging themes and positioning | |
- Recommended application tone and style | |
- Interview preparation insights | |
""" | |
return client.generate(prompt, system_prompt) | |
def generate_strategic_resume(client: SambaNovaClient, candidate_info: str, strategy: str) -> str: | |
"""Generates a tailored, ATS-optimized resume.""" | |
system_prompt = "You are a professional resume writer and ATS optimization expert with extensive experience in creating winning resumes." | |
prompt = f""" | |
Create a professional, ATS-optimized resume based on: | |
CANDIDATE INFORMATION: | |
{candidate_info} | |
STRATEGIC GUIDANCE: | |
{strategy} | |
Generate a complete resume with: | |
- Compelling professional summary (3-4 lines) | |
- Core competencies/skills section optimized for ATS | |
- Professional experience with quantified achievements | |
- Education and certifications | |
- Additional relevant sections (projects, awards, etc.) | |
Format professionally with clear sections and bullet points. | |
Focus on impact, metrics, and value delivery. | |
""" | |
return client.generate(prompt, system_prompt) | |
def create_cover_letter(client: SambaNovaClient, candidate_info: str, strategy: str, job_description: str) -> str: | |
"""Generates a persuasive, personalized cover letter.""" | |
system_prompt = "You are an expert cover letter writer specializing in compelling, personalized application letters that get results." | |
prompt = f""" | |
Write a persuasive cover letter based on: | |
CANDIDATE INFORMATION: | |
{candidate_info} | |
STRATEGIC POSITIONING: | |
{strategy} | |
JOB DESCRIPTION: | |
{job_description} | |
Create an engaging cover letter that: | |
- Opens with a compelling hook that grabs attention | |
- Demonstrates specific research about the company/role | |
- Connects candidate experience to concrete value delivery | |
- Shows cultural fit and genuine enthusiasm | |
- Addresses potential concerns proactively | |
- Closes with a confident, action-oriented call-to-action | |
Keep it concise (3-4 paragraphs) but impactful. | |
""" | |
return client.generate(prompt, system_prompt) | |
def quality_assurance_check(client: SambaNovaClient, resume: str, cover_letter: str, job_posting: str) -> str: | |
"""Performs quality review of generated documents.""" | |
system_prompt = "You are a senior HR professional and application reviewer with expertise in document quality assessment." | |
prompt = f""" | |
Perform a comprehensive quality review of these application materials: | |
RESUME: | |
{resume} | |
COVER LETTER: | |
{cover_letter} | |
ORIGINAL JOB POSTING: | |
{job_posting} | |
Evaluate and provide feedback on: | |
- ATS optimization and keyword alignment (score /10) | |
- Document consistency and professional presentation (score /10) | |
- Value proposition clarity and impact (score /10) | |
- Competitive differentiation strength (score /10) | |
- Overall application effectiveness (score /10) | |
Provide specific improvement recommendations and an overall quality assessment. | |
""" | |
return client.generate(prompt, system_prompt) | |
# === Main Career Agent Class === | |
class CareerAgent: | |
"""Main Career Agent class handling AI-powered document generation.""" | |
def __init__(self): | |
self.client = self._initialize_client() | |
def _initialize_client(self) -> SambaNovaClient: | |
"""Initialize SambaNova client.""" | |
api_key = os.getenv("SAMBANOVA_API_KEY") | |
if not api_key: | |
raise ValueError("SAMBANOVA_API_KEY environment variable is required.") | |
return SambaNovaClient(api_key=api_key) | |
def process_application(self, user_info: str, job_description: str) -> str: | |
"""Process the complete application with step-by-step analysis.""" | |
if not user_info.strip() or not job_description.strip(): | |
return "β Please provide both your profile and the job description." | |
try: | |
logger.info("π Step 1: Analyzing candidate profile...") | |
profile_analysis = analyze_candidate_profile(self.client, user_info) | |
logger.info("π Step 2: Researching job requirements...") | |
job_research = research_job_posting(self.client, job_description) | |
logger.info("π― Step 3: Assessing fit and developing strategy...") | |
strategy = assess_fit_and_strategy(self.client, profile_analysis, job_research) | |
logger.info("π Step 4: Generating tailored resume...") | |
resume = generate_strategic_resume(self.client, user_info, strategy) | |
logger.info("βοΈ Step 5: Creating personalized cover letter...") | |
cover_letter = create_cover_letter(self.client, user_info, strategy, job_description) | |
logger.info("β Step 6: Performing quality assurance...") | |
qa_review = quality_assurance_check(self.client, resume, cover_letter, job_description) | |
# Format final output | |
result = f""" | |
=== π TAILORED RESUME === | |
{resume} | |
=== βοΈ PERSONALIZED COVER LETTER === | |
{cover_letter} | |
=== π― STRATEGIC ANALYSIS === | |
{strategy} | |
=== β QUALITY ASSURANCE REVIEW === | |
{qa_review} | |
--- | |
Generated by SambaNova Llama 3.3 70B Instruct | |
""" | |
logger.info("β Application processing completed successfully!") | |
return result.strip() | |
except Exception as e: | |
logger.error(f"Processing error: {e}") | |
return f"""β SambaNova API Error: {str(e)} | |
π§ Troubleshooting: | |
- Verify your SAMBANOVA_API_KEY is valid | |
- Check your internet connection | |
- Ensure you have sufficient API credits | |
- Try again in a few moments | |
If the problem persists, please check your API key configuration.""" | |
# === Enhanced Gradio Interface === | |
class CareerAgentInterface: | |
def __init__(self, agent: CareerAgent): | |
self.agent = agent | |
def create_interface(self) -> gr.Blocks: | |
"""Create enhanced side-by-side interface.""" | |
with gr.Blocks(title="π― Intelligent Career Agent (SambaNova)", css=self._css()) as demo: | |
# Header | |
gr.Markdown(""" | |
# π― Intelligent Career Agent | |
### Powered by SambaNova's Llama 3.3 70B Instruct | |
Generate tailored resumes and cover letters using cutting-edge AI technology. | |
""") | |
# Status indicator | |
status = gr.Markdown("β **Ready** - Llama 3.3 70B Model Loaded", elem_classes="status-ready") | |
# Main layout - side by side | |
with gr.Row(equal_height=True): | |
# Left column - Inputs | |
with gr.Column(scale=1): | |
gr.Markdown("## π Input Information") | |
self.user_info = gr.Textbox( | |
label="π€ Your Professional Profile", | |
placeholder="""Example: | |
β’ Software Engineer with 5+ years experience | |
β’ Expert in Python, React, AWS | |
β’ Led team of 8 developers at TechCorp | |
β’ MBA in Technology Management | |
β’ Passionate about AI and machine learning | |
Paste your complete background here...""", | |
lines=12, | |
max_lines=15 | |
) | |
self.job_description = gr.Textbox( | |
label="π Target Job Description", | |
placeholder="""Paste the complete job posting here: | |
- Job title and company | |
- Requirements and qualifications | |
- Responsibilities | |
- Company culture info | |
- Any other relevant details...""", | |
lines=8, | |
max_lines=12 | |
) | |
# Control buttons | |
with gr.Row(): | |
self.generate_btn = gr.Button( | |
"π Generate Application", | |
variant="primary", | |
size="lg" | |
) | |
self.clear_btn = gr.Button( | |
"ποΈ Clear All", | |
variant="secondary" | |
) | |
# Right column - Output | |
with gr.Column(scale=1): | |
gr.Markdown("## π Generated Documents") | |
self.output = gr.Textbox( | |
label="π― Your Tailored Application Materials", | |
placeholder="Click 'Generate Application' to create your personalized resume and cover letter...", | |
lines=25, | |
max_lines=30, | |
show_copy_button=True, | |
interactive=False | |
) | |
# Progress and tips | |
gr.Markdown(""" | |
### π‘ Tips for Best Results: | |
- **Be specific** about your achievements with numbers/metrics | |
- **Include keywords** from your target industry | |
- **Paste the complete** job description for better matching | |
- **Review the output** and customize as needed | |
### π Processing Steps: | |
1. **Profile Analysis** - Understanding your background | |
2. **Job Research** - Decoding employer requirements | |
3. **Strategy Development** - Optimizing your positioning | |
4. **Resume Generation** - Creating tailored content | |
5. **Cover Letter Writing** - Personalizing your pitch | |
6. **Quality Assurance** - Ensuring excellence | |
""") | |
# Event handlers | |
def process_with_status(user_info, job_desc): | |
try: | |
result = self.agent.process_application(user_info, job_desc) | |
return result, "β **Complete** - Your application materials are ready!" | |
except Exception as e: | |
return f"β Error: {str(e)}", "β **Error** - Please check your API key and try again" | |
self.generate_btn.click( | |
fn=lambda: "π **Generating...** SambaNova Llama 3.3 70B is processing your request", | |
outputs=status | |
).then( | |
fn=process_with_status, | |
inputs=[self.user_info, self.job_description], | |
outputs=[self.output, status] | |
) | |
self.clear_btn.click( | |
fn=lambda: ("", "", "Click 'Generate Application' to create your personalized resume and cover letter...", "β **Ready** - Llama 3.3 70B Model Loaded"), | |
outputs=[self.user_info, self.job_description, self.output, status] | |
) | |
return demo | |
def _css(self) -> str: | |
"""Enhanced CSS for better visual design.""" | |
return """ | |
.gradio-container { | |
max-width: 1400px !important; | |
margin: auto; | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
} | |
.status-ready { | |
background: linear-gradient(90deg, #10b981, #059669); | |
color: white; | |
padding: 10px; | |
border-radius: 8px; | |
text-align: center; | |
margin: 10px 0; | |
} | |
/* Button styling */ | |
.btn-primary { | |
background: linear-gradient(90deg, #3b82f6, #1d4ed8) !important; | |
border: none !important; | |
color: white !important; | |
font-weight: bold !important; | |
} | |
.btn-primary:hover { | |
background: linear-gradient(90deg, #1d4ed8, #1e40af) !important; | |
} | |
/* Enhanced textbox styling */ | |
.textbox textarea { | |
border-radius: 8px !important; | |
border: 2px solid #e5e7eb !important; | |
} | |
.textbox textarea:focus { | |
border-color: #3b82f6 !important; | |
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important; | |
} | |
/* Column gap */ | |
.flex.gap-4 > div { | |
gap: 1.5rem; | |
} | |
""" | |
# === Entry Point === | |
def main(): | |
"""Main entry point with enhanced error handling.""" | |
try: | |
print("π Initializing Career Agent with SambaNova...") | |
# Check for API key | |
if not os.getenv("SAMBANOVA_API_KEY"): | |
print("β Error: SAMBANOVA_API_KEY environment variable not found!") | |
print("Please set your SambaNova API key:") | |
print("export SAMBANOVA_API_KEY='your-api-key-here'") | |
return | |
career_agent = CareerAgent() | |
print("β SambaNova Llama 3.3 70B initialized successfully!") | |
interface = CareerAgentInterface(career_agent) | |
demo = interface.create_interface() | |
print("π Launching Gradio interface...") | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False, | |
show_error=True | |
) | |
except Exception as e: | |
logger.error(f"Startup error: {e}") | |
print(f"β Startup Error: {str(e)}") | |
print("\nTroubleshooting:") | |
print("1. Check your SAMBANOVA_API_KEY is valid") | |
print("2. Ensure you have internet connection") | |
print("3. Verify all dependencies are installed: pip install openai gradio python-dotenv") | |
if __name__ == "__main__": | |
main() |