
    j(                         S SK r S SKrS SKrS SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
  S SKJr  S SKJr  S r " S S	5      r " S
 S5      rS rS rS r\S:X  a  \R*                  " \" 5       5        gg)    N)tqdm)OllamaEmbeddings)FAISS)PromptTemplate)
ChatOllamac                    [        SS9nSU  SU 3n[        R                  R                  U5      (       az  [        R                  " U5       Vs/ s H  oDR                  S5      (       d  M  UPM     nnU(       a%  [        R                  " X2SS9n[        SU 35        U$ [        S	U S
35         g [        SU  SU S
35        g s  snf )Nznomic-embed-text)modelzmy_embeddings_video//)z.faissz.pklT)allow_dangerous_deserializationzEmbeddings loaded from zNo embedding files found in .z"No embeddings found for client_id z and reference_id )	r   ospathisdirlistdirendswithr   
load_localprint)	client_idreference_id
embeddingsreference_dirfembedding_filesvectorss          M/var/www/eduai.edurigo.com/question_generate/production/generate_mcq_video.pyload_all_embeddingsr      s    !(:;J*9+Q|nEM	ww}}]##&(jj&?b&?::N`Ca1&?b&&}bfgG+M?;<N0qAB  	29+=OP\~]^_` cs   C+Cc                   8    \ rS rSrS rS rS rS rS rS r	Sr
g	)
QuestionHistory   c                 J    SU SU S3U l         U R                  5       U l        g )Nzquestion_history_video/r
   z.json)	file_pathload	questions)selfr   r   s      r   __init__QuestionHistory.__init__   s%    29+Q|nER    c                     [         R                  R                  U R                  5      (       an   [	        U R                  S5       nUR                  5       R                  5       nS S S 5        W(       a  [        [        R                  " U5      5      $ [        5       $ [        S5        [        5       $ ! , (       d  f       NS= f! [        R                   a&    [        SU R                   S35        [        5       s $ f = f)NrzWarning: Invalid JSON in z!. Starting with an empty history.z6No history file found. Starting with an empty history.)r   r   existsr!   openreadstripsetjsonloadsJSONDecodeErrorr   )r$   r   contents      r   r"   QuestionHistory.load"   s    77>>$..))$..#.!ffhnn.G /3:s4::g./EE
 JL5L /. '' 1$..1AAbcdus/   C B2%-C 	C 2
C <C 7C=<C=c                 0   [         R                  " [         R                  R                  U R                  5      SS9  [        U R                  S5       n[        R                  " [        U R                  5      U5        S S S 5        g ! , (       d  f       g = f)NT)exist_okw)
r   makedirsr   dirnamer!   r+   r/   dumplistr#   )r$   r   s     r   saveQuestionHistory.save/   sT    
BGGOODNN3dC$..#&!IId4>>*A. '&&s   +B
Bc                 :    U R                   R                  U5        g N)r#   addr$   questions     r   r?   QuestionHistory.add4   s    8$r'   c                     XR                   ;   $ r>   )r#   r@   s     r   __contains__QuestionHistory.__contains__7   s    >>))r'   c                 ,    [        U R                  5      $ r>   )lenr#   )r$   s    r   __len__QuestionHistory.__len__:   s    4>>""r'   )r!   r#   N)__name__
__module____qualname____firstlineno__r%   r"   r;   r?   rD   rH   __static_attributes__ r'   r   r   r      s     %/
%*#r'   r   c                        \ rS rSrS rS rSrg)RateLimiter=   c                 *    Xl         X l        / U l        g r>   max_requestsperiodrequests)r$   rU   rV   s      r   r%   RateLimiter.__init__>   s    (r'   c                   #    [         R                   " 5       nU R                   Vs/ s H  o!U-
  U R                  :  d  M  UPM     snU l        [        U R                  5      U R                  :  aB  U R                  XR                  S   -
  -
  nUS:  a  [
        R                  " U5      I S h  vN   U R                  R                  [         R                   " 5       5        g s  snf  N87f)Nr   )timerW   rV   rG   rU   asynciosleepappend)r$   nowreq
sleep_times       r   waitRateLimiter.waitC   s     iik(,QsT[[9PQt}}!2!22mmA.>(>?JA~mmJ///TYY[) R 0s#   $C)C" C"A(C).C'/9C)rT   N)rJ   rK   rL   rM   r%   ra   rN   rO   r'   r   rQ   rQ   =   s    
*r'   rQ   c                    U R                  SS5      R                  SS5      R                  SS5      R                  SS5      n[        R                  " SU5      n/ nU GH}  nUR                  5       nU(       d  M  [        R                  " SU5      nU(       d  M=  USUR                  5        R                  5       nU(       d  Mg  0 nS	 HZ  nS
U-   S-   n	[        R                  " X[        R                  5      n
U
(       a#  U
R                  S5      R                  5       Xx'   MZ    O   [        U5      S:  a  M  [        R                  " SU5      nU(       a   UR                  S5      R                  5       nOP[        R                  " SU[        R                  5      nU(       a   UR                  S5      R                  5       nOGMh  UR                  UUUS.5        GM     U$ )z
Robustly parses multiple-choice questions from the LLM response string.
Supports bolding, different bullet styles, double newlines, and trailing spaces.
z** *___z3(?i)(?:^|\n)\s*(?:Q|Question)\s*(?:\d+)?\s*[:.-]\s*z(?i)(?:^|\n)\s*A[\s).:-]+N)ABCDz(?i)(?:^|\n)\s*z9[\s).:-]+(.*?)(?=\n\s*(?:[A-D][\s).:-]|Correct|Answer)|$)      z:(?i)(?:Correct|Answer|Correct\s*Answer)\s*[:.-]*\s*([A-D])z'(?i)(?:Correct|Answer)\s*.*?\b([A-D])\b)rA   optionscorrect_answer)replaceresplitr-   searchstartDOTALLgrouprG   upperr]   )response_strcleaned
raw_blocksr#   blockopt_a_matchquestion_textrn   optopt_pattern	opt_matchcorrect_matchcorrect_lettercorrect_match_fallbacks                 r   parse_mcqs_robustlyr   L   s   
 ""4,44S"=EEdBOWWX[]_`GPRYZJIii <eD2{002399;'C,S01mmK		+bii@I(q1779 ( w<!		"_afg*00399;N%'YY/Y[`bdbkbk%l"%!7!=!=a!@!F!F!H%,
 	G R r'   c           	      ,  ^^^#    [        X5      nU(       d  [        S5        / SS4$ [        X5      mUR                  SS0S9n[	        SSS9m[        S	S
/SS9m/ nSnSn/ n	[        5       n
/ SQnU Hq  n UR                  U5      I S h  vN nU HN  n[        UR                  S S 5      nX;  d  M"  U
R                  U5        U	R                  UR                  5        MP     Ms     U	(       d4  UR                  S5      I S h  vN nU Vs/ s H  oR                  PM     n	nUUU4S jn[        USS9 n[        R                  " 5       S-   nSn[        U5      U:  Ga  [        R                  " 5       U:  Gar  U[        U5      -
  n[!        US5      n/ n[#        [!        S[        U	5      5      5       H(  nUU-   [        U	5      -  nUR                  U	U   5        M*     US-   [%        [        U	5      S5      -  n U" UUU5      I S h  vN nU H  n[        U5      U:  d  M  US   T;  d  M  UR                  U5        TR                  US   5        US-  nU[        US   R'                  5       5      [)        S US   R+                  5        5       5      -   -  nUR-                  S5        M     [        U5      U:  a  O+[        U5      U:  a  [        R                  " 5       U:  a  GMr  [        U5      U:  a  [        S[        U5       SU S35        TR/                  5         U[        T5      U4sS S S 5        $  GN! [         a     GM  f = f GNOs  snf  GNQ! [         a  n[        SU 35         S nAGM,  S nAff = f! , (       d  f       g = f7f)Nz=No embeddings found for the given client ID and reference ID.r   k
   )search_kwargszhttp://127.0.0.1:11434z
gemma3:12b)base_urlr	   contextnum_questionsa:  
        {context}
        Generate {num_questions} multiple-choice questions based on the information provided above. Each question should have one correct option and three incorrect options. Use the following format:
        Q:
        A)
        B)
        C)
        D)
        Correct:
        Ensure questions are concise and directly related to the content. Try to cover different aspects of the provided information. Do not include phrases like "in the document", "according to the text", or any other references to the source material in the questions.
        )input_variablestemplaterl   )zkey concepts and definitionszimportant facts and detailszmain topics and summaryz processes methods and proceduresz#examples applications and use cases   overviewc                   >#    SR                  U 5      nTR                  X2S9nTR                  U/5      I Sh  vN nUR                  n[	        U5      n/ nU H  n	U	S   n
[
        R                  " SSU
[
        R                  S9R                  5       n
[
        R                  " SSU
[
        R                  S9R                  5       n
U
T;  d  Mv  UR                  U[        U5      -   U
U	S	   U	S
   S.5        M     U$  N7f)z>Process multiple contexts in a single LLM call for efficiency.z

---

)r   r   NrA   ze\b(in|from|according to|mentioned in|stated in|as per) (the|this)? ?(document|text|passage|content)\brd   )flagszQ^(The|This) (document|text|passage|content) (states|mentions|says|indicates) thatrn   ro   )numberrA   rn   ro   )joinformatainvoker2   r   rq   sub
IGNORECASEr-   r]   rG   )contextsstart_numbernum_to_generatecombined_contextpromptresponserx   parsed_questionsr#   qrA   llmmcq_templatequestion_historys              r   process_batch)generate_mcq_video.<locals>.process_batch   sC    (--h7$$-=$]fX..''.|<	!A}H vv  G  IK  MU  ]_  ]j  ]j  k  q  q  sHvvrtv  yA  IK  IV  IV  W  ]  ]  _H//  *S^; ( |&'(8&9	"  " ) /s   6C?C=BC?/C?zGenerating MCQs)totaldesci,     rA   c              3   T   #    U  H  n[        UR                  5       5      v   M      g 7fr>   )rG   rr   ).0options     r   	<genexpr>%generate_mcq_video.<locals>.<genexpr>   s2       PK  sJhnPSTZT`T`TbPcPc  sJs   &(rn   zError processing context: zWarning: Only generated z unique questions out of z requested.)r   r   r   as_retrieverr   r   r.   r   hashpage_contentr?   r]   	Exceptionr   rZ   rG   minrangemaxrr   sumvaluesupdater;   )r   r   r   GPUr   	retrievermcqsquestion_numbertotal_token_countall_contextsseen_contentsseed_queriesr   resultsr)   content_hashr   pbartimeout	ctx_indexremaining_questions
batch_sizebatch_contextsiidxnew_mcqsmcqer   r   r   s                               @@@r   generate_mcq_videor      s    !):GMN1ax&y?$$C9$=I
)C ""O4
L DO LEML 	%--a00G#ANN4C$894!%%l3 ''7	   !))*55078184 
M(9	:d))+#	$i-'DIIK',A"/#d)";0"5J  N3q#l"345 1}L(99%%l3&78 6 #Q#c,.?*CCI!.~PZ![[#C4y=0S_L\5\C((,,S_='1,)SZ1F1F1H-IC  PKruv  sA  sH  sH  sJ  PK  MK  .K  K)A $ 4yM)7 $i-'DIIK',A: t9}$,SYK7PQ^P__jklS)*,==K 
;	:O 1  		 68X \  21#675 
;	:s   A0N6L?
L<$L?30L?#NMNM N4CN;MM	M#M.BM08N+AN2
N<L??
M	NMNNM
N &M;4N;N  N
NNc                  d  #    Sn SnSn[        XU5      I S h  vN u  p4nU(       d  [        S5        g [        SU 35        [        SU 35        U HX  n[        SUS    SUS	    35        US
   R                  5        H  u  px[        U SU 35        M     [        SUS    S35        MZ     g  N7f)Nr   r   z'No multiple-choice questions generated.zTotal questions in history: zTotal token count: z	Question r   z: rA   rn   z) zCorrect Answer: ro   
)r   r   items)	r   r   r   r   history_counttoken_countr   r   texts	            r   mainr      s     IML-?	Zf-g'g$D78	(
89	}
-.	#h-3z?*;<=	N002LFVHBtf%& 3 %5!6 7r:;	  (hs   B0B.BB0__main__)r   randomr/   r[   rq   rZ   r   langchain_ollamar    langchain_community.vectorstoresr   langchain_core.promptsr   r   r   r   rQ   r   r   r   rJ   runrO   r'   r   <module>r      so    	    	   - 2 1 ' # #@* *2hw>r<& zKK r'   