Spaces:
Sleeping
Sleeping
| from typing import List, Dict, Any, Optional, Annotated | |
| from pydantic import BaseModel, Field | |
| from langchain_core.messages import BaseMessage | |
| from langgraph.graph import add_messages | |
| class ChatbotState(BaseModel): | |
| def get(self, key, default=None): | |
| """ | |
| Allow dict-like .get() access for compatibility. | |
| """ | |
| # First try attribute directly | |
| if hasattr(self, key): | |
| return getattr(self, key) | |
| # Fallback: check if it's in __dict__ | |
| return self.__dict__.get(key, default) | |
| def setdefault(self, key, default): | |
| """ | |
| Dict-like setdefault: if attribute is None, set it to default and return it. | |
| Otherwise, return existing value. | |
| """ | |
| if hasattr(self, key): | |
| value = getattr(self, key) | |
| if value is None: | |
| setattr(self, key, default) | |
| return default | |
| return value | |
| else: | |
| # attribute does not exist: set it | |
| setattr(self, key, default) | |
| return default | |
| profile: Dict[str, Any] = Field(..., description="Preprocessed / summarized profile data") | |
| profile_url: Optional[str] = Field( | |
| default=None, | |
| description="Original LinkedIn profile URL provided by the user." | |
| ) | |
| # Quick access sections (about, headline, skills etc.) | |
| sections: Dict[str, str] = Field(..., description="Flattened profile sections for quick access") | |
| # Enhancements and analysis results | |
| enhanced_content: Dict[str, str] = Field( | |
| default_factory=dict, | |
| description=( | |
| "Map of improved or rewritten profile sections generated by the ContentGenerator tool. " | |
| "Keys are section names (e.g., 'about', 'headline'); values are enhanced text." | |
| ) | |
| ) | |
| profile_analysis: Optional[Dict[str, Any]] = Field( | |
| None, | |
| description=( | |
| "Structured analysis of the user's profile produced by the ProfileAnalyzer tool, " | |
| "including strengths, weaknesses, and actionable suggestions." | |
| ) | |
| ) | |
| job_fit: Optional[Dict[str, Any]] = Field( | |
| None, | |
| description=( | |
| "Assessment result from the JobMatcher tool, detailing how well the user's profile matches " | |
| "the target role, including missing skills and match score." | |
| ) | |
| ) | |
| target_role: Optional[str] = Field( | |
| None, | |
| description=( | |
| "Target job role the user is aiming for. " | |
| "Can be set by the user directly during the conversation or inferred by the chatbot." | |
| ) | |
| ) | |
| editing_section: Optional[str] = Field( | |
| None, | |
| description=( | |
| "Name of the profile section currently being edited or improved, " | |
| "set dynamically when the ContentGenerator tool is invoked." | |
| ) | |
| ) | |
| next_tool_name: Optional[str] = Field( | |
| default=None, | |
| description="Name of the next tool the chatbot wants to call, set dynamically after LLM response." | |
| ) | |
| # Annotated chat history directly using BaseMessage | |
| messages: Annotated[List[BaseMessage], add_messages] = Field( | |
| default_factory=list, | |
| description="List of user and assistant messages" | |
| ) | |
| class ProfileAnalysisStrengths(BaseModel): | |
| technical: List[str] | |
| projects: List[str] | |
| education: List[str] | |
| soft_skills: List[str] | |
| class ProfileAnalysisWeaknesses(BaseModel): | |
| technical_gaps: List[str] | |
| project_or_experience_gaps: List[str] | |
| missing_context: List[str] | |
| class ProfileAnalysisModel(BaseModel): | |
| strengths: ProfileAnalysisStrengths | |
| weaknesses: ProfileAnalysisWeaknesses | |
| suggestions: List[str] | |
| class JobFitModel(BaseModel): | |
| match_score: int = Field(..., ge=0, le=100) | |
| missing_skills: List[str] | |
| suggestions: List[str] | |
| class ContentGenerationModel(BaseModel): | |
| new_content: str | |
| # ========== 6. MEMORY SETUP ========== | |
| class UserMemory: | |
| def __init__(self): | |
| self.profile = None | |
| self.target_roles = [] | |
| self.history = [] | |
| def save(self, key, value): | |
| self.history.append((key, value)) | |
| def get_history(self): | |
| return self.history | |