Spaces:
Sleeping
Sleeping
File size: 4,285 Bytes
5318b09 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
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
|