o
    KiC                     @   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G dd dZdd Zedkr\e  dS dS )    N)DictListOptional)	dataclass)
ChatOllama)PromptTemplate)HumanMessage)levelc                   @   sv   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d< eed	< eed
< ee ed< eed< eed< dS )OnlineCourseRecommendationz+Data class for online course recommendationcourse_nameplatform
instructordurationskill_leveldescriptionurlpriceratingskills_coveredmatch_percentagerecommendation_reasonN)__name__
__module____qualname____doc__str__annotations__r   int r   r   7/var/www/eduai.edurigo.com/tna/staging/online_course.pyr
      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 )	OnlineCourseResponsez4Data class for online course recommendation responsedomainfield_prompttotal_recommendationscourse_recommendationssearch_summarysuccessN)
r   r   r   r   r   r   r   r   r
   boolr   r   r   r   r       s   
 r    c                	   @   s   e Zd ZdZddefddZdd Zdd	ed
ededefddZ	d	ed
edede
e fddZdede
e fddZdedefddZde
e fddZdedefddZdS ) OnlineCourseRecommendationSystemz-Online Course Recommendation System using LLM
gemma3:12b
model_namec              
   C   sZ   zt |dddd| _d| _td|  W dS  ty, } z	td|   d}~ww )	z2Initialize the online course recommendation systemi  g?i  )modelnum_ctxtemperaturenum_predictr   z<Online Course Recommendation System initialized with model: z:Failed to initialize Online Course Recommendation System: N)r   llmtotal_tokensloggerinfo	Exceptionerror)selfr*   er   r   r   __init__*   s   z)OnlineCourseRecommendationSystem.__init__c                 C   s.   t |d }t |d }|  j|| 7  _dS )zEAdd estimated token usage from LLM prompt and response to total count   N)lenr0   )r5   prompt_textresponse_contentprompt_tokensresponse_tokensr   r   r   
add_tokens9   s   z+OnlineCourseRecommendationSystem.add_tokens
   r!   r"   max_coursesreturnc                 C   s   z<t d| d|  | |||}t||t||dt| d| d| dt|dkd}t dt| d	 |W S  tye } zt d
|  t||dg dt| ddW  Y d}~S d}~ww )a{  
        Recommend online courses based on domain and field prompt

        Args:
            domain: The domain category (e.g., "Technology", "Business", "Healthcare")
            field_prompt: The specific field or skill area
            max_courses: Maximum number of courses to recommend

        Returns:
            OnlineCourseResponse with course recommendations
        z-Generating online course recommendations for  - z
Generated z# online course recommendations for z in z domainr   )r!   r"   r#   r$   r%   r&   z online course recommendationsz0Error generating online course recommendations: z"Error generating recommendations: FN)r1   r2    _generate_course_recommendationsr    r9   r3   r4   r   )r5   r!   r"   r@   recommendationsresponser6   r   r   r   recommend_online_courses@   s2   
	z9OnlineCourseRecommendationSystem.recommend_online_coursesc           	   
   C   s   t g ddd}z-|j|||d}| jt|dg}| ||j | |j}t	dt
| d |W S  tyQ } ztd|  g W  Y d}~S d}~ww )	z)Generate course recommendations using LLMr!   r"   r@   a
  
            You are an EXPERT online course curator and career advisor specializing in the {domain} domain.

            DOMAIN: {domain}
            TARGET FIELD/SKILL: {field_prompt}
            MAX COURSES: {max_courses}

            TASK: Recommend the BEST online courses available for someone who wants to learn "{field_prompt}" in the {domain} domain.

            COURSE SELECTION CRITERIA:
            1. High-quality, reputable platforms (Coursera, Udemy, edX, Pluralsight, LinkedIn Learning, etc.)
            2. Well-reviewed courses with good ratings
            3. Comprehensive coverage of {field_prompt}
            4. Mix of beginner to advanced levels
            5. Practical, hands-on learning approach
            6. Industry-relevant and up-to-date content

            PLATFORMS TO CONSIDER:
            - Coursera (University partnerships, certificates)
            - Udemy (Practical, affordable courses)
            - edX (Academic, high-quality content)
            - Pluralsight (Tech-focused, skill assessments)
            - LinkedIn Learning (Professional development)
            - Skillshare (Creative and business skills)
            - MasterClass (Expert-led courses)
            - Codecademy (Programming and tech)
            - Khan Academy (Fundamentals and academics)
            - FutureLearn (University partnerships)

            RESPONSE FORMAT: Return ONLY a JSON array with this exact structure:
            [
                {{
                    "course_name": "Complete Course Title",
                    "platform": "Platform Name",
                    "instructor": "Instructor Name or Institution",
                    "duration": "X hours/weeks",
                    "skill_level": "Beginner/Intermediate/Advanced",
                    "description": "Detailed course description covering what students will learn",
                    "url": "https://platform.com/course-url",
                    "price": "Free/Paid/$XX",
                    "rating": "4.5/5 stars",
                    "skills_covered": ["skill1", "skill2", "skill3"],
                    "match_percentage": 95,
                    "recommendation_reason": "Why this course is perfect for {field_prompt}"
                }}
            ]

            IMPORTANT GUIDELINES:
            - Provide realistic course information (avoid making up specific URLs)
            - Include a variety of skill levels and platforms
            - Ensure courses are directly relevant to {field_prompt}
            - Match percentage should reflect relevance (70-100%)
            - Include both free and paid options when possible
            - Focus on courses that are currently available and popular
            - Provide practical, actionable course recommendations
            )input_variablestemplate)contentzLLM generated z course recommendationsz Error in LLM course generation: N)r   formatr/   invoker   r>   rJ   _parse_course_responser1   r2   r9   r3   r4   )	r5   r!   r"   r@   prompt_templateformatted_promptrE   rD   r6   r   r   r   rC   j   s(   <zAOnlineCourseRecommendationSystem._generate_course_recommendationsr;   c           	      C   s<  zcddl }|d||j}|r_t| }g }|D ]8}| |rRt|d |d |d |d |d |d	 |d
d|d |d |d t	|d |d d}|
| q|jdd dd |W S |  W S  tjy } ztd|  |  W  Y d}~S d}~w ty } ztd|  g W  Y d}~S d}~ww )z4Parse LLM response to extract course recommendationsr   Nz\[.*\]r   r   r   r   r   r   r    r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   c                 S   s   | j S )N)r   )xr   r   r   <lambda>   s    zIOnlineCourseRecommendationSystem._parse_course_response.<locals>.<lambda>T)keyreversezJSON parsing failed: zError parsing course response: )researchDOTALLjsonloadsgroup_validate_course_itemr
   getr   appendsort _create_fallback_recommendationsJSONDecodeErrorr1   warningr3   r4   )	r5   r;   rV   
json_matchparsed_responserD   itemrecommendationr6   r   r   r   rM      sH   




z7OnlineCourseRecommendationSystem._parse_course_responsere   c              	   C   s   g d}|D ]}||vrt d|   dS qzt|d }|dk s'|dkr2t d|  W dS W n ttfyJ   t d|d  Y dS w t|d	 ts_t d
|d	  dS dS )z3Validate that a course item has all required fields)r   r   r   r   r   r   r   r   r   r   r   zMissing required field: Fr   F   d   zInvalid match percentage: z!Invalid match percentage format: r   zskills_covered must be a list: T)r1   rb   r   
ValueError	TypeErrorr]   
isinstancelist)r5   re   required_fieldsfield
percentager   r   r   r\      s(   z6OnlineCourseRecommendationSystem._validate_course_itemc                 C   s$   t dddddddddd	gd
ddgS )z6Create fallback recommendations when LLM parsing failsz3Please check platform directly for relevant courseszMultiple PlatformszVarious InstructorsVariesz
All LevelszpCourse recommendations could not be generated. Please search directly on platforms like Coursera, Udemy, or edX.rP   zN/Azgeneral skillsK   z0Fallback recommendation due to system limitationrQ   )r
   )r5   r   r   r   r`   	  s   zAOnlineCourseRecommendationSystem._create_fallback_recommendations	json_datac           
      C   sR  zcd| _ t|}|dd}|dd}|dd}|r|s&ddg d	W S | |||}g }|jD ] }||j|j|j	|j
|j|j|j|j|j|j|j|jd
 q2|j|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": "Python Programming",
            "max_courses": 10
        }
        r   r!   rP   r"   r@   r?   Fz)Both domain and field_prompt are required)r&   r4   r$   rQ   )r&   r!   r"   r#   r$   r%   token_countzJSON decode error: zInvalid JSON format: NzProcessing error: )r0   rY   rZ   r]   rF   r$   r^   r   r   r   r   r   r   r   r   r   r   r   r   r&   r!   r"   r#   r%   ra   r1   r4   r3   r   )
r5   rr   request_datar!   r"   r@   rE   course_recommendations_jsonrecr6   r   r   r   process_json_request  sf   



z5OnlineCourseRecommendationSystem.process_json_requestN)r)   )r?   )r   r   r   r   r   r7   r>   r   r    rF   r   r
   rC   rM   dictr'   r\   r`   r   rw   r   r   r   r   r(   '   s    *S.r(   c                  C   s  ddddddddddd	dd
dddg} t d t }| D ]}t dd  t d|d  d|d   t d  |t|}t d|d   t d t d|d   t d|d   t d|d   t d t|d dD ]s\}}t d| d|d    t d!|d"   t d#|d$   t d%|d&   t d'|d(   t d)|d*   t d+|d,   t d-|d.  d/ t d0d1|d2   t d3|d4   t d5|d6 d7d8  d9 qv|d st d:|d   t d;|d<   qd7S )=z,Test the online course recommendation system
TechnologyzPython Programming   rG   BusinesszDigital Marketing   z!Data Science and Machine Learning   CreativezUI/UX Design   z3=== TESTING ONLINE COURSE RECOMMENDATION SYSTEM ===
zP================================================================================z	TESTING: r!   rB   r"   u   ✅ SUCCESS: r&   u   📊 STATS:z   Total recommendations: r#   z   Domain: z
   Field: u   
🎓 COURSE RECOMMENDATIONS:r$      z
   u   . 📚 r   z      Platform: r   z      Instructor: r   z      Duration: r   z      Level: r   z      Price: r   z      Rating: r   z      Match: r   %z      Skills: z, r   z      Reason: r   z      Description: r   Nrh   z...z    No recommendations found for u   
📝 Summary: r%   )printr(   rw   rY   dumps	enumeratejoin)
test_casescourse_system	test_caseresulticourser   r   r   "test_online_course_recommendationsj  s\   
r   __main__)rY   loggingtypingr   r   r   dataclassesr   langchain_ollamar   langchain_core.promptsr   langchain_core.messagesr   basicConfigINFO	getLoggerr   r1   r
   r    r(   r   r   r   r   r   <module>   s(    
	  E@
