o
    th                     @   s   d dl Z d dlZd dlmZmZ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G dd dZdd Zedkree  dS dS )    N)DictListOptional)	dataclass)
ChatOllama)PromptTemplate)HumanMessage)levelc                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )Coursez!Data class for course information	course_idnameshort_descriptiondescriptionskillN)__name__
__module____qualname____doc__str__annotations__ r   r   E/var/www/eduai.edurigo.com/doc_train/edurigo_ai/TNA/testing/tester.pyr
      s   
 r
   c                   @   s2   e Zd ZU dZeed< eed< eed< eed< dS )CourseMatchz(Data class for course match with scoringr   course_namematch_percentagereasonN)r   r   r   r   r   r   intr   r   r   r   r      s   
 r   c                   @   sF   e Zd ZU dZeed< eed< eed< ee ed< eed< eed< dS )	DomainFilterResponsez.Data class for domain-aware filtering responsedomainfield_prompttotal_courses_inputcourse_matchestotal_matching_coursesprocessing_summaryN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r      s   
 r   c                   @   s   e Zd ZdZd#dedefddZdee d	e	ee ef 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d	ee f
ddZdee d	efddZdedee d	ee fddZded	efddZdedee d	ee fddZded	efd d!Zd"S )$DomainAwareCourseFilterz2Domain-aware course filtering using LLM in batches
gemma3:12b   
model_name
batch_sizec              
   C   sb   zt |dddd| _|| _td| d| d W d	S  ty0 } z	td|   d	}~ww )
z)Initialize the domain-aware course filteri  g?i  )modelnum_ctxtemperaturenum_predictz3Domain-Aware Course Filter initialized with model: z (Batch size: )z1Failed to initialize Domain-Aware Course Filter: N)r   llmr(   loggerinfo	Exceptionerror)selfr'   r(   er   r   r   __init__+   s   z DomainAwareCourseFilter.__init__coursesreturnc                 C   s   t dt| d |dfS )z*Keep all courses - no aggressive filteringz$Using all courses without cleaning:  coursesr   )r/   r0   len)r3   r6   r   r   r   clean_course_data:   s   z)DomainAwareCourseFilter.clean_course_datar   r   c                 C   s  zt |}| |\}}g }g }t || j d | j }	tdt || jD ][}
||
|
| j  }|
| j d }td| d|	 d|
d  dt|
| j t |  | ||||}|| |	d| dt | d	t | d
 td| dt | d q%|j
dd dd d|	 dd| }t||||t ||d}td| dt | d
 |W S  ty } ztd|  t||t |g ddt| dW  Y d}~S d}~ww )a  
        Main method: Filter courses using domain-aware LLM analysis in batches
        
        Args:
            domain: The identified domain (e.g., "Technology", "Business", "Healthcare")
            field_prompt: The specific field (e.g., "Frontend Development", "Sales Training")
            courses: List of all courses to filter
            
        Returns:
            DomainFilterResponse with matched courses and details
           r   zProcessing batch /z
: courses -Batch z: z matches from r8   z
 results: z matchesc                 S   s   | j S N)r   )xr   r   r   <lambda>g   s    zBDomainAwareCourseFilter.filter_courses_by_domain.<locals>.<lambda>T)keyreversez
Processed z
 batches. z | )r   r   r    r!   r"   r#   zFinal results: u    → z!Error in domain-aware filtering: zError in filtering: N)r9   r:   r(   ranger/   r0   min_analyze_batch_with_domainextendappendsortjoinr   r1   r2   r   )r3   r   r   r6   original_countcleaned_coursesremoved_countall_matchesbatch_summariestotal_batchesibatch	batch_numbatch_matchesr#   responser4   r   r   r   filter_courses_by_domainA   sL   6
&	z0DomainAwareCourseFilter.filter_courses_by_domainrR   rS   c              
   C   s   |  |}tg ddd}z+|j||||d}| jt|dg}| |j|}	t	d| dt
|	 d |	W S  tyW }
 ztd| d	|
  g W  Y d
}
~
S d
}
~
ww )z8Analyze a batch of courses using LLM with domain context)r   r   courses_textrS   a  
            You are an EXPERT course curator specializing in the {domain} domain.
            
            DOMAIN: {domain}
            TARGET FIELD: {field_prompt}
            BATCH: {batch_num}
            
            TASK: Analyze each course below and determine if it's relevant for someone seeking "{field_prompt}" skills in the {domain} domain.
            
            EVALUATION CRITERIA:
            1. Course content directly relates to {field_prompt}
            2. Skills taught are applicable in {domain} field
            3. Course would help someone working in or entering {field_prompt}
            4. Content is professional-level, not basic computer literacy
            
            SCORING GUIDE:
            - 90-100%: Perfect match, essential for {field_prompt}
            - 80-89%: Very relevant, directly applicable
            - 70-79%: Somewhat relevant, useful supporting skills
            - Below 70%: Not relevant enough to recommend
            
            COURSES TO ANALYZE:
            {courses_text}
            
            RESPONSE FORMAT: Return ONLY a JSON array with this exact structure:
            [
                {{
                    "course_id": "123",
                    "course_name": "Exact Course Name",
                    "match_percentage": 95,
                    "reason": "Specific reason why this course matches {field_prompt}"
                }}
            ]
            
            IMPORTANT: 
            - Only include courses with match_percentage >= 70
            - If no courses meet the criteria, return an empty array: []
            - Be selective and strict in your evaluation
            - Ensure course_name matches exactly as provided
            )input_variablestemplate)contentr>   z: LLM identified z matching courseszError in batch z LLM analysis: N)_format_batch_for_llmr   formatr.   invoker   _parse_batch_responserZ   r/   r0   r9   r1   r2   )r3   r   r   rR   rS   rW   prompt_templateformatted_promptrU   matchesr4   r   r   r   rF      s*   
,z2DomainAwareCourseFilter._analyze_batch_with_domainc                 C   s   g }|D ]A}d|j  d}|d|j d7 }|jr(|j|jkr(|d|j d7 }|jr4|d|j d7 }|jr@|d|j d7 }|| qdd| d S )	z'Format a batch of courses for LLM inputzID: 
zName: zShort Description: zDescription: zSkills: z3
==================================================z2==================================================)r   r   r   r   r   rH   rJ   )r3   rR   courses_formattedcoursecourse_infor   r   r   r[      s   z-DomainAwareCourseFilter._format_batch_for_llmresponse_contentoriginal_batchc           
   
   C   s  zDddl }|d||j}|r>t| }g }|D ] }| |r:tt|d |d t	|d |d d}|
| q|W S | ||W S  tjye }	 ztd	|	  | ||W  Y d}	~	S d}	~	w ty }	 ztd
|	  g W  Y d}	~	S d}	~	ww )z,Parse LLM response to extract course matchesr   Nz\[.*\]r   r   r   r   r   r   r   r   zJSON parsing failed: zError parsing batch response: )researchDOTALLjsonloadsgroup_validate_match_itemr   r   r   rH   _fallback_parse_batch_responseJSONDecodeErrorr/   warningr1   r2   )
r3   rf   rg   ri   
json_matchparsed_responsera   itemmatchr4   r   r   r   r^      s6   



z-DomainAwareCourseFilter._parse_batch_responseru   c              	   C   sb   g d}|D ]	}||vr dS qzt |d }|dk s|dkr"W dS W dS  ttfy0   Y dS w )z2Validate that a match item has all required fieldsrh   Fr   F   d   T)r   
ValueError	TypeError)r3   ru   required_fieldsfield
percentager   r   r   ro     s   z,DomainAwareCourseFilter._validate_match_itemc              	      sL   g }|D ]}|j  v r#t fdddD r#|t|j |jddd q|S )z+Fallback parsing when JSON extraction failsc                 3   s    | ]	}|   v V  qd S r?   )lower).0positiverf   r   r   	<genexpr>  s
    

zIDomainAwareCourseFilter._fallback_parse_batch_response.<locals>.<genexpr>)relevantrv   goodsuitable	recommendK   z5Identified as relevant through fallback text analysisrh   )r   anyrH   r   r   )r3   rf   rg   ra   rd   r   r   r   rp     s   z6DomainAwareCourseFilter._fallback_parse_batch_response	json_datac              
   C   s  zzt |}|dd}|dd}|r|sddg dW S |dg }g }|D ]&}tt|dd|d	d|d
d|dd|ddd}|| q'| |||}	g }
|	jD ]}|
|j|j	|j
|jd qZd|	j|	j|	j|
|	j|	jdW S  t jy } 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
        
        Expected input format:
        {
            "domain": "Technology",
            "field_prompt": "Frontend Development",
            "courses": [...]
        }
        r    r   Fz)Both domain and field_prompt are required)successr2   r!   r6   r   r   course_short_descriptioncourse_descriptionr   )r   r   r   r   r   rh   T)r   r   r   r    r!   r"   r#   zJSON decode error: zInvalid JSON format: NzProcessing error: )rl   rm   getr
   r   rH   rV   r!   r   r   r   r   r   r   r    r"   r#   rq   r/   r2   r1   )r3   r   request_datar   r   courses_datar6   course_datard   filter_responsecourse_matches_jsonrv   r4   r   r   r   process_json_request(  sh   







z,DomainAwareCourseFilter.process_json_requestN)r%   r&   )r   r   r   r   r   r   r5   r   r
   tupler:   r   rV   r   rF   r[   r^   dictboolro   rp   r   r   r   r   r   r   r$   (   s    "&BE$r$   c                  C   s:  g ddddg dddddg dd	d
d
dg dddddg dddddg dddddg dddddg dddddg dddddg 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+d,d-dg dd.d/d/dg dd0d1d1dg dd2d3d3dg dd4d5d6dg dd7d8d8d9g dd:d;d<dg dd=d>d?dg dd@dAdAdg ddBdCdCdg ddDdEdFdg ddGdHdHdg ddIdJdKdg ddLdMdMdg ddNdOdOdg ddPdQdRdg ddSdTdUdg ddVdWdWdXdYd dZd"d[d d\d"gdd]d^d^dg dd_d`dadg ddbdcdcdg ddddedfdg ddgdhdhdg ddidjdjdg ddkdldWdg ddmdndndg ddodpdhdg ddqdrdjdg ddsdtdtdg ddudvdvdg ddwdxdxdg ddydzdzdg dd{d|d|dg dd}d~ddg dddddg dddddg ddddKdg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg ddddKdg dddddg dddddg dddddg dddddg ddddKdg ddddKdg ddddKdg ddddKdg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg ddddzdg dddddg dddddg dddddg ddddddd dd"gdddddg ddddddd dd"dd dd"dddd"gdddddg ddddKdg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg ddddddd dd"gddd ddg dddddg ddddddd dd"gdddddg ddd	d	dg dd
ddKdg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dddddg dd d!d"dg dd#d$d$dg dd%d&d&d'g dd(d)d)dg dd*d+d+dg dd,d-d-dd d.d/d"gdd0d1d2dg dd3d4d4dd d d/d"d5d.d6d"gdd7d8d8dg dd9d:d:dg dd;d<d<d<g dd=d>d>dg dd?d@d@d@g ddAdBd@d@g ddCdDdDdDg ddEdFd@d@g ddGdHd@d@g ddIdJdKdg ddLdMdKdg ddNdOdOdg ddPdQdRddSd dTd"gddUdVdWddd dXd"gddYdZdZdg dd[d\d\dg dd]d^d\dg dd_d`d`ddd dXd"gddadbdcdg ddddedcdg ddfdgdOdg ddhdidRddSd dTd"gddjdkdWddd dXd"gddldmdWddd dXd"gddndod`ddd dXd"gddpdqdqdg ddrdsdsdg ddtdududg ddvdwdudg ddxdydydg ddzd{d{dg d} d|d}d~ddd~d|dd~g}t d tdd}|D ]}t dd  t d|d  d|d   t d  |d |d | d}|t|}t d|d   t d t d|d   t d|d   t d |d D ])}t d|d   t d|d  d t d|d   t   qR|d st d|d   t d|d   qdS (  z&Test the domain-aware filtering system33zCurrent Affairsr   )r   r   r   r   skills35zFI-Lead A leadership Development Intervention for Emerging Markets teamzGLeadership Development intervention for emerging markets team at EmcurezI-Lead Program was designed to support the Emerging Markets team Leaders at Emcure Pharmaceuticals to develop specific leadership competencies and to take their performance to the next level in achieve desired business goal.43z)Python Programming for Complete Beginners49zSales MasterClassz!A complete Sales Training ProgramzToday's selling environment is tough, and only getting tougher. The old tactics are no longer working, and the current economy is only making selling more difficult. You need sales tactics and strategies that work now and work fast.59zCodeigntier Beginner86zJava For BeginnerszLorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.360zScorm Set-1zSet- 1367Scorm374zProduction test 9-6-22zProduction Test408zCourse for Learning pathzCourse GFor Learning path2851zManager Level 1)skill_id
skill_type
skill_name284Wicketkipper283Boller426zLearn Spoken Englishz!Learn to speak English in 90 dayszThis is a 60 days self paced course. It consists of more than 3 hours of video lectures, more than 2 hours of reading material and hundreds of interesting questions.476	Inductiontraining485zNew Scorm Course496zScorm Course Test503zScorm Server Test505zScorm Posh CoursezInfoSec Posh513zScorm Info SecurityzMiami-Dade County's partnership with OBE Power is providing electric vehicle (EV) charging as a service to parking patrons at key locations throughout the County's public garages in Downtown Miami.536zassesment test	assesment544zOnly Classic quizquiz554z$Course for testing direct coure 100%562zNew Assessment for Infobeans565zVideo testingvideo570zCultural Pillars599zAll resoursesAll616z3CODE OF CONDUCT, ANTI-BRIBERY AND CORRUPTION POLICY650zISO Test656z/New Course For Production build testing 20-7-23zProduction Build657zReminder Test For CourseReminder673zDeveloping Digital EtiquettezIn today's digital world, the way we communicate online matters more than ever. Developing Digital Etiquette is designed to help you navigate virtual interactions with professionalism, clarity, and respect.1544zDigital Marketing Strategy1540zRobotics Engineering683zStorage System684zModule Lock Testz
Modul Test700zCourse Lock710zCourse Flow Check Same As KCKC711zAscent UK B2B Test712zAscent USA B2B Test715z'Developing Digital Etiquette- Cycle - 1718zMaterial Handeling Equipments725z'Advance - Ascent UK B2B Test- Cycle - 1726zAdvance - Ascent USA B2B Test730zCommunicating with impact733zTest Stream Upload file735Intrapreneurship765r
   790zAdvance Level Communication795zTrainer create a coursezTrainer course805zCoad of Conduct 23-24z23 -24810zPOSH and INFO SECKINFO845zAll Content851zSection ExportSection852zCourse New create test857zDeveloping People at Workz#Learn how to develop people at workzPeople feel valued when the organizations they work for care for their development. This course is designed to give you a lens through which you can assess the developmental needs of your Team members.900zDock Ack TestDock914zPosh for Bloom (neha)Bloom915zManager Course- MangeshMangesh936zMechanical Demo977zTest course 15-5-2024zTest course 14/05/241000zThe Five Dysfunctions of a team1017zThe Art of CoachingzQA step by step approach to initiate coaching conversations with your Team Membersa  This course aims to introduce the Art of Coaching to managers and leaders who wish to take that extra step to develop their Team Members. Coaching is often misunderstood because we witness it from a perspective where the coach is pushing and telling people what to do.1026zAll resourses- Cycle - 2u   कार्यस्थल में महिलाओं के यौन उत्पीड़न का निवारण1048
Assignment1059z
POSH Hindi1081ExtcDemo1084zLearning Path course 1Lp11085zElectrical Engineering1090zElectrical Vehical1101
Mechanical1131zCommunication Skill1132zDemo Course1158zDis Function51182zReport Test1188zEmail Etiquitee Scorm Web1189zStress Management1248z"Course reference matrial acknoldge1278zNICPL & HR Induction1288zAssignment TestTest1293zCoursera Course1298zAssignment One1304zBGSS Demo Course 1one1305zTime Spent course Onez
Time spent1350981Ancibel1360z!Time Spent course One - Cycle - 11376zCleanmax RequirementzMultimodule Support282Batsman9723Linux1377zMultiple Scorm in one module1378zAll resourses for testing1388zManager feed BackzManager Feed Back1389zAdvance Feedback Test1411z Advance Feedback Test- Cycle - 31415z	BGSS Demo1424z+Advance Feedback Test- Cycle - 3- Cycle - 11426zMidland DemozEdurigo empowers managers with powerful tools to seamlessly track their team's progress. Tabs like Courses, Programs, Assessments, and StoriGo provide instant visibility into completion statuses.1435zAdvance Feedback Testing1438z#Advance Feedback Testing- Cycle - 21446z.Advance Feedback Testing- Cycle - 2- Cycle - 11447zWeeak ly Course1455zAssignment Test- Cycle - 11456zHR Course 1Hr1457zupload assignment course test1458zAssignment Test-for new device1469z(upload assignment course test- Cycle - 11476m11481zAll Content- Cycle - 11498z!Frontend Development - HTML & CSSz#Introduction to HTML and CSS basics1499z!Frontend Development - JavaScriptzIntroduction to JavaScript (JS)1500zFrontend Development - ReactJszIntroduction to ReactJs1505v11510zAll resource coursezAll Resource course1562zScorm 1 vedakzScorm 11572ziframe video15771591z
Video Testv1597zVijaysales Demo1616z Handling Difficult Conversationsz=Track and calculate average learning hours per user annually.1628zMidland Use Case1636zHR Induction Course1649zDemo Nirmal2zActive Listening1991zANgular BasicszANgular Basicss1668zfunctional demo1342zBig Data Analysis1669zCourse test without badges1674zLock seeak bar1675zhide seek bar testing1676zTwo Bagje Only1677z
badge test1678zbadge test- Cycle - 11679zbadge test 21680zbadge test- Cycle - 21681z badge test- Cycle - 2- Cycle - 11682zAssignment Flow testzAssignment flow test1683zAssignment test1685zSingle Badge With Single roul1686z1Single Badge: Completion by first set of learnersz#Completion by first set of learners1599zBlockchain Security Measures1687z/Single Badge : Score exceeds defined percentagez Score exceeds defined percentagezAccounting and Auditing1688zSingle Badge : With 2 Quiz1689z Completion before specified date1690z+Completion before specified date- Cycle - 11691z@3 Badge : Score exceeds defined percentage : diffrant percentage1692z,Single Badge With Multipal Roul Or conditionzSingle Badge With Multipal Roul1693z-Single Badge With Multipal Roul AND condition1694z)Single Badge With Single roul: API Change1695z>Single Badge: Completion by first set of learners : API Change1696z:Single Badge : Score exceeds defined percentage- Cycle - 21697zESingle Badge : Score exceeds defined percentage- Cycle - 2- Cycle - 11698zK3 Badge : Score exceeds defined percentage : diffrant percentage- Cycle - 11700zAll Resource1701zZero Point Course1702zNew One1703zNew One- Cycle - 11704zDecision Making1705zTime and Stress Management
Technologyz I want to improev my tech skills)r   r   BusinesszSales Trainingz'I want to improve only my python skillsz*=== TESTING DOMAIN-AWARE COURSE FILTER ===r&   )r(   rb   z<============================================================z	TESTING: r   z - r   )r   r   r6   u   ✅ SUCCESS: r   u   📊 STATS:z   Input courses: r    z   Final matches: r"   u   
🎯 COURSE MATCHES:r!   u      📋 r   z      Match: r   %z      Reason: r   z   No matches found for u   📝 Processing: r#   N)printr$   r   rl   dumps)test_courses
test_casesfilter_system	test_casetest_requestresultrv   r   r   r   test_domain_aware_filteringx  s8  	%,3:AX_fmt{   
        &  -  4  ;  B  I  P  W  i  p  w  ~                   "    )    0    7    >    E    L    S    Z    a    h    o    v    }                             !      (      /      6      =      D      K      R      Y      `      g      n      u      |                                                '        .        5        <        C        J        W        ^        u        |                                                            '          .          5          <          C          J          W          ^          e          r          y                                                                      $            +            2            9            @            G            N            U            \            c            p            y                                                       !              (              /              6              =              D              K              R              Y              `              m              z                               	                                                $                +                2                ?                L                Y                f                m                t                {                                   
                  
$


rh  __main__)rl   loggingtypingr   r   r   dataclassesr   langchain_ollamar   langchain.promptsr   langchain.schemar   basicConfigr   	getLoggerr   r/   r
   r   r   r$   rh  r   r   r   r   <module>   s>    
	  R         J
