o
    Ki                    @   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 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G dd dZ G dd dZ!G dd dZ"G dd dZ#dd  Z$ed!kre$  dS dS )"    N)DictListOptionalTuple)	dataclass)SequenceMatcher)Counter)datetime)
ChatOllama)PromptTemplate)HumanMessage)levelc                   @   sB   e Zd ZU dZeed< eed< dZee ed< dZ	ee ed< dS )Skillz Data class for skill informationskill_id
skill_nameNskill_levelskill_count)
__name__
__module____qualname____doc__int__annotations__strr   r   r    r   r   :/var/www/eduai.edurigo.com/tna/testing/tna_skill_second.pyr      s   
 r   c                   @   s>   e Zd ZU dZeed< eed< eed< eed< ee ed< dS )Coursez!Data class for course information	course_idnameshort_descriptiondescriptionskillsN)r   r   r   r   r   r   r   r   r   r   r   r      s   
 r   c                   @   sJ   e Zd ZU dZeed< eed< eed< ee ed< ee ed< eed< dS )	SkillAnalysisRequestz%Data class for skill analysis request
user_query
admin_namedepartment_namefiltered_skillsall_skills_dataall_courses_dataN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r"   "   s   
 r"   c                   @   sB   e Zd ZU dZeed< eed< eed< eed< eed< eed< dS )	SkillRecommendationz#Data class for skill recommendationr   r   r   prioritysourcejustificationN)r   r   r   r   r   r   r   r   r   r   r   r)   ,   s   
 r)   c                   @   sF   e Zd ZU dZee ed< eed< eed< e	ed< eed< eed< dS )	SkillAnalysisResponsez&Data class for skill analysis responserecommended_skillsanalysis_summarydepartment_coveragetotal_skills_recommendedcase_appliedidentified_fieldN)
r   r   r   r   r   r)   r   r   floatr   r   r   r   r   r-   6   s   
 r-   c                   @   sf   e Zd ZU dZeed< eed< 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< dS )AnalysisResultz'Data class for complete analysis resultsuccessr3   r2   r1   r0   r/   r.   r#   r$   r%   N)r   r   r   r   boolr   r   r   r4   r   r)   r   r   r   r   r5   @   s   
 r5   c                   @   s  e Zd ZdZd:defddZ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d0d1Zd2ed
e	e fd3d4Zd5ed6ed
efd7d8Zd9S );SkillInferenceEnginezJHandles skill inference using LLM with enhanced specificity-aware approach	gemma3:4b
model_namec              
   C   sT   zt |d| _d| _td|  W dS  ty) } z	td|   d}~ww )zInitialize the LLM model)modelr   z"Initialized Skill LLM with model: z Failed to initialize Skill LLM: N)r
   llmtotal_tokensloggerinfo	Exceptionerror)selfr:   er   r   r   __init__Q   s   zSkillInferenceEngine.__init__c                 C   s@   t |drt|jdd}t|jdd}|  j|| 7  _dS dS )z0Add token usage from LLM response to total countusage_metadatainput_tokensr   output_tokensN)hasattrgetattrrE   r=   )rB   responserF   rG   r   r   r   
add_tokens[   s
   
zSkillInferenceEngine.add_tokensr#   r%   returnc              
   C   s   t ddgdd}z'|j||d}| jt|dg}| | | |j}t	d|  |W S  t
yQ } ztd|  d	d
g dddW  Y d}~S d}~ww )a3  
        Enhanced Step 1: Identify the field/domain with specificity analysis

        Args:
            user_query: User's business goal or challenge
            department_name: Target department name

        Returns:
            Dictionary containing field analysis with specificity information
        r#   r%   u[  
            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"

            ANALYSIS REQUIRED:
            1. Identify the primary professional field/domain
            2. Determine specificity level of the request
            3. Extract any specific technologies/tools mentioned
            4. Determine if this requires broad exploration or targeted learning

            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"
            }}

            EXAMPLES:
            "improve tech skills" → {{"primary_field": "Software Development", "specificity_level": "GENERAL", "key_technologies": [], "skill_focus": "broad", "learning_approach": "exploration"}}

            "improve Angular skills" → {{"primary_field": "Frontend Development", "specificity_level": "HIGHLY_SPECIFIC", "key_technologies": ["Angular", "TypeScript"], "skill_focus": "targeted", "learning_approach": "mastery"}}

            "improve web development" → {{"primary_field": "Web Development", "specificity_level": "SPECIFIC", "key_technologies": ["HTML", "CSS", "JavaScript"], "skill_focus": "broad", "learning_approach": "specialization"}}

            Field Analysis:
            input_variablestemplate)r#   r%   contentzField analysis: zError in field identification: GeneralGENERALbroadexplorationprimary_fieldspecificity_levelkey_technologiesskill_focuslearning_approachN)r   formatr<   invoker   rK   _parse_field_analysisrQ   r>   r?   r@   rA   )rB   r#   r%   prompt_templateformatted_promptrJ   field_analysisrC   r   r   r   identify_field_domainb   s0   )
z*SkillInferenceEngine.identify_field_domainra   r'   c                 C   sh   |d }|d }|d }d dd |D }|dkr"| ||||S |dkr-| |||S | |||S )	aY  
        Enhanced Step 2: Filter organizational skills based on field analysis and specificity

        Args:
            field_analysis: Result from identify_field_domain with specificity info
            all_skills_data: Complete list of organizational skills

        Returns:
            List of field-relevant organizational skills
        rW   rX   rY   
c                 S   s&   g | ]}d |d  d|d  dqS )z- r   z (ID: r   )r   .0skillr   r   r   
<listcomp>   s    zNSkillInferenceEngine.filter_relevant_organizational_skills.<locals>.<listcomp>HIGHLY_SPECIFICSPECIFIC)join_filter_highly_specific_skills_filter_specific_skills_filter_general_skills)rB   ra   r'   rW   rX   rY   skills_textr   r   r   %filter_relevant_organizational_skills   s   
z:SkillInferenceEngine.filter_relevant_organizational_skillsrW   rY   ro   c              
   C   s   d |}tg ddd}z3|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 )
z5Filter skills for highly specific technology requests, )rW   rY   ro   a  
            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}
            4. Testing, debugging, or deployment tools for {key_technologies}
            5. Integration technologies that work with {key_technologies}

            Be VERY SELECTIVE - only include skills that have clear relevance to {key_technologies}.
            Exclude general programming concepts unless they're specifically crucial for {key_technologies}.

            Return ONLY the skill names that are relevant, one per line:
            - Skill Name 1
            - Skill Name 2
            ...

            Relevant Skills for {key_technologies}:
            rM   rP   	Filtered z highly specific skills for z*Error in highly specific skill filtering: N)rk   r   r\   r<   r]   r   rK   _parse_skills_from_responserQ   _match_skills_to_datar>   r?   lenr@   rA   )rB   rW   rY   ro   r'   key_tech_strr_   r`   rJ   relevant_skill_namesrelevant_skillsrC   r   r   r   rl      s,   

z3SkillInferenceEngine._filter_highly_specific_skillsc           
   
   C      t ddgdd}z2|j||d}| jt|dg}| | | |j}| ||}t	
dt| d|  |W S  tyV }	 zt	d	|	  g W  Y d
}	~	S d
}	~	ww )z*Filter skills for specific domain requestsrW   ro   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. Methodologies and practices specific to {primary_field}
            4. Soft skills that are particularly valuable in {primary_field}
            5. Industry-standard technologies for {primary_field}

            Include both technical and soft skills that are domain-relevant.
            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}:
            rM   rW   ro   rP   rr   z specific domain skills for z#Error in specific skill filtering: Nr   r\   r<   r]   r   rK   rs   rQ   rt   r>   r?   ru   r@   rA   
rB   rW   ro   r'   r_   r`   rJ   rw   rx   rC   r   r   r   rm      (   
z,SkillInferenceEngine._filter_specific_skillsc           
   
   C   ry   )z(Filter skills for general broad requestsrW   ro   a  
            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. Transferable skills useful across different areas of {primary_field}
            3. Essential soft skills for {primary_field} professionals
            4. Popular tools and technologies in {primary_field}
            5. Skills that provide good career foundation in {primary_field}

            Be INCLUSIVE rather than restrictive - include skills that could be valuable for someone wanting to improve broadly in {primary_field}.
            Include both technical and soft skills that build a well-rounded foundation.

            Return ONLY the skill names that are relevant, one per line:
            - Skill Name 1
            - Skill Name 2
            ...

            Relevant Skills for {primary_field}:
            rM   rz   rP   rr   z general foundation skills for z"Error in general skill filtering: Nr{   r|   r   r   r   rn   0  r}   z+SkillInferenceEngine._filter_general_skillsexisting_skillsneeded_countc           
      C   st   |d }|d }|d }|d }|rd |nd}	|dkr&| ||||	|S |dkr2| |||	|S | |||	|S )	a  
        Enhanced external skill suggestion based on specificity level

        Args:
            user_query: User's business goal
            field_analysis: Complete field analysis with specificity info
            existing_skills: Skills already identified
            needed_count: Number of additional skills needed

        Returns:
            List of external skill suggestions
        rW   rX   rY   r[   rq   Noneri   rj   )rk   (_suggest_highly_specific_external_skills!_suggest_specific_external_skills _suggest_general_external_skills)
rB   r#   ra   r~   r   rW   rX   rY   r[   existing_skills_textr   r   r   suggest_external_skills`  s    
z,SkillInferenceEngine.suggest_external_skillsc              
   C   s   d |}tg ddd}z3|j|||||d}| jt|dg}	| |	 | |	j}
t	
dt|
 d|  |
d| W S  ty\ } zt	d	|  g W  Y d}~S d}~ww )
z?Suggest external skills for highly specific technology requestsrq   )r#   rW   rY   r~   r   a  
            HIGHLY SPECIFIC EXTERNAL SKILLS for {key_technologies}

            User Goal: {user_query}
            Field: {primary_field}
            Target Technologies: {key_technologies}
            Already Covered: {existing_skills}
            Skills Needed: {needed_count}

            Suggest {needed_count} ADVANCED and SPECIALIZED external skills specifically for {key_technologies}.

            Focus on:
            1. Advanced {key_technologies} concepts and patterns
            2. {key_technologies} performance optimization techniques
            3. {key_technologies} testing and debugging tools
            4. {key_technologies} deployment and CI/CD
            5. {key_technologies} ecosystem libraries and extensions
            6. Advanced architectural patterns for {key_technologies}
            7. {key_technologies} security best practices

            Avoid basic programming concepts - focus on skills that specifically enhance {key_technologies} expertise.

            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            ...

            Advanced {key_technologies} Skills:
            rM   rP   
Suggested z% highly specific external skills for Nz4Error in highly specific external skill suggestion: )rk   r   r\   r<   r]   r   rK   rs   rQ   r>   r?   ru   r@   rA   )rB   r#   rW   rY   r~   r   rv   r_   r`   rJ   r!   rC   r   r   r   r     s.   
!
z=SkillInferenceEngine._suggest_highly_specific_external_skillsc           
   
   C      t g ddd}z2|j||||d}| jt|dg}| | | |j}t	dt
| d|  |d| W S  tyV }	 ztd|	  g W  Y d}	~	S d}	~	ww )	z4Suggest external skills for specific domain requestsr#   rW   r~   r   a  
            SPECIFIC DOMAIN EXTERNAL SKILLS for {primary_field}

            User Goal: {user_query}
            Field: {primary_field}
            Already Covered: {existing_skills}
            Skills Needed: {needed_count}

            Suggest {needed_count} external skills that are trending and valuable in the {primary_field} domain.

            Focus on:
            1. Current industry trends in {primary_field}
            2. Emerging technologies in {primary_field}
            3. Professional best practices for {primary_field}
            4. Tools that are becoming standard in {primary_field}
            5. Skills that differentiate professionals in {primary_field}

            Include both technical and methodology skills relevant to {primary_field}.

            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            ...

            Trending {primary_field} Skills:
            rM   rP   r   z% specific domain external skills for Nz-Error in specific external skill suggestion: r   r\   r<   r]   r   rK   rs   rQ   r>   r?   ru   r@   rA   
rB   r#   rW   r~   r   r_   r`   rJ   r!   rC   r   r   r   r     *   
z6SkillInferenceEngine._suggest_specific_external_skillsc           
   
   C   r   )	z2Suggest external skills for general broad requestsr   a  
            GENERAL FOUNDATIONAL EXTERNAL SKILLS for {primary_field}

            User Goal: {user_query}
            Field: {primary_field}
            Already Covered: {existing_skills}
            Skills Needed: {needed_count}

            Suggest {needed_count} diverse external skills that provide a strong foundation across {primary_field}.

            Focus on:
            1. Fundamental skills every {primary_field} professional should have
            2. Cross-cutting skills that apply to multiple areas of {primary_field}
            3. Soft skills essential for {primary_field} success
            4. Basic tools and technologies that are widely used in {primary_field}
            5. Skills that provide good career versatility in {primary_field}

            Provide a well-rounded mix of technical, methodological, and soft skills.

            Return exactly {needed_count} skills in this format:
            - External Skill 1
            - External Skill 2
            ...

            Foundation {primary_field} Skills:
            rM   rP   r   z( general foundation external skills for Nz,Error in general external skill suggestion: r   r   r   r   r   r     r   z5SkillInferenceEngine._suggest_general_external_skillsresponse_contentc           	   
   C   s   ddl }ddl}z.|d||j}|r1|| }g d}|D ]}||vr-| |||< q |W S | |W S  tyX } zt	
d|  ddg dd	dW  Y d}~S d}~ww )
z&Parse field analysis from LLM responser   Nz\{.*\}rV   zError parsing field analysis: rR   rS   rT   rU   )jsonresearchDOTALLloadsgroup_get_default_value_fallback_field_analysisr@   r>   rA   )	rB   r   r   r   
json_matchra   required_fieldsfieldrC   r   r   r   r^   "  s.   z*SkillInferenceEngine._parse_field_analysis
field_namec                 C   s   ddg ddd}| |dS )z%Get default values for missing fieldsrR   rS   rT   rU   rV    get)rB   r   defaultsr   r   r   r   B  s   z'SkillInferenceEngine._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   )rf   techcontent_lowerr   r   	<genexpr>S      z@SkillInferenceEngine._fallback_field_analysis.<locals>.<genexpr>)angularreactvuepythonjavaawsdockerri   targetedmasteryc                 3   r   r   r   )rf   domainr   r   r   r   W  r   )zweb developmentzmobile developmentzdata sciencefrontendbackendrj   rT   specializationrS   rU   rV   )lowerany_clean_field_name)rB   r   specificityfocusapproachr   r   r   r   r   M  s&   
z-SkillInferenceEngine._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)rB   r   r'   rx   r   	org_skillr   r   r   rt   k  s   
z*SkillInferenceEngine._match_skills_to_data
field_textc                 C   s<   |  dd }|dddddd}| d}|S )zClean and normalize field namerc   r   zField/Domain:r   zField:zDomain:z "')stripsplitreplace)rB   r   r   r   r   r   u  s   
z&SkillInferenceEngine._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 responserc   u   ^[-•*\d+\.\)]\s*r      )r   r   r   subru   r   )rB   r   r!   linesliner   r   r   rs   |  s   
z0SkillInferenceEngine._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 similarityz[^a-zA-Z0-9\s]r   TNg?F)r   r   r   r   r   ratio)rB   r   r   skill1_normskill2_norm
similarityr   r   r   r     s   z"SkillInferenceEngine._skills_matchNr9   )r   r   r   r   r   rD   rK   dictrb   r   r   rp   rl   rm   rn   r   r   r   r   r   r^   r   r   rt   r   rs   r7   r   r   r   r   r   r8   N   s    
L


4

0

0

"

:

3
3 "
r8   c                	   @   s6   e Zd ZdZe	d	dee dedee fddZdS )
SkillMatcherz/Handles skill matching and filtering operations      ?r&   coverage_thresholdrL   c                 C   sl   | sg S t dd | D dd}g }| D ]}|j| }||k r#|| qtdt| dt|  d |S )a7  
        Filter out skills that are already well-covered in the department

        Args:
            filtered_skills: Current department skills with counts
            coverage_threshold: Threshold for considering a skill well-covered

        Returns:
            List of skills that need improvement
        c                 S      g | ]}|j qS r   r   re   r   r   r   rh         z9SkillMatcher.filter_department_skills.<locals>.<listcomp>   )defaultrr   z under-covered skills from z total skills)maxr   r   r>   r?   ru   )r&   r   total_employeesunder_covered_skillsrg   coverage_ratior   r   r   filter_department_skills  s   

 z%SkillMatcher.filter_department_skillsN)r   )	r   r   r   r   staticmethodr   r   r4   r   r   r   r   r   r     s    r   c                	   @   s   e Zd ZdZdd ZdedefddZ		dded	ed
ede	fddZ
dee de	de	fddZdee dee	ef fddZdedefddZdS )TNAPresentationz8Handles presentation of TNA analysis in multiple formatsc                 C   s   t d dS )z"Initialize the presentation systemz#TNA Presentation System initializedN)r>   r?   )rB   r   r   r   rD     s   zTNAPresentation.__init__analysis_resultrL   c                 C   s   g }|j D ]}||j|j|j|j|j|jd q|j|j	|j
|jt|jd|j||j|j|jt  tdd |j D tdd |j D | |j dd}td |S )	z
        Generate raw analysis output in JSON format

        Args:
            analysis_result: Complete analysis result

        Returns:
            Dictionary with raw analysis data
        r   r   r   r*   r+   r,      c                 S      g | ]	}|j d kr|qS organizational_relevantr+   rf   sr   r   r   rh         z9TNAPresentation.generate_raw_analysis.<locals>.<listcomp>c                 S   r   externalr   r   r   r   r   rh     r   )r#   r$   r%   analysis_timestamptotal_organizational_skillstotal_external_skillspriority_breakdown)r6   r3   r2   r1   r0   r/   r.   metadataz#Raw analysis generated successfully)r.   r   r   r   r   r*   r+   r,   r6   r3   r2   r1   roundr0   r/   r#   r$   r%   r	   now	isoformatru   _get_priority_breakdownr>   r?   )rB   r   skills_jsonrg   raw_analysisr   r   r   generate_raw_analysis  s8   






z%TNAPresentation.generate_raw_analysisNoffline_coursesonline_coursesc              	   C   s  dd |j D }dd |j D }dd |j D }dd |j D }dd |j D }dd |j D }	t d}
d	g d
|j d|j d|j d|j d|j  d| 	|| d d| 	|d dddd || dd D  dddd |dd D  dddd |dd D  dt
ddt||  d t||  d!dd"d || dd D  d#dd$d |dd D  d%|j  d&|
 d'|jrd(nd) d*t
dd+}td, |S )-a[  
        Generate professional TNA report for organization admins

        Args:
            analysis_result: Complete analysis result
            offline_courses: List of recommended offline courses
            online_courses: List of recommended online courses

        Returns:
            Formatted string with professional TNA report
        c                 S   r   r   r   r   r   r   r   rh     r   zCTNAPresentation.generate_strategic_presentation.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   rh     r   c                 S   r   )department_existingr   r   r   r   r   rh      r   c                 S   r   )Highr*   r   r   r   r   rh     r   c                 S   r   )Mediumr   r   r   r   r   rh     r   c                 S   r   )Lowr   r   r   r   r   rh     r   z	%B %d, %Yr   z
            Hello z',

            We noticed you shared: "u:   ". That’s a great growth mindset! Wanting to improve in u    shows real initiative.

            Here’s what we’ve analyzed and suggest for you:

            ━━━━━━━━━━━━━━━━━━━━━━━
            What You Need to Grow in ux   
            ━━━━━━━━━━━━━━━━━━━━━━━

            To really level up your z skills, we identified a combination of organizational skills you already have access to, plus some external skills that will give you an extra edge.

            Core Organizational Skills You Can Start With:
            organizationalu   

            These are skills already available internally through your organization’s resources. It’s like already having some tools in your toolbox!

            High-Value External Skills That Unlock the Next Level:
            r   u  

            These are the more advanced or specialized areas where external training, certifications, or hands-on projects could make a big difference.

            ━━━━━━━━━━━━━━━━━━━━━━━
            Prioritized Skill Recommendations
            ━━━━━━━━━━━━━━━━━━━━━━━

            Based on your profile and our analysis, here’s a practical order to focus on:

            1️ Most Important – Start Here:
            rq   c                 S   r   r   r   r   r   r   r   rh   &  r   N   u   

            Why? You already have access to resources for these. Quick wins, low setup time, high ROI.

            2️ Secondary Focus – Build Deeper Expertise:
            c                 S   r   r   r   r   r   r   r   rh   +  r   u   

            These are high-impact but need external support or new learning paths.

            3️ Bonus Round – Become Truly Unstoppable:
            c                 S   r   r   r   r   r   r   r   rh   0  r      u  

            Once you’ve mastered the core and secondary skills, these will push your capabilities into the top professional bracket.

            ━━━━━━━━━━━━━━━━━━━━━━━
            Your Current Capability Assessment
            ━━━━━━━━━━━━━━━━━━━━━━━

            - Skill Match with Organization: z.1fz'%
            - Existing Skills Found: uH   

            Good news — you already have a solid foundation! Having uJ   relevant skills puts you one step ahead.

            ━━━━━━━━━━━━━━━━━━━━━━━
            Suggested Learning Path
            ━━━━━━━━━━━━━━━━━━━━━━━

            Phase 1 (0–3 Months): Strengthen Existing Skills
            - Focus on c                 S   r   r   r   r   r   r   r   rh   B  r   u   
            - Use internal training programs
            - Regular check-ins to track progress

            Phase 2 (3–6 Months): Expand with External Skills
            - Focus on c                 S   r   r   r   r   r   r   r   rh   G  r   u  
            - Plan for external courses, certifications, or mentorship
            - Budget allocation and resource setup required

            ━━━━━━━━━━━━━━━━━━━━━━━
            Final Thoughts
            ━━━━━━━━━━━━━━━━━━━━━━━

            You’ve already taken the first step by identifying your goal. Now with this structured plan, you’re on the path to mastering uK   .

            Let’s keep the momentum going!

            Generated on: z"
            Analysis Confidence: r   r   z#
            Resource Utilization: u8   %

            — TNA v2.0 Insights Engine
            z-Strategic presentation generated successfully)r.   r	   r   strftimerk   r$   r#   r3   r   _format_skill_sectionorg_percentageru   r6   r>   r?   )rB   r   r   r   
org_skills
ext_skillsdept_skillshigh_prioritymedium_prioritylow_prioritycurrent_datestrategic_reportr   r   r   generate_strategic_presentation  s`   

#(0

1
3:?GKLM
Tz/TNAPresentation.generate_strategic_presentationr!   section_typec              	   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   2d.  (rd   rc   )	enumerater   r   r   rk   )rB   r!   r
  formatted_skillsirg   r   r   r   r   _  s   $
z%TNAPresentation._format_skill_sectionc                 C   s6   dddd}|D ]}|j |v r||j   d7  < q|S )z#Get breakdown of skills by priorityr   )r   r   r   r   r   )rB   r!   	breakdownrg   r   r   r   r   j  s   
z'TNAPresentation._get_priority_breakdownc                 C   s   |  || |dS )z
        Generate both raw and strategic formats

        Args:
            analysis_result: Complete analysis result

        Returns:
            Dictionary containing both formats
        r   strategic_presentation)r   r	  )rB   r   r   r   r   generate_both_formatsr  s   z%TNAPresentation.generate_both_formats)NN)r   r   r   r   rD   r5   r   r   r   r   r	  r)   r   r   r   r  r   r   r   r   r     s     -
pr   c                	   @   s   e Zd ZdZd!defddZdedefdd	Zd
e	de
dee defddZd
e	de
dee defddZdede	fddZdedefddZdedefddZdedefddZdedefddZd"dededeeef fddZd S )#SkillAnalysisSystemzCMain Skill Analysis System with enhanced specificity-aware approachr9   r:   c                 C   s.   t || _t | _t | _d| _td dS )z$Initialize the skill analysis system   z<Enhanced Specificity-Aware Skill Analysis System initializedN)	r8   skill_enginer   skill_matcherr   	presentermin_skills_targetr>   r?   )rB   r:   r   r   r   rD     s
   
zSkillAnalysisSystem.__init__request_datarL   c                 C   s   z9|  |}| j|j|jpd}| j||j}|jr2|j dkr2t|j	dkr2| 
|||W S | |||W S  tyb } ztd|  tg dt| dddd	d
W  Y d}~S d}~ww )z
        Main method to analyze skills using enhanced specificity-aware approach

        Args:
            request_data: Dictionary containing all necessary data

        Returns:
            SkillAnalysisResponse with recommendations
        rR   nullr   zError in skill analysis: zError in analysis:         r   ErrorUnknownr.   r/   r0   r1   r2   r3   N)_parse_requestr  rb   r#   r%   rp   r'   r   ru   r&   _handle_case_1_improved_handle_case_2_improvedr@   r>   rA   r-   r   )rB   r  requestra   relevant_org_skillsrC   r   r   r   analyze_skills  s6   

z"SkillAnalysisSystem.analyze_skillsr$  ra   r%  c                 C   s  t d |d }|d }g }t }| jj|jdd}|D ].}	|	j|vrK|t|	j|	j	|	j
p/dddd	|	j d
tdd |jD  d ||	j q|D ])}
|
d |vrw|t|
d |
d dddd| d|  dd ||
d  qNt|| jk r| jt| }dd |D }| j|j|||}t|D ]\}}|td| |dddd|  d| dd q|jrt|t|j nd}t|d| j d|j d | d| d!t| d"	|t|d| j d#|d$S )%zq
        Handle Case 1 with enhanced specificity-aware approach: Department found AND employee count > 3
        zFApplying Case 1 (Enhanced): Department found with sufficient employeesrW   rX   r   )r   Intermediater   r   zUnder-covered in department: z employees out of c                 S   r   r   r   r   r   r   r   rh     r   z?SkillAnalysisSystem._handle_case_1_improved.<locals>.<listcomp>r   r   r   r   r   Relevant to  field (% level) and available in organizationc                 S   r   r   r   rf   recr   r   r   rh     r   (#  Beginnerr   r   	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 employeesr   )r>   r?   setr  r   r&   r   r   r)   r   r   r   r   addr   ru   r  r  r   r#   r  r-   r%   )rB   r$  ra   r%  r3   rX   recommendationsused_skill_idsunder_covered_dept_skills
dept_skillr   r   existing_skill_namesexternal_skillsr  	ext_skilldept_coverager   r   r   r"    sx   

 

"z+SkillAnalysisSystem._handle_case_1_improvedc                 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	
|j||
|	}t|D ]\}}|td| |dddd|  d| dd qat|d| j d| d
| dt| ddt|d| j d|dS )uv   
        Handle Case 2 with enhanced specificity-aware approach: Department not found OR employee count ≤ 3
        zJApplying Case 2 (Enhanced): Department not found or insufficient employeesrW   rX   r   r   r'  r   r   r(  r)  r*  r   c                 S   r   r   r   r+  r   r   r   rh   '  r   z?SkillAnalysisSystem._handle_case_2_improved.<locals>.<listcomp>r-  r.  r   r   r/  r0  z to fill capability gapNzEnhanced general analysis for r1  r2  r  zACase 2 (Enhanced): Department not found or insufficient employeesr   )r>   r?   r3  r   r)   r   r4  ru   r  r  r   r#   r  r-   )rB   r$  ra   r%  r3   rX   r5  r6  r   r   r9  r:  r  r;  r   r   r   r#  
  sV   

	z+SkillAnalysisSystem._handle_case_2_improvedc              
   C   st   g }d|v r"|d D ]}| t|d |d |d|dd q
t|d |d |d	 ||d
g |di dS )z3Parse request data into SkillAnalysisRequest objectr&   r   r   r   r   r   r   r   r   r#   r$   r%   r'   r(   r#   r$   r%   r&   r'   r(   )r   r   r   r"   )rB   r  r&   
skill_datar   r   r   r!  D  s"   


z"SkillAnalysisSystem._parse_request	json_datac                 C   sT  zt |}|dd}|dd}|dd}|dg }|dg }d}|r<dd |D }	d	d
|	dd  }d}
|rSdd |D }dd
|dd  }
d| d|pZd d| d|
 d	}| jjt|dg}| j| |j	
 }zh|d}|dd }|dkr||kr||| }t |}g }d}|dg D ]$}|||ddd|dd |d d!|d"dd# |d7 }qd$|d%d&||d'd(d)t|d*d+W W S td, t jtfy } ztd-|  | |W  Y d}~W S d}~ww  ty) } ztd.|  d/t|g d0W  Y d}~S d}~ww )1z
        OPTIMIZED: Single LLM call for complete skill analysis (much faster)

        Args:
            json_data: JSON string with request data

        Returns:
            Dictionary with response data
        r#   r   r$   r%   r&   r'   c                 S   "   g | ]}| d r| d dqS r   r   r   r   r   r   r   rh   q     " zESkillAnalysisSystem.process_optimized_single_call.<locals>.<listcomp>zDepartment skills: rq   N   c                 S   rA  rB  r   r   r   r   r   rh   v  rC  zAvailable skills:    z>Analyze this training need and recommend skills.

USER QUERY: z
DEPARTMENT: rR   rc   aV  

Provide a JSON response with:
{
  "field": "identified field/domain",
  "skills": [
    {"name": "skill name", "source": "department|organizational|external", "priority": "high|medium|low", "reason": "brief justification"}
  ],
  "summary": "brief analysis summary"
}

Focus on practical, relevant skills. Return exactly 8-12 skills total.
rP   {}r   r   i  r!   r   r'  r*   mediumr+   r   reasonr   Tr   zGeneral SkillssummaryzSkills analysis completedr   zOptimized Single Call Analysisr6   r3   r.   r/   r0   r1   r2   zNo JSON found in responsez#JSON parse failed, using fallback: zOptimized processing error: Fr6   rA   r.   )r   r   r   rk   r  r<   r]   r   rK   rQ   r   findrfindr   titleru   
ValueErrorJSONDecodeErrorr>   warning_fallback_skill_analysisr@   rA   r   )rB   r@  r  r#   r$   r%   r&   r'   dept_skills_textdept_skill_namesorg_skills_textorg_skill_namespromptrJ   r   
json_startjson_endjson_strparsedr5  r   r?  rC   r   r   r   process_optimized_single_callZ  s   












z1SkillAnalysisSystem.process_optimized_single_callc              
      s"  | dd  | dd}t fdddD rd}nt fddd	D r*d
}nt fdddD r8d}nd}ddddddddddddddddddddddddddddd dg}g }d!}|D ]}|||d" d#|d$ |d% |d& d' |d(7 }qfd)||d*| d+d,t|d-d.S )/z&Fallback skill analysis when LLM failsr#   r   r%   c                 3   r   r   r   rf   wordr#   r   r   r     r   z?SkillAnalysisSystem._fallback_skill_analysis.<locals>.<genexpr>)r   r   
javascriptcodingprogrammingzSoftware Developmentc                 3   r   r   r   r^  r`  r   r   r     r   )sales	marketingcustomerzBusiness Developmentc                 3   r   r   r   r^  r`  r   r   r     r   )
management
leadershipteam
ManagementzGeneral Professional SkillszCommunication Skillsr   r   zEssential for all roles)r   r+   r*   rI  zProblem SolvingzCore competencyzTime Managementr   zProductivity skillzTeam CollaborationzTeam effectivenessAdaptabilityr   r   zFuture-ready skillzDigital LiteracyzModern workplace requirementi  r   r'  r*   r+   rI  r   r   TzBasic analysis for z fieldg333333?zFallback AnalysisrK  )r   r   r   r   ru   )rB   r  r%   r   basic_skillsr5  r   rg   r   r`  r   rS    sH   	

z,SkillAnalysisSystem._fallback_skill_analysisc              
   C   s  z>d| j _t|}| |}g }|jD ]}||j|j|j	|j
|j|jd qd|j||jt|jd|j|j| j jdW S  tjyb } ztd|  dd| g d	W  Y d
}~S d
}~w ty } ztd|  dt|g d	W  Y d
}~S d
}~ww )z
        Process JSON request and return JSON response (Raw format only)

        Args:
            json_data: JSON string with request data

        Returns:
            Dictionary with response data
        r   r   Tr   )r6   r3   r.   r/   r0   r1   r2   token_countJSON decode error: FInvalid JSON format: rL  NProcessing error: )r  r=   r   r   r&  r.   r   r   r   r   r*   r+   r,   r3   r/   r   r0   r1   r2   rQ  r>   rA   r@   r   )rB   r@  r  rJ   recommendations_jsonr,  rC   r   r   r   process_json_request  sL   






z(SkillAnalysisSystem.process_json_requestc                 C   s  z2t |}| |}td|j|j|j|j|j|j	|d |d |d d
}| j
|}td |W S  t jy\ } ztd|  dd	| g d
d| dW  Y d}~S d}~w ty } ztd|  dt|g d
dt| dW  Y d}~S d}~ww )z
        Process JSON request and return BOTH raw and strategic formats
        
        Args:
            json_data: JSON string with request data
            
        Returns:
            Dictionary with both presentation formats
        Tr#   r$   r%   
r6   r3   r2   r1   r0   r/   r.   r#   r$   r%   z0Both presentation formats generated successfullyrn  Fro  rL  zError: Invalid JSON format - r  Nrp  zError: )r   r   r&  r5   r3   r2   r1   r0   r/   r.   r  r  r>   r?   rQ  rA   r@   r   )rB   r@  r  analysis_responser   both_formatsrC   r   r   r   process_with_both_formats+  sJ   



z-SkillAnalysisSystem.process_with_both_formatstna_analysisfilename_prefixc                 C   sj  zt |}| |}td|j|j|j|j|j|j	|d |d |d d
}t
 d}| j|}| d| d}t|d	d
d}	t j|d |	ddd W d   n1 sWw   Y  | d| d}
t|
d	d
d}	|	|d  W d   n1 s}w   Y  td| d|
  ||
ddW S  ty } ztd|  dt|dW  Y d}~S d}~ww )a  
        Process analysis and save both formats to files
        
        Args:
            json_data: JSON string with request data
            filename_prefix: Prefix for saved files
            
        Returns:
            Dictionary with file paths
        Tr#   r$   r%   rs  z%Y%m%d_%H%M%S_raw_z.jsonwzutf-8)encodingr   r   F)indentensure_asciiN_strategic_z.txtr  zAnalysis saved to z and )raw_filestrategic_filer6   zError saving analysis: )r6   rA   )r   r   r&  r5   r3   r2   r1   r0   r/   r.   r	   r   r   r  r  opendumpwriter>   r?   r@   rA   r   )rB   r@  rx  r  rt  r   	timestampru  raw_filenamefstrategic_filenamerC   r   r   r   save_analysis_reportb  sJ   

z(SkillAnalysisSystem.save_analysis_reportNr   )rw  )r   r   r   r   r   rD   r   r-   r&  r"   r   r   r"  r#  r!  r]  rS  rr  rv  r  r   r   r   r   r    s0    	.
O
:j07$7r  c            
      C   s  t  } ddddddddd	d
dddgdddddddddddddddddddddddddddd d!dd"d#dgd$d%d&d&d'g d(d)gid*}d+dddddddd	d
dddgddddd,ddd-ddddddddddd d.dd"d/dgd$d%d0d1d'g d2d)gid*}td3 td4 td3 td5 td6 td7 | t|}td8|d9   td:|d;   td<|d=   td> t|d? d@D ]\}}t| dA|dB  dC|dD  dE|dF   qtd5 tdG td7 | t|}td8|d9   td:|d;   td<|d=   td> t|d? d@D ]\}}t| dA|dB  dC|dD  dE|dF   q)tdH tdI td3 tdJ t|}| |}|dK }	t|	 dLS )Mz:Example usage of the Enhanced Specificity-Aware TNA Systemz'Want to improve my Python skill abilityAscent	Developerx   Pythonr'  r   r=  i  zEmotional IntelligenceAdvancedr   il  znegotiation and closure)r   r   im  zmarket analysisin  zproduct knowledgey   
JavaScriptz   React{   zNode.js|   HTML}   CSS~   SQL   Git   Docker373zJava Courser   )r   ra  rb  )courseIdr   r   r    r!   r>  z!Want to improve my Angular skills
TypeScriptAngularzVue.jsRxJSzAngular Advanced CoursezAdvanced Angular Development)r   
typescriptrxjszP================================================================================z3ENHANCED SPECIFICITY-AWARE TNA SYSTEM DEMONSTRATIONz3
==================================================z0TEST 1: GENERAL QUERY - 'improve python ability'z2==================================================zField Identified: r3   zTotal Skills: r1   z	Summary: r/   z
Top 5 Recommended Skills:r.   r   r  r   r  r+   z) - r,   z8TEST 2: HIGHLY SPECIFIC QUERY - 'improve Angular skills'zQ
================================================================================zmENHANCEMENT SUCCESS: Different queries now produce different, contextually appropriate skill recommendations!	Strategicr  N)r  printrr  r   dumpsr  rv  )
skill_systemsample_request_generalsample_request_specificgeneral_resultr  rg   specific_resultr@  resultr  r   r   r   main  s   -),.

r  __main__)%r   loggingtypingr   r   r   r   dataclassesr   difflibr   r   collectionsr   r	   langchain_ollamar
   langchain_core.promptsr   langchain_core.messagesr   basicConfigINFO	getLoggerr   r>   r   r   r"   r)   r-   r5   r8   r   r   r  r  r   r   r   r   <module>   sV    
			    R  F    " 
