o
    qzph"                    @   s&  d dl Z d dlZd dlmZmZmZmZ d dlmZ d dl	m
Z
 d dlZd dlmZ d dlmZ d dlmZ d dlmZ ejejd	 eeZeG d
d dZeG dd dZeG dd dZeG dd dZeG dd dZeG dd dZeG dd dZeG dd dZeG dd dZ eG dd dZ!G dd dZ"G d d! d!Z#G d"d# d#Z$G d$d% d%Z%G d&d' d'Z&dfd)e'd*e&fd+d,Z(d-e&d.e'd/ee d*efd0d1Z)d-e&d2e'd3e'd4e'd5ee d6ee d7ee d*efd8d9Z*e&Z+e(Z,e*Z-ed:kre( Z.e/d; e/d< e/d; e*e.d=d>d?d@dAdBdCdDdEdFdGdHdDgdIdJdKdLdMdKdNdOdKgdPdQdRdSg dTdUgZ0e/dV e/e0dW ddX dY  e*e.dZd>d?d@dAdBdCdDgdIdJdKdLd[dKdNd\dKgd]d^d_d`dadbgdUgZ1e/dc e/e1dW ddX dY  e/dd e/de e/d; dS dS )g    N)DictListOptionalTuple)	dataclass)SequenceMatcher)datetime)
ChatOllama)PromptTemplate)HumanMessage)levelc                   @   s   e Zd ZU eed< eed< dS )
DepartmentidnameN__name__
__module____qualname__int__annotations__str r   r   @/var/www/eduai.edurigo.com/doc_train/edurigo_ai/Puru/tna_core.pyr         
 r   c                   @   s"   e Zd ZU eed< ee ed< dS )
TNARequestuser_promptorganization_departmentsN)r   r   r   r   r   r   r   r   r   r   r   r      s   
 r   c                   @   s6   e Zd ZU eed< eed< eed< eed< eed< dS )TNAResponsedepartment_iddepartment_nameinferred_departmentsimilarity_scorematchedN)r   r   r   r   r   r   floatboolr   r   r   r   r       s   
 r   c                   @   s>   e Zd ZU eed< eed< dZee ed< dZee ed< dS )Skillskill_id
skill_nameNskill_levelskill_count)	r   r   r   r   r   r   r(   r   r)   r   r   r   r   r%   (   s
   
 r%   c                   @   s>   e Zd ZU eed< eed< eed< eed< eed< eed< dS )SkillRecommendationr&   r'   r(   prioritysourcejustificationNr   r   r   r   r   r*   /   s   
 r*   c                   @   sR   e Zd ZU ee ed< eed< eed< eed< eed< eed< dZ	e
e ed< dS )	SkillAnalysisResponserecommended_skillsanalysis_summarydepartment_coveragetotal_skills_recommendedcase_appliedidentified_fieldNfield_analysis)r   r   r   r   r*   r   r   r#   r   r5   r   r   r   r   r   r   r.   8   s   
 r.   c                   @   s:   e Zd ZU eed< eed< eed< eed< ee ed< dS )Course	course_idcourse_nameshort_descriptiondescriptionskillsN)r   r   r   r   r   r   r   r   r   r   r6   B   s   
 r6   c                   @   s   e Zd ZU eed< eed< dS )InferredSkillInternalr'   r(   N)r   r   r   r   r   r   r   r   r   r<   J   r   r<   c                   @   s&   e Zd ZU eed< eed< eed< dS )SkillMatchInternal
user_skillcourse_skill
confidenceN)r   r   r   r   r   r#   r   r   r   r   r=   O   s   
 r=   c                   @   sz   e Zd ZU eed< eed< eed< eed< ee ed< eed< eed< eed< eed	< eed
< ee ed< ee	 ed< dS )CourseRecommendationInternalr7   r8   r9   r:   matched_skillsrelevance_scorellm_justificationmatched_usingdomain_relevancedomain_confidenceinferred_skillsskill_matchesN)
r   r   r   r   r   r   r#   r$   r<   r=   r   r   r   r   rA   U   s   
 rA   c                   @   s  e Zd ZdZd8defddZdededefd	d
Zdedee	 dee	 fddZ
dedee dedee	 dee	 f
ddZdededee	 dee	 fddZdededee	 dee	 fddZdededee dedee f
ddZdededee dededee fddZdededededee f
ddZdededededee f
d d!Zd"edefd#d$Zd%efd&d'Zd"edefd(d)Zd*ee dee	 dee	 fd+d,Zd-edefd.d/Zd0edee fd1d2Zd3ed4edefd5d6Zd7S )9EnhancedSkillInferenceEnginez8Enhanced skill inference with specificity-aware analysis
gemma3:12b
model_namec              
   C   N   zt |d| _td|  W d S  ty& } z	td|   d }~ww )Nmodelz+Initialized Enhanced Skill LLM with model: z)Failed to initialize Enhanced Skill LLM: r	   llmloggerinfo	ExceptionerrorselfrL   er   r   r   __init__k      z%EnhancedSkillInferenceEngine.__init__
user_queryr   returnc              
   C   s   t ddgdd}z"|j||d}| jt|dg}| |j}td|  |W S  t	yL } zt
d|  d	d
g dddW  Y d}~S d}~ww )z7Enhanced field identification with specificity analysisr[   r   a  
            You are an expert business analyst specializing in identifying professional fields and domains.
            
            User Goal/Challenge: {user_query}
            Department: {department_name}
            
            Analyze the user's goal and provide a detailed field analysis including specificity level.
            
            SPECIFICITY LEVELS:
            - GENERAL: Broad, vague requests like "improve tech skills", "better at development", "enhance coding"
            - SPECIFIC: Domain-focused like "improve frontend skills", "better at web development", "enhance mobile development"  
            - HIGHLY_SPECIFIC: Technology-specific like "improve Angular skills", "better at React development", "enhance AWS cloud skills"
            
            Return your analysis in this EXACT JSON format:
            {{
                "primary_field": "specific field name",
                "specificity_level": "GENERAL|SPECIFIC|HIGHLY_SPECIFIC", 
                "key_technologies": ["tech1", "tech2"],
                "skill_focus": "broad|targeted",
                "learning_approach": "exploration|specialization|mastery"
            }}
            
            Field Analysis:
            input_variablestemplate)r[   r   contentzEnhanced field analysis: z(Error in enhanced field identification: GeneralGENERALbroadexplorationprimary_fieldspecificity_levelkey_technologiesskill_focuslearning_approachN)r
   formatrQ   invoker   _parse_field_analysisra   rR   rS   rT   rU   )rW   r[   r   prompt_templateformatted_promptresponser5   rX   r   r   r   identify_field_domains   s.   z2EnhancedSkillInferenceEngine.identify_field_domainr5   all_skills_datac                 C   sh   |d }|d }|d }d dd |D }|dkr"| ||||S |dkr-| |||S | |||S )	z3Enhanced skill filtering based on specificity levelrg   rh   ri   
c                 S   s&   g | ]}d |d  d|d  dqS )z- r'   z (ID: r&   )r   .0skillr   r   r   
<listcomp>   s    zVEnhancedSkillInferenceEngine.filter_relevant_organizational_skills.<locals>.<listcomp>HIGHLY_SPECIFICSPECIFIC)join_filter_highly_specific_skills_filter_specific_skills_filter_general_skills)rW   r5   rs   rg   rh   ri   skills_textr   r   r   %filter_relevant_organizational_skills   s   
zBEnhancedSkillInferenceEngine.filter_relevant_organizational_skillsrg   ri   r   c              
   C   s   d |}tg ddd}z.|j|||d}| jt|dg}| |j}	| |	|}
t	
dt|
 d|  |
W S  tyW } zt	d|  g W  Y d	}~S d	}~ww )
z5Filter skills for highly specific technology requests, )rg   ri   r   a7  
            HIGHLY SPECIFIC SKILL FILTERING for {primary_field}
            Target Technologies: {key_technologies}
            
            Available Skills:
            {skills_text}
            
            Since this is a HIGHLY SPECIFIC request focusing on {key_technologies}, filter skills that are:
            1. DIRECTLY related to {key_technologies} 
            2. Essential prerequisites for {key_technologies}
            3. Advanced concepts that build upon {key_technologies}
            
            Be VERY SELECTIVE - only include skills that have clear relevance to {key_technologies}.
            
            Return ONLY the skill names that are relevant, one per line:
            - Skill Name 1
            - Skill Name 2
            
            Relevant Skills for {key_technologies}:
            r]   r`   	Filtered z highly specific skills for z*Error in highly specific skill filtering: N)r|   r
   rl   rQ   rm   r   _parse_skills_from_responsera   _match_skills_to_datarR   rS   lenrT   rU   )rW   rg   ri   r   rs   key_tech_strro   rp   rq   relevant_skill_namesrelevant_skillsrX   r   r   r   r}      s*   
z;EnhancedSkillInferenceEngine._filter_highly_specific_skillsc           
   
   C      t ddgdd}z-|j||d}| jt|dg}| |j}| ||}t	dt
| d|  |W S  tyQ }	 ztd	|	  g W  Y d
}	~	S d
}	~	ww )z*Filter skills for specific domain requestsrg   r   a  
            SPECIFIC SKILL FILTERING for {primary_field}
            
            Available Skills:
            {skills_text}
            
            Since this is a SPECIFIC domain request for {primary_field}, filter skills that are:
            1. Core skills essential to {primary_field}
            2. Common tools and technologies used in {primary_field}
            3. Industry-standard technologies for {primary_field}
            
            Be moderately selective - include skills that are commonly needed in {primary_field}.
            
            Return ONLY the skill names that are relevant, one per line:
            - Skill Name 1
            - Skill Name 2
            
            Relevant Skills for {primary_field}:
            r]   rg   r   r`   r   z specific domain skills for z#Error in specific skill filtering: Nr
   rl   rQ   rm   r   r   ra   r   rR   rS   r   rT   rU   
rW   rg   r   rs   ro   rp   rq   r   r   rX   r   r   r   r~      &   z4EnhancedSkillInferenceEngine._filter_specific_skillsc           
   
   C   r   )z(Filter skills for general broad requestsrg   r   a4  
            GENERAL SKILL FILTERING for {primary_field}
            
            Available Skills:
            {skills_text}
            
            Since this is a GENERAL request for improving skills in {primary_field}, filter skills that are:
            1. Foundational skills that provide broad value in {primary_field}
            2. Popular tools and technologies in {primary_field}
            3. Skills that provide good career foundation in {primary_field}
            
            Be INCLUSIVE - include skills that could be valuable for someone wanting to improve broadly in {primary_field}.
            
            Return ONLY the skill names that are relevant, one per line:
            - Skill Name 1
            - Skill Name 2
            
            Relevant Skills for {primary_field}:
            r]   r   r`   r   z general foundation skills for z"Error in general skill filtering: Nr   r   r   r   r   r     r   z3EnhancedSkillInferenceEngine._filter_general_skillsexisting_skillsneeded_countc           	      C   sl   |d }|d }|d }|rd |nd}|dkr"| |||||S |dkr.| ||||S | ||||S )z=Enhanced external skill suggestion based on specificity levelrg   rh   ri   r   Nonerz   r{   )r|   (_suggest_highly_specific_external_skills!_suggest_specific_external_skills _suggest_general_external_skills)	rW   r[   r5   r   r   rg   rh   ri   existing_skills_textr   r   r   suggest_external_skills>  s   
z4EnhancedSkillInferenceEngine.suggest_external_skillsc              
   C   s   d |}tg ddd}z!|j|||||d}| jt|dg}	| |	j}
|
d| W S  tyJ } zt	
d|  g W  Y d}~S d}~ww )z?Suggest external skills for highly specific technology requestsr   )r[   rg   ri   r   r   aU  
            User Goal: {user_query}
            Field: {primary_field}
            Target Technologies: {key_technologies}
            Already Covered: {existing_skills}
            
            Suggest {needed_count} ADVANCED external skills specifically for {key_technologies}.
            
            Focus on advanced {key_technologies} concepts, testing tools, and deployment.
            
            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            
            Advanced {key_technologies} Skills:
            r]   r`   Nz4Error in highly specific external skill suggestion: )r|   r
   rl   rQ   rm   r   r   ra   rT   rR   rU   )rW   r[   rg   ri   r   r   r   ro   rp   rq   r;   rX   r   r   r   r   T  s*   
zEEnhancedSkillInferenceEngine._suggest_highly_specific_external_skillsc           
   
   C      t g ddd}z |j||||d}| jt|dg}| |j}|d| W S  tyD }	 zt	d|	  g W  Y d}	~	S d}	~	ww )z4Suggest external skills for specific domain requestsr[   rg   r   r   a  
            User Goal: {user_query}
            Field: {primary_field}
            Already Covered: {existing_skills}
            
            Suggest {needed_count} external skills that are trending in the {primary_field} domain.
            
            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            
            Trending {primary_field} Skills:
            r]   r`   Nz-Error in specific external skill suggestion: 
r
   rl   rQ   rm   r   r   ra   rT   rR   rU   
rW   r[   rg   r   r   ro   rp   rq   r;   rX   r   r   r   r     &   z>EnhancedSkillInferenceEngine._suggest_specific_external_skillsc           
   
   C   r   )z2Suggest external skills for general broad requestsr   a  
            User Goal: {user_query}
            Field: {primary_field}
            Already Covered: {existing_skills}
            
            Suggest {needed_count} diverse external skills for a strong foundation in {primary_field}.
            
            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            
            Foundation {primary_field} Skills:
            r]   r`   Nz,Error in general external skill suggestion: r   r   r   r   r   r     r   z=EnhancedSkillInferenceEngine._suggest_general_external_skillsresponse_contentc              
   C   s   z.t d|t j}|r)t| }g d}|D ]}||vr%| |||< q|W S | |W S  tyP } zt	
d|  ddg dddW  Y d}~S d}~ww )	z&Parse field analysis from LLM responsez\{.*\}rf   zError parsing field analysis: rb   rc   rd   re   N)researchDOTALLjsonloadsgroup_get_default_value_fallback_field_analysisrT   rR   rU   )rW   r   
json_matchr5   required_fieldsfieldrX   r   r   r   rn     s*   z2EnhancedSkillInferenceEngine._parse_field_analysis
field_namec                 C   s   ddg ddd}| |dS )z%Get default values for missing fieldsrb   rc   rd   re   rf    )get)rW   r   defaultsr   r   r   r     s   z/EnhancedSkillInferenceEngine._get_default_valuec                    sv   |   t fdddD rd}d}d}nt fdddD r(d	}d
}d}nd}d
}d}| |}||g ||dS )z+Fallback parsing when JSON extraction failsc                 3       | ]}| v V  qd S Nr   )rw   techcontent_lowerr   r   	<genexpr>      zHEnhancedSkillInferenceEngine._fallback_field_analysis.<locals>.<genexpr>)angularreactvuepythonjavaawsdockerrz   targetedmasteryc                 3   r   r   r   )rw   domainr   r   r   r     r   )zweb developmentzmobile developmentzdata sciencefrontendbackendr{   rd   specializationrc   re   rf   )lowerany_clean_field_name)rW   r   specificityfocusapproachr   r   r   r   r     s&   
z5EnhancedSkillInferenceEngine._fallback_field_analysisskill_namesc                 C   s:   g }|D ]}|D ]}|  ||d r||  nqq|S )z-Match skill names back to original skill datar'   )_skills_matchappend)rW   r   rs   r   r'   	org_skillr   r   r   r     s   
z2EnhancedSkillInferenceEngine._match_skills_to_data
field_textc                 C   s<   |  dd }|dddddd}| d}|S )zClean and normalize field namert   r   zField/Domain:r   zField:zDomain: "')stripsplitreplace)rW   r   r   r   r   r     s   
z.EnhancedSkillInferenceEngine._clean_field_nameresponse_textc                 C   sX   g }|  d}|D ]}|  }tdd|}|  }|r)t|dkr)|| q|S )zParse skills from LLM responsert      ^[-•*\d+\.\)]\s*r      )r   r   r   subr   r   )rW   r   r;   linesliner   r   r   r     s   
z8EnhancedSkillInferenceEngine._parse_skills_from_responseskill1skill2c                 C   sl   t dd|  }t dd|  }||krdS td|| }|dkr*dS ||v s2||v r4dS dS )z9Check if two skill names match with reasonable similarity[^a-zA-Z0-9\s]r   TNg?F)r   r   r   r   r   ratio)rW   r   r   skill1_normskill2_norm
similarityr   r   r   r   (  s   z*EnhancedSkillInferenceEngine._skills_matchNrK   )r   r   r   __doc__r   rY   dictrr   r   r   r   r}   r~   r   r   r   r   r   r   rn   r   r   r   r   r   r$   r   r   r   r   r   rJ   h   s~    3


/

+

+



+

$
%"
rJ   c                   @   s@   e Zd ZddefddZdedefddZd	edefd
dZdS )DepartmentInferenceEnginerK   rL   c              
   C   rM   )NrN   z'Initialized Department LLM with model: z%Failed to initialize Department LLM: rP   rV   r   r   r   rY   >  rZ   z"DepartmentInferenceEngine.__init__r   r\   c              
   C   s   t dgdd}z%|j|d}| jt|dg}|j }| |}t	d|  |W S  t
yG } ztd|  W Y d }~dS d }~ww )	Nr   a  
            You are an expert business analyst specializing in organizational structure and training needs.
            
            Based on the following business goal or challenge, identify the SINGLE most relevant department.
            
            User Goal/Challenge: {user_prompt}
            
            Common departments include:
            - Sales
            - Marketing
            - HR (Human Resources)
            - Operations
            - Finance
            - Product Management
            - Development/Engineering
            - Customer Service
            - Quality Assurance
            - Research and Development
            
            Return ONLY the department name (e.g., "Sales", "Marketing", "HR")
            
            Department:
            r]   )r   r`   zInferred department: Error in department inference: Unknown)r
   rl   rQ   rm   r   ra   r   _clean_department_namerR   rS   rT   rU   )rW   r   ro   rp   rq   inferred_deptrX   r   r   r   infer_departmentF  s    

z*DepartmentInferenceEngine.infer_department	dept_namec                 C   sD   | dd dd}| dd dd}|dd }|d}|S )	NzDepartment:r   r   zTeam:Teamrt   r   r   )r   r   r   )rW   r   r   r   r   r   p  s
   
z0DepartmentInferenceEngine._clean_department_nameNr   )r   r   r   r   rY   r   r   r   r   r   r   r   =  s    *r   c                   @   s<   e Zd ZedededefddZededefddZd	S )
SimilarityMatcherstr1str2r\   c                 C   s   t | }t |}td || }||krdnd}||v s"||v r$dnd}t| }t| }|rD|rDt||t|| nd}	t	||||	}
|
S )N      ?        g?)
r   _normalize_stringr   r   setr   r   intersectionunionmax)r   r   	str1_norm	str2_normseq_similarityexact_matchsubstring_matchwords1words2word_similarityfinal_scorer   r   r   calculate_similarityx  s   

(z&SimilarityMatcher.calculate_similaritysc                 C   sl   |   } tdd| } tdd| } dddddddd	d	d
d
d
dd
d}| D ]
\}}| ||} q'|  S )Nr   r   z\s+ hritrdzcustomer supportproductdevelopment	developer)zhuman resourceszhuman resourcezinformation technologyzresearch and developmentzresearch & developmentzcustomer servicezcustomer carezproduct managementzproduct managerzsoftware developmentzsoftware engineeringengineering
programmerprogramming)r   r   r   itemsr   r   )r   replacementsoldnewr   r   r   r     s*   z#SimilarityMatcher._normalize_stringN)r   r   r   staticmethodr   r#   r   r   r   r   r   r   r   w  s
    r   c                
   @   s   e Zd ZddefddZdededeeeef fdd	Z	dede
e fd
dZde
e de
e de
e fddZdede
e dededef
ddZdedeeeef fddZdede
e fddZdede
e fddZdS )CourseInferenceEnginerK   rL   c              
   C   rM   )NrN   z#Initialized Course LLM with model: z!Failed to initialize Course LLM: rP   rV   r   r   r   rY     rZ   zCourseInferenceEngine.__init__course
departmentr\   c           
   
   C   s   t g ddd}z6|j|j|j|j|d}| jt|dg}| |j	\}}}t
d|j d| d|dd	 |||fW S  tyY }	 zt
d
|	  W Y d }	~	dS d }	~	ww )N)r8   r9   r:   r  ai  
            Course Information:
            - Course Name: {course_name}
            - Short Description: {short_description}
            - Full Description: {description}
            
            Target Department/Domain: {department}
            
            STRICT EVALUATION RULES:
            1. Return "No" if course is generic (demo, test, sample, author courses)
            2. Return "No" if course has no clear domain-specific content
            3. Only return "Yes" if course teaches SPECIFIC skills relevant to {department}
            
            For {department} domain, look for:
            - Technical skills, programming, development tools (if Developer/Technical)
            - Sales techniques, client management, revenue (if Sales)
            - HR processes, recruitment, management (if HR)
            
            Is this course specifically relevant and valuable for {department} professionals?
            
            Return EXACTLY this format:
            Is_Match: [Yes/No]
            Confidence: [0.0 to 1.0]
            Justification: [One clear sentence explaining your decision]
            r]   r`   zDomain relevance for 'z': z (confidence: z.2fru   z&Error in domain relevance evaluation: )Fr   zError in evaluation)r
   rl   r8   r9   r:   rQ   rm   r   _parse_domain_responsera   rR   rS   rT   rU   )
rW   r  r  ro   rp   rq   is_matchr@   r-   rX   r   r   r   evaluate_domain_relevance  s(   "z/CourseInferenceEngine.evaluate_domain_relevancec              
   C   s   t g ddd}z9|jrd|jnd}|j|j|j|j|d}| jt	|dg}| 
|j}tdt| d|j d	 |W S  ty] } ztd
|  g W  Y d }~S d }~ww )N)r8   r9   r:   r   aF  
            Course Information:
            - Course Name: {course_name}
            - Short Description: {short_description}
            - Full Description: {description}
            - Existing Skill Tags: {existing_skills}
            
            Based on the course content, identify 3-5 key skills that learners will likely develop or improve.
            
            Return skills in the following format:
            - Skill Name 1 | Skill Level
            - Skill Name 2 | Skill Level
            - Skill Name 3 | Skill Level
            
            Skills:
            r]   r   zNone specifiedr`   z
Extracted z skills from ''zError in skill extraction: )r
   r;   r|   rl   r8   r9   r:   rQ   rm   r   _parse_skills_responsera   rR   rS   r   rT   rU   )rW   r  ro   r   rp   rq   rH   rX   r   r   r   extract_course_skills  s*   z+CourseInferenceEngine.extract_course_skillsuser_skillscourse_skillsc           
   
   C   s   |r|sg S d |}d dd |D }tddgdd}z%|j||d}| jt|d	g}| |j}t	d
t
| d |W S  ty^ }	 ztd|	  g W  Y d }	~	S d }	~	ww )Nr   c                 S   s    g | ]}|j  d |j dqS ) (ru   r'   r(   )rw   csr   r   r   ry          zCCourseInferenceEngine.match_skills_semantically.<locals>.<listcomp>r  r  a  
            User-Needed Skills: {user_skills}
            Course-Taught Skills: {course_skills}
            
            Match semantically related skill pairs between user needs and course offerings.
            
            Return matches in the following format:
            User_Skill: [skill name] | Course_Skill: [skill name] | Confidence: [0.0-1.0]
            
            Skill Matches:
            r]   )r  r  r`   zFound z semantic skill matchesz"Error in semantic skill matching: )r|   r
   rl   rQ   rm   r   _parse_matches_responsera   rR   rS   r   rT   rU   )
rW   r  r  user_skills_textcourse_skills_textro   rp   rq   rI   rX   r   r   r   match_skills_semantically  s,   
z/CourseInferenceEngine.match_skills_semanticallyrB   rC   c              
   C   s   t g ddd}z-|rd|nd}|j|j|||d}| jt|dg}|j }	|		dd }	|	W S  t
yU }
 ztd	|
  d
| dW  Y d }
~
S d }
~
ww )N)r8   rB   rC   r  aC  
            Course: {course_name}
            Matched Skills: {matched_skills}
            Relevance Score: {relevance_score}
            Department: {department}
            
            Write a concise justification (1-2 sentences) for why this course is recommended.
            
            Justification:
            r]   r   z general professional developmentr`   zJustification:r   z Error generating justification: zRecommended for z* professionals to develop relevant skills.)r
   r|   rl   r8   rQ   rm   r   ra   r   r   rT   rR   rU   )rW   r  rB   rC   r  ro   matched_skills_textrp   rq   r-   rX   r   r   r   generate_course_justification.  s*   
z3CourseInferenceEngine.generate_course_justificationr   c           	   	   C   s   |  d}d}d}d}|D ]R}|  }| dr-|ddd    }d|v }q| d	rPz|ddd   }t|}W q tyO   d
}Y qw | dra|ddd   }q|||fS )Nrt   Fr   zNo justification providedz	is_match::   yeszconfidence:      ?zjustification:)r   r   r   
startswithr#   
ValueError)	rW   r   r   r  r@   r-   r   
match_textconfidence_textr   r   r   r  R  s(   

z,CourseInferenceEngine._parse_domain_responsec                 C   s   g }|  d}|D ]5}|  }tdd|}d|v r@|d}t|dkr@|d   }|d   }|r@|r@|t||d q|S )	Nrt   r   r   |r   r   r!  r  )r   r   r   r   r   r   r<   )rW   r   r;   r   r   partsr'   r(   r   r   r   r  i  s"   
z,CourseInferenceEngine._parse_skills_responsec                 C   sD  g }|  d}|D ]}|  }|r| dv rqzfd|v rd|v rd|v r|d}t|dkr|d d	d
d
   }|d
 d	d
d
   }|d d	d
d
   }td|}	|	rt|	d
}
|
dkrm|
d }
|
dkr|r|r|t	|||
d W q t
tfy } ztd| d|  W Y d }~qd }~ww |S )Nrt   )zskill matches:zmatches:r   zUser_Skill:zCourse_Skill:zConfidence:r(     r   r   r!  r   z(\d+\.?\d*)r   g      Y@r#  r>   r?   r@   zFailed to parse line: 'z' - Error: )r   r   r   r   r   r   r#   r   r   r=   r%  
IndexErrorrR   warning)rW   r   matchesr   r   r)  r>   r?   r'  confidence_matchr@   rX   r   r   r   r    s>   
z-CourseInferenceEngine._parse_matches_responseNr   )r   r   r   r   rY   r6   r   r$   r#   r  r   r<   r  r=   r  r  r  r  r  r   r   r   r   r    s&     /
(
&
$r  c                   @   s  e Zd Zd2defddZdedee defdd	Zd
edededee	 dee
 dee deeee f fddZd
edededee	 dee
 defddZd
edededee	 dedee
 defddZd
edededee	 dedee
 defddZded
edededef
ddZdedee de
fdd Zd3dee	 d"edee	 fd#d$Zded%ed&ee dee dee f
d'd(Zd)ee d*ed+ee defd,d-Zd.ee defd/d0Zd1S )4EnhancedIntegratedTNASystemrK   rL   c                 C   sF   t || _t | _t|| _t|| _d| _d| _	d| _
td d S )NgQ?333333?   zEEnhanced Integrated TNA System initialized with specificity detection)r   dept_enginer   similarity_matcherrJ   skill_enginer  course_enginesimilarity_thresholddomain_thresholdmin_skills_targetrR   rS   )rW   rL   r   r   r   rY     s   


z$EnhancedIntegratedTNASystem.__init__r   r   r\   c              
   C   s   z8t ||}| j|j}| ||j}|d | jkr-t|d j|d j	||d ddW S tdd||d ddW S  t
y[ } ztd|  tdd	d	d
ddW  Y d}~S d}~ww )zProcess department inferencer!   r  T)r   r   r    r!   r"   r   NullFr   Errorr   N)r   r3  r   r   _find_best_matchr   r7  r   r   r   rT   rR   rU   )rW   r   r   tna_requestr    
best_matchrX   r   r   r   process_department_inference  s<   
z8EnhancedIntegratedTNASystem.process_department_inferencer[   
admin_namer   filtered_skillsrs   offline_coursesc              
   C   s   z |  |||||}| ||||}| ||j|j|}	||	fW S  tyC }
 ztd|
  dt|
 g fW  Y d}
~
S d}
~
ww )zLEnhanced skill analysis and course recommendation with specificity awarenessz-Error in enhanced skill and course analysis: zError in analysis: N)	_analyze_skills_enhanced/_generate_strategic_skill_presentation_enhanced_recommend_coursesr4   r/   rT   rR   rU   r   )rW   r[   r@  r   rA  rs   rB  skill_analysis_responseskill_analysis_strategiccourse_recommendationsrX   r   r   r   !process_skill_and_course_analysis  s4   
z=EnhancedIntegratedTNASystem.process_skill_and_course_analysisc                 C   sd   | j ||pd}| j ||}|r(| dkr(t|dkr(| ||||||S | ||||||S )z8Enhanced skill analysis using specificity-aware approachrb   nullr*  )r5  rr   r   r   r   _handle_case_1_enhanced_handle_case_2_enhanced)rW   r[   r@  r   rA  rs   r5   relevant_org_skillsr   r   r   rC    s"   

z4EnhancedIntegratedTNASystem._analyze_skills_enhancedr5   rM  c                 C   s  t d |d }|d }g }	t }
| |d}|D ]-}|j|
vrG|	t|j|j|jp,dddd|j	 d	t
d
d |D  d |
|j q|D ])}|d |
vrs|	t|d |d dddd| d|  dd |
|d  qJt|	| jk r| jt|	 }dd |	D }| j||||}t|D ]\}}|	td| |dddd|  d| dd q|rt|t| nd}t|	d| j d| d| d| d t| d!	|t|	d| j d"||d#S )$z6Handle Case 1 with enhanced specificity-aware approachzFApplying Case 1 (Enhanced): Department found with sufficient employeesrg   rh   r#  IntermediateHighdepartment_existingzUnder-covered in department: z employees out of c                 S      g | ]}|j qS r   r)   rw   r   r   r   r   ry   %      zGEnhancedIntegratedTNASystem._handle_case_1_enhanced.<locals>.<listcomp>r&   r'   r(   r+   r,   r-   r&   r'   Mediumorganizational_relevantRelevant to  field (% level) and available in organizationc                 S   rQ  r   r'   rw   recr   r   r   ry   9  rT  (#  BeginnerLowexternal	External  skill for z to enhance capabilitiesr   NzEnhanced analysis for z department in 	). Found   relevant organizational skills.z=Case 1 (Enhanced): Department found with sufficient employeesr/   r0   r1   r2   r3   r4   r5   )rR   rS   r   _filter_department_skillsr&   r   r*   r'   r(   r)   r   addr   r   r9  r5  r   	enumerater.   )rW   r[   r@  r   rA  r5   rM  r4   rh   recommendationsused_skill_idsunder_covered_dept_skills
dept_skillr   r   existing_skill_namesexternal_skillsi	ext_skilldept_coverager   r   r   rK    st   


	 z3EnhancedIntegratedTNASystem._handle_case_1_enhancedc                 C   s@  t d |d }|d }g }	t }
|D ])}|d |
vr=|	t|d |d dddd	| d
|  dd |
|d  qt|	| jk r}| jt|	 }dd |	D }| j	
||||}t|D ]\}}|	td| |dddd|  d| dd q`t|	d| j d| d
| dt| ddt|	d| j d||dS )z6Handle Case 2 with enhanced specificity-aware approachzJApplying Case 2 (Enhanced): Department not found or insufficient employeesrg   rh   r&   r'   rN  rV  rW  rX  rY  rZ  rU  c                 S   rQ  r   r[  r\  r   r   r   ry   t  rT  zGEnhancedIntegratedTNASystem._handle_case_2_enhanced.<locals>.<listcomp>r^  r_  r`  ra  rb  rc  z to fill capability gapNzEnhanced general analysis for rd  re  r   zACase 2 (Enhanced): Department not found or insufficient employeesrf  )rR   rS   r   r   r*   r   rh  r   r9  r5  r   ri  r.   )rW   r[   r@  r   rA  r5   rM  r4   rh   rj  rk  r   r   rn  ro  rp  rq  r   r   r   rL  X  sX   

	z3EnhancedIntegratedTNASystem._handle_case_2_enhancedanalysis_responsec                 C   s  dd |j D }dd |j D }dd |j D }|j r&t|t|j  d nd}t d}	|jp3i }
|
dd	}|
d
g }|
dd}|rQdd| dnd}dg d| d| d|	 d|j | d| d|j d| d|	  d|j
 dt| dt| d|dd| dd  d!| d"|j d#|	  d$|d%krd&n|d'krd(nd) d*|rd|nd+ d,| ||  d-| | d.|	 d/}|S )0zEGenerate enhanced strategic presentation with specificity informationc                 S      g | ]	}|j d kr|qS )rW  r,   rS  r   r   r   ry         z_EnhancedIntegratedTNASystem._generate_strategic_skill_presentation_enhanced.<locals>.<listcomp>c                 S   rt  )ra  ru  rS  r   r   r   ry     rv  c                 S   rt  )rP  ru  rS  r   r   r   ry     rv  d   r   z	%B %d, %Yrh   rc   ri   rk   re   z	 (Focus: r   ru   r   u   
📊 ENHANCED TRAINING NEEDS ANALYSIS REPORT
═══════════════════════════════════════════════════════════════

Organization: z
Department: z
Analysis Date: z
Field Identified: u   

🎯 EXECUTIVE SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

User Goal: "z"
AI-Identified Field: z
Specificity Level: z
Learning Approach: z
Case Applied: u   

Key Findings:
• u6    organizational skills aligned with business goal
• u=    external skills identified for capability enhancement  
• z.1fu4   % utilization of existing organizational assets
• _-u   learning pathway identified

🧠 SPECIFICITY ANALYSIS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Request Type: u   
├─ Field Focus: u   
├─ Learning Approach: u   
├─ Skill Selection: rz   zTargeted technology-specificr{   zDomain-focusedzBroad foundationalu   
└─ Key Technologies: zGeneral skills across the fieldu  

🟢 IMMEDIATE PRIORITIES (Organizational Skills)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
u  

🟡 GROWTH OPPORTUNITIES (External Skills)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
u   

═══════════════════════════════════════════════════════════════
Report Generated: u   
Analysis Engine: Enhanced TNA v3.0 (Specificity-Aware Approach)
═══════════════════════════════════════════════════════════════
)r/   r   r   nowstrftimer5   r   r|   r4   titler3   r   r   _format_skill_section)rW   rs  r[   r@  r   
org_skills
ext_skillsdept_skillsorg_percentagecurrent_dater5   rh   ri   rk   tech_focus_textstrategic_reportr   r   r   rD    sp    


#'*/zKEnhancedIntegratedTNASystem._generate_strategic_skill_presentation_enhancedr   org_departmentsc                 C   sD   ddd}|D ]}| j ||j}||d kr||d< ||d< q|S )zAFind the best matching department from organization's departmentsNr   )r  r!   r!   r  )r4  r   r   )rW   r   r  r>  deptr!   r   r   r   r<    s   z,EnhancedIntegratedTNASystem._find_best_matchr#  coverage_thresholdc                 C   sL   |sg S t dd |D dd}g }|D ]}|j| }||k r#|| q|S )zAFilter out skills that are already well-covered in the departmentc                 S   rQ  r   rR  rv   r   r   r   ry     rT  zIEnhancedIntegratedTNASystem._filter_department_skills.<locals>.<listcomp>r!  )default)r   r)   r   )rW   rA  r  total_employeesunder_covered_skillsrx   coverage_ratior   r   r   rg    s   

z5EnhancedIntegratedTNASystem._filter_department_skillsr4   r/   c                 C   s   dd |D }g }|D ]]}t d|j  | j||\}}	}
|rh|	| jkrh| j|}| j||}| ||	|}t	t
dd |D }| j||||}|rh|t|j|j|j|j|||d||	||d q|jdd d	d
 |S )z&Recommend courses using enhanced logicc                 S   rQ  r   r[  rv   r   r   r   ry     rT  zBEnhancedIntegratedTNASystem._recommend_courses.<locals>.<listcomp>zProcessing course: c                 S   rQ  r   )r>   rw   matchr   r   r   ry     rT  rQ   )r7   r8   r9   r:   rB   rC   rD   rE   rF   rG   rH   rI   c                 S   s   | j S r   )rC   )xr   r   r   <lambda>$  s    z@EnhancedIntegratedTNASystem._recommend_courses.<locals>.<lambda>T)keyreverse)rR   rS   r8   r6  r  r8  r  r  _calculate_relevance_scorelistr   r  r   rA   r7   r9   r:   sort)rW   r   r4   r/   rB  user_skill_namesrH  r  is_relevantrG   domain_justificationrH   rI   rC   matched_skill_namesr-   r   r   r   rE    sJ   
z.EnhancedIntegratedTNASystem._recommend_coursesrI   rG   rH   c           	      C   s   |sdS t dd |D t| }tt|d d}d}|D ]}|j dv r+|d7 }qt|d}|d	 |d  | | }t|d
S )z.Calculate overall relevance score for a courser   c                 s   s    | ]}|j V  qd S r   )r@   r  r   r   r   r   .  s    zIEnhancedIntegratedTNASystem._calculate_relevance_score.<locals>.<genexpr>g?g333333?)advancedexpertg?g?r1  r   )sumr   minr(   r   )	rW   rI   rG   rH   avg_skill_confidencematch_count_bonuslevel_bonusrx   rC   r   r   r   r  '  s&   

z6EnhancedIntegratedTNASystem._calculate_relevance_scorer;   c              	   C   sL   |sdS g }t |dD ]\}}||dd|j d|j d qd|S )z0Format skills section for strategic presentationz&No skills identified in this category.r!  2dz. r  ru   rt   )ri  r   r'   r(   r|   )rW   r;   formatted_skillsrp  rx   r   r   r   r}  @  s   $
z1EnhancedIntegratedTNASystem._format_skill_sectionNr   )r#  )r   r   r   r   rY   r   r   r   r?  r%   r   r6   r   rA   rI  r.   rC  r   rK  rL  rD  r<  r#   rg  r*   rE  r=   r<   r  r}  r   r   r   r   r0    s~    #
!

J
9
C 


2
r0  rK   rL   r\   c                 C   s   t | S )z.Factory function to create enhanced TNA system)r0  )rL   r   r   r   create_enhanced_tna_systemO  s   r  
tna_systemr   departmentsc                 C   s(   dd |D }|  ||}|j|jdS )z,Convenience function for department analysisc                 S   s    g | ]}t |d  |d dqS )r   r   )r   r   )r   )rw   dr   r   r   ry   V  r  z/process_department_analysis.<locals>.<listcomp>)identified_departmentr   )r?  r   r   )r  r   r  dept_objectsresultr   r   r   process_department_analysisS  s
   r  r[   r@  r   rA  
all_skillscoursesc                 C   s   dd |D }dd |D }|  ||||||\}	}
g }|
D ] }||j|j|j|j|jdd |jD dd |jD d q|	|dS )z=Enhanced convenience function for skills and courses analysisc              	   S   s0   g | ]}t |d  |d |d|ddqS )r&   r'   r(   r)   r&   r'   r(   r)   )r%   r   rS  r   r   r   ry   d  s    z@process_enhanced_skills_and_courses_analysis.<locals>.<listcomp>c                 S   s6   g | ]}t |d  |d |d |d |dg dqS )r7   r8   r9   r:   r;   r7   r8   r9   r:   r;   )r6   r   )rw   cr   r   r   ry   m  s    
c                 S   s   g | ]	}|j |jd qS )r  r  rv   r   r   r   ry     s    c                 S   s   g | ]}|j |j|jd qS )r+  r+  r  r   r   r   ry     s    )r7   r   rB   r-   rC   rH   rI   )skill_analysiscourses_offline)	rI  r   r7   r8   rB   rD   rC   rH   rI   )r  r[   r@  r   rA  r  r  skill_objectscourse_objectsstrategic_analysisrH  r  
course_recr   r   r   ,process_enhanced_skills_and_courses_analysis^  s6   	

r  __main__zP================================================================================z!ENHANCED TNA SYSTEM DEMONSTRATIONzWant to improve my tech abilityAscent	Developerx   PythonrN     r  i  zEmotional IntelligenceAdvancedr*  y   
JavaScript)r&   r'   z   React{   zNode.js101zFull Stack DevelopmentzComplete web development coursez(Learn HTML, CSS, JavaScript, and backend)htmlcss
javascriptr  zGENERAL QUERY RESULT:r  i  z...z!Want to improve my Angular skills
TypeScriptAngular201zAdvanced AngularzMaster Angular frameworkz%Deep dive into Angular and TypeScriptr   
typescriptz
SPECIFIC QUERY RESULT:zQ
================================================================================zENHANCEMENT SUCCESS!r   )2r   loggingtypingr   r   r   r   dataclassesr   difflibr   r   r   langchain_ollamar	   langchain.promptsr
   langchain.schemar   basicConfigINFO	getLoggerr   rR   r   r   r   r%   r*   r.   r6   r<   r=   rA   rJ   r   r   r  r0  r   r  r  r  IntegratedTNASystemcreate_tna_system#process_skills_and_courses_analysistnaprintgeneral_resultspecific_resultr   r   r   r   <module>   s   
	   X:1    ,



;
