Spaces:
Sleeping
Sleeping
Update src/app.py
Browse files- src/app.py +81 -75
src/app.py
CHANGED
|
@@ -216,118 +216,124 @@ class ImprovedChatMemory:
|
|
| 216 |
|
| 217 |
class ImprovedCPUChatbot:
|
| 218 |
def __init__(self):
|
| 219 |
-
self.model_name = "distilgpt2"
|
| 220 |
-
self.model = None
|
| 221 |
-
self.tokenizer = None
|
| 222 |
-
self.pipeline = None
|
| 223 |
self.nlp_processor = ImprovedNLPProcessor()
|
| 224 |
self.memory = ImprovedChatMemory()
|
| 225 |
self.is_loaded = False
|
| 226 |
|
|
|
|
| 227 |
self.template_responses = {
|
| 228 |
'experience': "To improve your experience section: Use bullet points with action verbs, quantify achievements with numbers, focus on results rather than duties, and tailor content to match job requirements.",
|
| 229 |
'ats': "Make your resume ATS-friendly by: Using standard section headings, including relevant keywords naturally, avoiding images and complex formatting, using common fonts like Arial, and saving as PDF.",
|
| 230 |
'skills': "Enhance your skills section by: Organizing technical and soft skills separately, matching skills to job descriptions, providing proficiency levels, and including both hard and soft skills relevant to your target role.",
|
| 231 |
'keywords': "Add relevant keywords by: Studying job descriptions in your field, using industry-specific terms, including both acronyms and full terms, and incorporating them naturally throughout your resume.",
|
| 232 |
-
'format': "Improve resume formatting with: Clear section headings, consistent bullet points, readable fonts, appropriate white space, and a clean, professional layout that's easy to scan."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
}
|
| 234 |
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
"""Load the model with better configuration"""
|
| 238 |
try:
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
_self.model_name,
|
| 245 |
-
torch_dtype=torch.float32,
|
| 246 |
-
low_cpu_mem_usage=True
|
| 247 |
-
)
|
| 248 |
-
|
| 249 |
-
text_generator = pipeline(
|
| 250 |
-
"text-generation",
|
| 251 |
-
model=model,
|
| 252 |
-
tokenizer=tokenizer,
|
| 253 |
-
device=-1,
|
| 254 |
-
max_new_tokens=50,
|
| 255 |
-
do_sample=True,
|
| 256 |
-
temperature=0.8,
|
| 257 |
-
top_p=0.85,
|
| 258 |
-
top_k=50,
|
| 259 |
-
repetition_penalty=1.2,
|
| 260 |
-
pad_token_id=tokenizer.eos_token_id,
|
| 261 |
-
no_repeat_ngram_size=3
|
| 262 |
-
)
|
| 263 |
-
|
| 264 |
-
return model, tokenizer, text_generator
|
| 265 |
except Exception as e:
|
| 266 |
-
st.error(f"Failed to
|
| 267 |
-
return
|
| 268 |
-
|
| 269 |
-
def initialize(self):
|
| 270 |
-
"""Initialize the chatbot"""
|
| 271 |
-
if not self.is_loaded:
|
| 272 |
-
result = self.load_model()
|
| 273 |
-
if result[0] is not None:
|
| 274 |
-
self.model, self.tokenizer, self.pipeline = result
|
| 275 |
-
self.is_loaded = True
|
| 276 |
-
return True
|
| 277 |
-
else:
|
| 278 |
-
return False
|
| 279 |
-
return True
|
| 280 |
|
| 281 |
def get_template_response(self, user_input: str) -> str:
|
| 282 |
-
"""
|
| 283 |
user_lower = user_input.lower()
|
| 284 |
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
return "To improve your resume for HR success: Use a clear, professional format with standard headings. Tailor your content to match job descriptions. Quantify achievements with numbers. Include relevant keywords naturally. Keep it to 1-2 pages. Use bullet points with action verbs. Proofread carefully for errors."
|
| 297 |
-
|
| 298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
|
| 300 |
return None
|
| 301 |
|
| 302 |
def generate_response(self, user_input: str, resume_context: str = "") -> str:
|
| 303 |
-
"""Generate response
|
| 304 |
if not self.is_loaded:
|
| 305 |
-
return "Please initialize the AI
|
| 306 |
|
|
|
|
| 307 |
template_response = self.get_template_response(user_input)
|
| 308 |
if template_response:
|
| 309 |
self.memory.add_conversation(user_input, template_response)
|
| 310 |
return template_response
|
| 311 |
|
| 312 |
-
|
| 313 |
-
self.
|
| 314 |
-
|
|
|
|
| 315 |
|
| 316 |
-
def
|
| 317 |
-
"""Provide
|
| 318 |
user_lower = user_input.lower()
|
| 319 |
|
| 320 |
-
|
| 321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 322 |
|
| 323 |
-
|
| 324 |
-
|
|
|
|
| 325 |
|
| 326 |
elif any(phrase in user_lower for phrase in ['job', 'career', 'position', 'role', 'work']):
|
| 327 |
-
return """For job
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
else:
|
| 330 |
-
return """Key resume
|
| 331 |
|
| 332 |
@st.cache_resource
|
| 333 |
def download_nltk_data():
|
|
|
|
| 216 |
|
| 217 |
class ImprovedCPUChatbot:
|
| 218 |
def __init__(self):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
self.nlp_processor = ImprovedNLPProcessor()
|
| 220 |
self.memory = ImprovedChatMemory()
|
| 221 |
self.is_loaded = False
|
| 222 |
|
| 223 |
+
# Comprehensive template responses for better coverage
|
| 224 |
self.template_responses = {
|
| 225 |
'experience': "To improve your experience section: Use bullet points with action verbs, quantify achievements with numbers, focus on results rather than duties, and tailor content to match job requirements.",
|
| 226 |
'ats': "Make your resume ATS-friendly by: Using standard section headings, including relevant keywords naturally, avoiding images and complex formatting, using common fonts like Arial, and saving as PDF.",
|
| 227 |
'skills': "Enhance your skills section by: Organizing technical and soft skills separately, matching skills to job descriptions, providing proficiency levels, and including both hard and soft skills relevant to your target role.",
|
| 228 |
'keywords': "Add relevant keywords by: Studying job descriptions in your field, using industry-specific terms, including both acronyms and full terms, and incorporating them naturally throughout your resume.",
|
| 229 |
+
'format': "Improve resume formatting with: Clear section headings, consistent bullet points, readable fonts, appropriate white space, and a clean, professional layout that's easy to scan.",
|
| 230 |
+
'summary': "Write an effective summary by: Starting with your professional title, highlighting 2-3 key achievements, mentioning relevant skills, and keeping it to 3-4 lines maximum.",
|
| 231 |
+
'education': "Optimize your education section by: Listing degree, institution, and graduation year, including relevant coursework for entry-level positions, mentioning GPA if above 3.5, and adding academic achievements.",
|
| 232 |
+
'projects': "Showcase projects effectively by: Describing the problem solved, technologies used, your specific role, quantifiable results or impact, and linking to live demos or repositories when possible.",
|
| 233 |
+
'cover_letter': "Create compelling cover letters by: Addressing specific job requirements, showing knowledge of the company, highlighting relevant achievements, and ending with a strong call to action.",
|
| 234 |
+
'interview': "Prepare for interviews by: Researching the company and role, practicing STAR method responses, preparing questions to ask, and reviewing your resume thoroughly to discuss any point confidently."
|
| 235 |
}
|
| 236 |
|
| 237 |
+
def initialize(self):
|
| 238 |
+
"""Initialize the chatbot - lightweight version without model loading"""
|
|
|
|
| 239 |
try:
|
| 240 |
+
# Simulate brief initialization
|
| 241 |
+
import time
|
| 242 |
+
time.sleep(0.5) # Brief delay to show initialization
|
| 243 |
+
self.is_loaded = True
|
| 244 |
+
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
except Exception as e:
|
| 246 |
+
st.error(f"Failed to initialize: {str(e)}")
|
| 247 |
+
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
|
| 249 |
def get_template_response(self, user_input: str) -> str:
|
| 250 |
+
"""Enhanced template response matching"""
|
| 251 |
user_lower = user_input.lower()
|
| 252 |
|
| 253 |
+
# More comprehensive keyword matching
|
| 254 |
+
response_mapping = [
|
| 255 |
+
(['experience', 'work history', 'job history', 'employment', 'career'], 'experience'),
|
| 256 |
+
(['ats', 'applicant tracking', 'ats-friendly', 'system'], 'ats'),
|
| 257 |
+
(['skills', 'technical skills', 'abilities', 'competencies'], 'skills'),
|
| 258 |
+
(['keywords', 'keyword', 'terms', 'buzzwords'], 'keywords'),
|
| 259 |
+
(['format', 'formatting', 'layout', 'design', 'structure'], 'format'),
|
| 260 |
+
(['summary', 'objective', 'profile', 'about', 'intro'], 'summary'),
|
| 261 |
+
(['education', 'degree', 'university', 'college', 'school'], 'education'),
|
| 262 |
+
(['projects', 'portfolio', 'work samples', 'personal projects'], 'projects'),
|
| 263 |
+
(['cover letter', 'covering letter', 'application letter'], 'cover_letter'),
|
| 264 |
+
(['interview', 'interviews', 'interviewing', 'job interview'], 'interview')
|
| 265 |
+
]
|
| 266 |
+
|
| 267 |
+
for keywords, response_key in response_mapping:
|
| 268 |
+
if any(keyword in user_lower for keyword in keywords):
|
| 269 |
+
return self.template_responses[response_key]
|
| 270 |
+
|
| 271 |
+
# General improvement queries
|
| 272 |
+
if any(phrase in user_lower for phrase in ['improve my resume', 'better resume', 'hire me', 'get hired', 'land job']):
|
| 273 |
return "To improve your resume for HR success: Use a clear, professional format with standard headings. Tailor your content to match job descriptions. Quantify achievements with numbers. Include relevant keywords naturally. Keep it to 1-2 pages. Use bullet points with action verbs. Proofread carefully for errors."
|
| 274 |
+
|
| 275 |
+
if any(phrase in user_lower for phrase in ['hr', 'hiring manager', 'recruiter', 'employer']):
|
| 276 |
+
return "To appeal to HR professionals: Use standard section headings they recognize. Include relevant keywords for ATS systems. Show clear career progression. Make it scannable with bullet points. Demonstrate measurable value and impact you can bring to their organization."
|
| 277 |
+
|
| 278 |
+
if any(word in user_lower for word in ['help', 'advice', 'tips', 'suggestions']):
|
| 279 |
+
return "Key resume best practices: Customize for each job application. Use metrics to show impact. Include both technical and soft skills. Write compelling summaries. Use reverse chronological order. Keep formatting clean and professional. Focus on achievements, not just duties."
|
| 280 |
|
| 281 |
return None
|
| 282 |
|
| 283 |
def generate_response(self, user_input: str, resume_context: str = "") -> str:
|
| 284 |
+
"""Generate response using templates and contextual advice"""
|
| 285 |
if not self.is_loaded:
|
| 286 |
+
return "Please initialize the AI assistant first by clicking 'Initialize AI'."
|
| 287 |
|
| 288 |
+
# Try template response first
|
| 289 |
template_response = self.get_template_response(user_input)
|
| 290 |
if template_response:
|
| 291 |
self.memory.add_conversation(user_input, template_response)
|
| 292 |
return template_response
|
| 293 |
|
| 294 |
+
# If no template match, provide contextual advice
|
| 295 |
+
contextual_response = self.get_contextual_advice(user_input, resume_context)
|
| 296 |
+
self.memory.add_conversation(user_input, contextual_response)
|
| 297 |
+
return contextual_response
|
| 298 |
|
| 299 |
+
def get_contextual_advice(self, user_input: str, resume_context: str) -> str:
|
| 300 |
+
"""Provide advice based on resume context and user input"""
|
| 301 |
user_lower = user_input.lower()
|
| 302 |
|
| 303 |
+
# Analyze resume context if available
|
| 304 |
+
if resume_context:
|
| 305 |
+
word_count = len(resume_context.split())
|
| 306 |
+
has_contact = '@' in resume_context or any(char.isdigit() for char in resume_context[:200])
|
| 307 |
+
has_bullets = any(marker in resume_context for marker in ['•', '*', '-', '→'])
|
| 308 |
+
|
| 309 |
+
context_advice = []
|
| 310 |
+
|
| 311 |
+
if word_count < 200:
|
| 312 |
+
context_advice.append("Your resume appears brief - consider expanding with more detailed achievements and responsibilities.")
|
| 313 |
+
elif word_count > 800:
|
| 314 |
+
context_advice.append("Your resume might be too lengthy - focus on the most relevant and impactful information.")
|
| 315 |
+
|
| 316 |
+
if not has_contact:
|
| 317 |
+
context_advice.append("Ensure your contact information (email and phone) is clearly visible at the top.")
|
| 318 |
+
|
| 319 |
+
if not has_bullets:
|
| 320 |
+
context_advice.append("Use bullet points to improve readability and make your achievements easier to scan.")
|
| 321 |
+
|
| 322 |
+
if context_advice:
|
| 323 |
+
return "Based on your resume: " + " ".join(context_advice)
|
| 324 |
|
| 325 |
+
# Default comprehensive advice based on query type
|
| 326 |
+
if any(phrase in user_lower for phrase in ['improve', 'better', 'enhance', 'optimize']):
|
| 327 |
+
return """To improve your resume effectiveness: 1) Tailor content to match specific job descriptions. 2) Use quantifiable achievements with numbers and percentages. 3) Start bullet points with strong action verbs like 'Led', 'Implemented', 'Increased'. 4) Keep it concise but comprehensive (1-2 pages). 5) Use clean, professional formatting with consistent styling. 6) Include both technical and soft skills relevant to your field. 7) Proofread thoroughly for grammar and spelling errors."""
|
| 328 |
|
| 329 |
elif any(phrase in user_lower for phrase in ['job', 'career', 'position', 'role', 'work']):
|
| 330 |
+
return """For successful job applications: 1) Research each company and role thoroughly. 2) Customize your resume for every application. 3) Highlight experiences most relevant to the specific position. 4) Use industry-specific terminology and keywords. 5) Show clear alignment between your background and their requirements. 6) Demonstrate both technical competencies and interpersonal skills. 7) Follow up professionally after applications."""
|
| 331 |
+
|
| 332 |
+
elif any(word in user_lower for word in ['why', 'what', 'how', 'when', 'where']):
|
| 333 |
+
return """Resume fundamentals: Focus on achievements over duties, use specific numbers when possible, maintain consistent formatting, tailor content for each application, include relevant keywords naturally, keep information current and accurate, and ensure easy readability with clear section headings."""
|
| 334 |
|
| 335 |
else:
|
| 336 |
+
return """Key resume principles: Use professional formatting with clear headings. Lead with your strongest qualifications. Include relevant keywords naturally throughout. Quantify achievements with specific metrics. Keep descriptions concise but impactful. Ensure error-free writing and consistent style. Focus on the value you can bring to potential employers."""
|
| 337 |
|
| 338 |
@st.cache_resource
|
| 339 |
def download_nltk_data():
|