Ë
    I»je  ã                  ó˜   — d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZmZmZ ddlmZ 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Z G d	„ d
«      Zy)u7   AI question generation â€” live LLM or local generator.é    )Úannotations)Úrender_role_question_prompts)Ú	JobStatus)Ú
DifficultyÚGeneratedOptionÚGeneratedQuestionÚQuestionGenRequestÚQuestionGenResponseÚQuestionTypeÚRoleQuestionGenRequestÚRoleQuestionGenResponse)Úgenerate_jsonc                óî  — g }t        | «      D ]ä  }d|j                  › d|› d|dz   › d�}g }d|› d�}|t        j                  k(  r(dd	|› �d
dœddddœddddœddddœg}d}d|› d|dz   › d�}nN|t        j                  k(  rddd
dœddddœg}d}|› d|dz   › d�}n!|t        j
                  k(  rd|› d|dz   › d�}d}|j                  d|dz   › �|j                  |j                  |||d|› d�i dœ«       Œæ |S ) NÚ[z] Explain a key concept about z (Qé   z).zSample answer covering Ú.ÚAzCorrect point about T©ÚkeyÚtextÚ
is_correctÚBzPlausible distractorFÚCzUnrelated optionÚDzCommon misconceptionzWhich statement best describes z? (QÚ)ÚTÚTrueÚFÚFalsez7 is an important topic for this role. True or False? (Qz"Write a short solution related to z# sample solution
passúq-zGenerated locally for ©ÚidÚquestion_typeÚ
difficultyÚstemÚoptionsÚanswerÚexplanationÚmetadata)ÚrangeÚvaluer   ÚMCQÚ
TRUE_FALSEÚCODINGÚappend)	ÚcountÚqtyper$   ÚtopicÚitemsÚir%   r&   r'   s	            ú0/var/www/html/TJ-AI/tj/app/services/questions.pyÚ_local_questionsr6      s  € ð €EÜ�5Ž\ˆØ�:×#Ñ#Ð$Ð$BÀ5À'ÈÈQÐQRÉUÈGÐSUÐVˆØ ˆØ*¨5¨'°Ð3ˆØ”L×$Ñ$Ò$àÐ';¸E¸7Ð%CÐSWÑXØÐ%;È5ÑQØÐ%7ÀuÑMØÐ%;È5ÑQð	ˆGð ˆFØ4°U°G¸4ÀÀAÁ¸wÀaÐH‰DØ”l×-Ñ-Ò-à V¸4Ñ@Ø W¸EÑBðˆGð ˆFØ�WÐSÐTUÐXYÑTYÐSZÐZ[Ð\‰DØ”l×)Ñ)Ò)Ø7¸°w¸cÀ!ÀaÁ%ÀÈÐKˆDØ.ˆFØ�‰à˜1˜q™5˜'�lØ!&§¡Ø(×.Ñ.ØØ"Ø Ø!7¸°w¸aÐ@Øñ	õ	
ð/ ðF €Ló    c                óæ  — g }t        | xs g «      D �]±  \  }}t        |t        «      sŒ|j                  d|j                  «      }|j                  d|j                  «      }	 t        |«      }	 t        |«      }	t        |j                  d«      xs g «      D �
�cg c]z  \  }
}t        |t        «      ret        t        |j                  dt        d|
z   «      «      «      t        |j                  dd«      «      t        |j                  dd	«      «      ¬
«      ‘Œ| }}
}|j                  t        t        |j                  dd|dz   › �«      «      ||	t        |j                  d«      xs |j                  d«      xs d|dz   › �«      ||j                  d«      |j                  d«      |j                  d«      xs i ¬«      «       �Œ´ |S # t        $ r |}Y �Œiw xY w# t        $ r |}	Y �Œow xY wc c}}
w )Nr#   r$   r&   r   éA   r   Ú r   Fr   r"   r    r   r%   z	Question r'   r(   r)   r!   )Ú	enumerateÚ
isinstanceÚdictÚgetr+   r   Ú
ValueErrorr   r   ÚstrÚchrÚboolr/   r   )ÚrawÚfallback_typeÚfallback_diffÚoutr4   Úitemr1   ÚdiffÚqtÚdfÚjÚor&   s                r5   Ú_parse_questionsrM   B   sÎ  € Ø#%€CÜ˜SšY B×'‰ˆˆ4Ü˜$¤Ô%ØØ—‘˜¨-×*=Ñ*=Ó>ˆØ�x‰x˜ m×&9Ñ&9Ó:ˆð	Ü˜eÓ$ˆBð	Ü˜DÓ!ˆBô " $§(¡(¨9Ó"5Ò";¸Ô<ô
ñ =‘��1Ü˜!œTÔ"ô Ü˜Ÿ™˜e¤S¨¨a©£[Ó1Ó2Ü˜Ÿ™˜v rÓ*Ó+Ü §¡ l°EÓ :Ó;öð
 =ð 	ñ 
ð 	�
‰
ÜÜ�t—x‘x ¨¨1¨q©5¨' lÓ3Ó4Ø ØÜ˜Ÿ™ &Ó)ÒT¨T¯X©X°fÓ-=ÒTÀ9ÈQÐQRÉUÈGÐATÓUØØ—x‘x Ó)Ø ŸH™H ]Ó3ØŸ™ *Ó-Ò3°ô	ö	
ð- (ðD €Jøô7 ò 	Ø‹Bð	ûô ò 	Ø‹Bð	üó
s+   Á#G	Á/GÂA?G-Ç	GÇGÇG*Ç)G*c                  ó$   — e Zd Zdd„Z	 	 	 	 dd„Zy)ÚQuestionsServicec              ƒ  óˆ  ‡K  — d}d‰j                   › d‰j                  › d‰j                  j                  › d‰j                  j                  › d‰j
                  › d‰j                  › d‰j                  xs d	› d
‰j                  › �}dˆfd„}t        |||¬«      ƒ d {  –—† \  }}}t        |j                  dg «      ‰j                  ‰j                  «      }|s.t         |«       d   ‰j                  ‰j                  «      }d\  }}t        ‰j                  t        j                  |dt!        |«      › d|› �|¬«      S 7 Œ ­w)Nz°You are an assessment question generator. Return JSON: {"questions":[{"id","question_type","difficulty","stem","options":[{"key","text","is_correct"}],"answer","explanation"}]}z	Subject: z
Topic: z
Type: z
Difficulty: z
Count: z
Language: z

Context: Únonez
Constraints: c            	     ó”   •— dt        ‰ j                  ‰ j                  ‰ j                  ‰ j                  › d‰ j
                  › �¬«      iS )NÚ	questionsz / ©r0   r1   r$   r2   )r6   r0   r#   r$   Úsubjectr2   )Úpayloads   €r5   Úlocalz(QuestionsService.generate.<locals>.localw   sH   ø€ àÔ-Ø!Ÿ-™-Ø!×/Ñ/Ø&×1Ñ1Ø$Ÿ_™_Ð-¨S°·±°Ð@ô	ðð r7   ©ÚsystemÚuserÚlocal_factoryrS   ©TrW   ú
Generated z question(s) via )Úcorrelation_idÚstatusÚstubÚmessagerS   ©Úreturnr=   )rU   r2   r#   r+   r$   r0   ÚlanguageÚcontextÚconstraintsr   rM   r>   r
   r^   r   Ú	SUCCEEDEDÚlen)	ÚselfrV   rY   rZ   rW   Údatar`   ÚproviderrS   s	    `       r5   ÚgeneratezQuestionsService.generatej   s`  øè ø€ ðeð 	ð ˜Ÿ™Ð(¨	°'·-±-°ð AØ×*Ñ*×0Ñ0Ð1°À×@RÑ@R×@XÑ@XÐ?Yð ZØ—m‘m�_ L°×1AÑ1AÐ0Bð CØŸ™Ò1¨6Ð2°/À'×BUÑBUÐAVðXð 	õ	ô &3Ø °Eô&
÷  
Ñˆˆd�Hô %Ø�H‰H�[ "Ó% w×'<Ñ'<¸g×>PÑ>Pó
ˆ	ñ Ü(Ù“˜Ñ$ g×&;Ñ&;¸W×=OÑ=OóˆIð +‰NˆD�(ä"Ø"×1Ñ1Ü×&Ñ&ØØ ¤ Y£Ð 0Ð0AÀ(ÀÐLØô
ð 	
ð 
ús   ƒBEÂE Â B!Ec              ƒ  ód  ‡‡
K  — t        ‰j                  ‰j                  ‰j                  xs d‰j                  xs d‰j
                  ‰j                  ‰j                  D �cg c]  }|j                  ‘Œ c}‰j                  j                  ‰j                  ‰j                  ‰j                  xs d¬«      \  }}|dz   }‰j                  r‰j                  d   nt        j                  Š
dˆˆ
fd„}t        |||¬«      ƒ d {  –—† \  }}}t!        |j#                  dg «      ‰
‰j                  «      }	|	s$t!         |«       d   ‰
‰j                  «      }	d\  }}t%        ‰j&                  ‰j                  ‰j                  t(        j*                  |d	t-        |	«      › d
|› �||dœ|	¬«      S c c}w 7 Œ«­w)Nr:   )ÚpersonaÚ
role_titleÚ	seniorityÚ
departmentÚjob_descriptionÚskillsÚquestion_typesr$   r0   rd   ÚinstructionszŒ
Return JSON only: {"questions":[{"id","question_type","difficulty","stem","options":[{"key","text","is_correct"}],"answer","explanation"}]}r   c                 óÚ   •— ‰j                   } ‰j                  r.‰j                   › ddj                  ‰j                  d d «      › d�} dt        ‰j                  ‰‰j
                  | ¬«      iS )Nz (z, é   r   rS   rT   )ro   rs   Újoinr6   r0   r$   )r2   rV   Úprimary_types    €€r5   rW   z2QuestionsService.generate_from_role.<locals>.local¬   sn   ø€ Ø×&Ñ&ˆEØ�~Š~Ø"×-Ñ-Ð.¨b°·±¸7¿>¹>È"È1Ð;MÓ1NÐ0OÈqÐQ�àÔ-Ø!Ÿ-™-Ø&Ø&×1Ñ1Øô	ðð r7   rX   rS   r\   r]   z role question(s) via )rY   rZ   )r^   ro   rn   r_   r`   ra   Úprompt_previewrS   rb   )r   rn   ro   rp   rq   rr   rs   rt   r+   r$   r0   rd   ru   r   ÚSHORT_ANSWERr   rM   r>   r   r^   r   rg   rh   )ri   rV   rI   rY   Úuser_promptrW   rj   r`   rk   rS   ry   s    `        @r5   Úgenerate_from_rolez#QuestionsService.generate_from_role•   s­  ùè ø€ ô ;Ø—O‘OØ×)Ñ)Ø×'Ñ'Ò-¨2Ø×)Ñ)Ò/¨RØ#×3Ñ3Ø—>‘>Ø/6×/EÒ/EÓFÑ/E¨˜BŸH›HÐ/EÑFØ×)Ñ)×/Ñ/Ø—-‘-Ø×%Ñ%Ø ×-Ñ-Ò3°ô
Ñˆ�ð ðeñeð 	ð
 5<×4JÒ4J�w×-Ñ-¨aÒ0ÔP\×PiÑPiˆö	ô &3Ø ¸5ô&
÷  
Ñˆˆd�Hô %Ø�H‰H�[ "Ó% |°W×5GÑ5Gó
ˆ	ñ Ü(Ù“˜Ñ$ l°G×4FÑ4FóˆIð +‰NˆD�(ä&Ø"×1Ñ1Ø×)Ñ)Ø—O‘OÜ×&Ñ&ØØ ¤ Y£Ð 0Ð0FÀxÀjÐQØ&,°kÑBØô	
ð 		
ùòM Gð4 
ús    „AF0Á"F)Á5BF0ÄF.ÄB,F0N)rV   r	   rc   r
   )rV   r   rc   r   )Ú__name__Ú
__module__Ú__qualname__rl   r}   © r7   r5   rO   rO   i   s   „ ó)
ðV9
Ø-ð9
à	 ô9
r7   rO   N)
r0   Úintr1   r   r$   r   r2   r@   rc   z
list[dict])rC   ÚlistrD   r   rE   r   rc   zlist[GeneratedQuestion])Ú__doc__Ú
__future__r   Úapp.promptsr   Úapp.schemas.commonr   Úapp.schemas.questionsr   r   r   r	   r
   r   r   r   Úapp.services.ai_generater   r6   rM   rO   r�   r7   r5   Ú<module>rŠ      sm   ðÙ =å "å 4Ý (÷	÷ 	ó 	õ 3ð+àð+ð ð+ð ð	+ð
 ð+ð ó+ó\$÷Ne
ò e
r7   